Ha egy modulban nem csak függvények vannak, hanem változók is, és ezek fontos részei annak, akkor érdemes lehet a modult objektumként importálni, hiszen ekkor a függvényekből az objektum metódusai lesznek, a változókból pedig az objektum tulajdonságai lesznek. Ennek fő előnye, hogy az egész egyben kezelhető, „önhordó” lesz.
Nézzünk erre egy gyakorlati példát. Készítsünk egy nagyon egyszerű naplófájl kezelő modult, legyen a neve log.psm1:
$name = "log-$(get-date -f
'yyyyMMddHHmmss').log"
$path = $env:TEMP
$created = $false
$verbose = $true
$typehash = @{
"I" = @{Text = "Info"}
"W" = @{Text = "Warning";
FC = "Yellow"; BC = "Black"}
"E" = @{Text = "Error";
FC = "Red"; BC = "Black"}
}
function write {
param(
$entry,
$type = "i"
)
$fullpath = Join-Path $path $name
if(!(test-path $fullpath) -and $name){
$line = "DateTime, EntryType, EntryText"
[void] (New-Item -Path $path -Name $name -ItemType file -Force)
Set-Content
-Path $fullpath -Value $line -Encoding unicode
$script:created = $true
}
$line = (Get-Date -f "yyyy.MM.dd hh.mm.ss") + ",
" + $typehash.$type.text + ", " + $entry
if($verbose){
if($type -eq "I"){
Write-Host
$line
}
else{
Write-Host
$line -ForegroundColor $typehash.$type.fc -BackgroundColor $typehash.$type.bc
}
}
Add-Content -Path $fullpath -Value $line -Encoding unicode
}
function open {
if($script:created){
$fullpath = Join-Path $path $name
Import-Csv
-Path $fullpath | Out-GridView
}
else{
Write-Host
"No log entry has been created." -ForegroundColor red
}
}
Export-ModuleMember -Variable name, path, created, verbose, typehash -Function write, open
A modulban két függvényt definiáltam, a Write segítségével lehet a fájlba kiírni egy naplóbejegyzést és ha ’verbose’ üzemmódban vagyunk, akkor ugyanezt a sort a képernyőre is kiírja. Ráadásul a képernyőre kiírt változat színe a bejegyzés típusától függően piros vagy sárga, ha hiba vagy figyelmeztető üzenetről van szó. Van még egy Open függvény is, ami megnyitja a naplófájlt a GridView felületen.
Van még ebben a modulban néhány változó, amelyekkel a naplóállomány nevét ($name) és helyét ($path) adhatjuk meg, valamint az előbb már említett ’verbose’ üzemmódot állíthatjuk a $verbose paraméterrel, és a $created változó kiolvasásával ellenőrizhetjük, hogy történt-e már naplóbejegyzés vagy sem.
Természetesen lehetne még fokozni ennek a modulnak a szolgáltatásait, de itt most nem ez a lényeg, hanem az, hogy belássuk, hogy egy ilyen jellegű modult, ha csak simán importálunk, akkor elég nehéz kezelni. Hiszen függvényei sem túl specifikusak, például a Write egyben a Write-Host álneve is, így inkább az fog futni, nem pedig a mi függvényünk. Meg az exportált változókat sem könnyű megtalálni a számos gyári és esetleges egyéb saját változók között. Amúgy meg nem túl sok mindent exportálunk a modulból. Jó lenne ezt a néhány dolgot együtt tartani, és erre pont jó az egyedi objektumként történő importálás. Nézzük, hogy hogyan:
[1] PS C:\> $logger = Import-Module C:\_munka\powershell\_Scripts\log.psm1 -AsC
ustomObject -Force
[2] PS C:\> $logger
created : False
name : log-20120315225244.log
path : C:\Users\soost\AppData\Local\Temp
typehash : {I, E, W}
verbose : True
[3] PS C:\> $logger | gm -MemberType methods
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
open ScriptMethod System.Object open();
write ScriptMethod System.Object write();
A $logger változóm tartalmazza a modul képességeit, az ott definiált függvényekből metódusok lettek, az exportált változókból meg tulajdonságok. És így egy egységben tarthatjuk ezeket. Nézzük, az objektum a formában hogyan is kezelhető a naplózás:
[4] PS C:\> $logger.write("Sima infó")
2012.03.16 11.08.09, Info, Sima infó
[5] PS C:\> $logger.write("Figyelmeztetés","W")
2012.03.16
11.08.14, Warning, Figyelmeztetés
[6] PS C:\> $logger.write("Hiba","E")
2012.03.16 11.08.15, Error, Hiba
[7] PS C:\> $logger.open()
Az Open hatására megnyílik a rács, benne a naplóbejegyzések:
Evvel aztán a beépített keresési, szűrési és sorba rendezési lehetőségekkel könnyen tudjuk kezelni a naplófájlunkat.
Megjegyzés
Sajnos a modul egyedi objektumként való importálásával a modul a szokásos módon is importálásra kerül, azaz például a $created és a $name változó, vagy a függvények is megszólíthatók kívülről is. Ennek az a veszélye, hogy ha például a globális hívási környezetben átírom a $name változót, akkor már a $logger.Open() sem fog működni:
[21] PS C:\> $name
log-20120316110803.log
[22] PS C:\> $name = "valami"
[23] PS C:\> $logger.open()
Exception calling "open" with "0"
argument(s): "Cannot open file "C:\Users\soo
st\AppData\Local\Temp\valami"."
At line:1 char:13
+ $logger.open <<<< ()
+
CategoryInfo : NotSpecified: (:) [],
MethodInvocationException
+
FullyQualifiedErrorId : ScriptMethodRuntimeException
Így erre mindenképpen oda kell figyelni a modul egyedi objektumként való importálásakor.