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
System.Management.Automation.PSCustomObject
System.Object
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.
function Get-TNObject
{
param(
$ComputerName = $env:COMPUTERNAME
)
$os = Get-WmiObject -ComputerName $ComputerName -Class Win32_OperatingSystem
$prop = @{
ComputerName = $ComputerName
OSName = $os.Caption
OSVersion = $os.Version
ScanTime = Get-Date
}
$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.