Při našem posledním předprázdninovém setkání jsme vytvářeli vlastní objekty. Dnes posuneme naši snahu o dokonalost o trochu dále. Pouze pro jistotu zopakujeme použitý kód:
function Get-TNObject { param( $ComputerName = $env:COMPUTERNAME )
$os = Get-WmiObject -ComputerName $ComputerName -ClassWin32_OperatingSystem
$prop = @{ ComputerName = $ComputerName OSName = $os.Caption OSVersion = $os.Version ScanTime = Get-Date }
New-Object -TypeName PSObject -Property $prop
}
Výstupem dané funkce je například:
PS C:\> Get-TNObject | Format-Tablet -AutoSize
OSVersion ScanTime OSName ComputerName --------- -------- ------ ------------ 5.1.2600 03-Sep-12 23:23:48 Microsoft Windows XP Professional MAKOVEC-40
Pokud si uložíme výstupní objekt do proměnné – se kterou chceme dále pracovat - dostaneme následující výsledky:
PS C:\> $tn = Get-TNObject
PS C:\Scripts > $tn.GetType()
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False PSCustomObject System.Object
PS C:\> $tn.GetType().FullName System.Management.Automation.PSCustomObject
PS C:\Scripts > $tn | gm
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() ComputerName NoteProperty System.String ComputerName=MAKOVEC-40 OSName NoteProperty System.String OSName=Microsoft Windows XP Professional OSVersion NoteProperty System.String OSVersion=5.1.2600 ScanTime NoteProperty System.DateTime ScanTime=0š-Sep-12 23:25:46
Vidíme, že objekt typu PSCustomObject. Vzhledem k tomu, že si dnes budeme trochu hrát s typem objektu, hodilo by se nám zjistit, jak jsme se vlastně dostali k „výslednému“ typu objektu.
Pozn.: Pokud jsou mezi vámi vývojáři, promiňte prosím v rámci zjednodušení některé prohřešky proti běžným konvencím. Dopouštím se jich vědomě.
PS C:\> $tn.PSTypeNames System.Management.Automation.PSCustomObject System.Object
Pokud čteme výstup odspodu, vidíme, že náš TN objekt je zároveň typu Systém.Object (základ všech objektů v .NET) a již uvedeného PSCustomObject. Tato vlastnost se nám může hodit v případě vytváření vlastních rozšíření pomocí formátovacích souborů (o těchto souborech si povíme více v některém z příštích pokračování). Nejprve si ale musíme připravit naše objekty. Pro názornost si ještě ukážeme, jakého typu je například objekt z WMI.
PS C:\> $os = Get-WmiObject -Class Win32_OperatingSystem PS C:\> $os.PSTypeNames System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem System.Management.ManagementObject System.Management.ManagementBaseObject System.ComponentModel.Component System.MarshalByRefObject System.Object
Vidíte, že opět začínáme u Systém.Object a pokračujeme dalšími typy až k výsledném Win32_OperatingSystem.
Přemýšleli jste někdy nad tím, proč se při zadání
PS C:\> Get-WmiObject Win32_OperatingSystem
SystemDirectory : C:\WINDOWS\system32 Organization : PowerShell.cz BuildNumber : 2600 RegisteredUser : PowerShell.cz SerialNumber : 12345-678-12345-678910 Version : 5.1.2600
zobrazí pouze pár vlastností, když jich je ve skutečnosti mnohem více?
PS C:\> Get-WmiObject Win32_OperatingSystem | Get-Member -MemberType Property | Measure-Object
Count : 71
Pro zobrazení všech hodnot můžete použít
PS C:\> Get-WmiObject Win32_OperatingSystem | Format-List -Property *
Nebudeme zde z důvodu místa uvádět výsledek – sami si ho můžete jednoduše zobrazit. Zobrazení vlastností je kontrolované právě takzvaným formátovacím souborem. Pokud si zobrazíme část tohoto souboru – právě pro WMI objekty – uvidíme toto:
Pokud se podíváte na část PSStandardMembers a porovnáte ji s výstupem cmdletu Get-WmiObject, uvidíte jistou shodu. Právě tato část určuje, jaké vlastnosti se zobrazí při standardním výstupu.
Pozor! Pokud neodoláte touze a soubor najdete, v žádném případě jej neměňte. Soubor je digitálně podepsán a jeho změnou si narušíte jednu ze základních funkcí PowerShellu. Existují lepší metody, jak standardní výpis změnit.
Pojďme tedy na začátek dnešního článku a zkusme si změnit (přidat) nový typ k našemu TN objektu. Osobně mám rád cestu, kdy nejdříve zrušíme veškeré informace o typu a poté přidáme pouze náš vlastní.
PS C:\> $tn.PSTypeNames.Clear()
PS C:\> $tn.PSTypeNames
PS C:\> $tn.PSTypeNames.Add('Makovec.TNObjekt')
PS C:\> $tn.PSTypeNames Makovec.TNObjekt
PS C:\> $tn | Get-Member
TypeName: Makovec.TNObjekt
…
Nyní máme připravený objekt pro další práci. Abychom nemuseli upravovat výsledné objekty, je lepší měnit typ ihned po vytvoření objektu. Proto si trochu upravíme původní funkci.
$os = Get-WmiObject -ComputerName $ComputerName -Class Win32_OperatingSystem
$obj = New-Object -TypeName PSObject -Property $prop $obj.PSTypeNames.Clear() $obj.PSTypeNames.Add('Makovec.TNObjekt') $obj
Při zobrazování tohoto typu objektu můžeme použít formátovací soubor. Jak již bylo uvedeno – použití tohoto souboru si ukážeme v některém z příštích pokračování.
Příště se podíváme na PowerShell v3 – vzhledem k tomu, že uvedení Win8 se blíží, je myslím vhodná doba pro opuštění v2. Nicméně vše, co jsme si ukazovali ve všech předchozích dílech, platí i ve verzi 3.
- David Moravec