Seriál Windows PowerShell: Typ objektu (část 28.)

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:

image

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.

- David Moravec