Eigene Objekte erzeugen
Wenn Sie in Powershell Skripte schreiben, sollten Sie sich angewöhnen, immer Objekte auszugeben. Der Grund ist relativ einfach – Objekte sind das universelle Datenformat in Powershell. Liegen Daten in Objektform vor, können Sie sie in beliebige andere Formate konvertierten oder weiterverarbeiten.
Es gibt unzählige Cmdlets in Powershell, um Objekte in alle nur denkbaren Formate umzuwandeln, wie CSV, JSON, XML, HTML, XLSX oder Text, um nur einige zu nennen. Objekte können Sie aber auch direkt in SQL-Server Tabellen schreiben lassen oder als AD-Objekte anlegen. Wenn Sie Daten aus Ihrem Skript heraus bereits in ein Format konvertiert haben, nehmen Sie sich oder dem Anwender Ihres Skripts die einfache Möglichkeit selbst zu entscheiden, welches Format gerade benötigt wird!
Das Erstellen von Objekten ist dabei denkbar einfach, da Microsoft Ihnen für das Erstellen von eigenen Objekten eine leere Vorlage erstellt hat, die Sie einfach um Ihre eigenen Eigenschaften und Methoden erweitern können. Sie nennt sich PSCustomObject.
Um neue Objekte zu erstellen, verwenden Sie das Cmdlet New-Object. New-Object benötigt beim Erstellen eines neuen Objekts immer den Typ, von dem Sie eine Instanz (Kopie) erstellen möchten:
New-Object -Typename PSCustomObject | Get-Member
> 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()
Ein PSCustomObject ist ein Minimalobjekt, das nur über die Standardmethoden verfügt, die jedes Objekt besitzt. Diese Methoden werden von einer Basisklasse "geerbt". Wie man sieht, hat das PSCustomObject die Gettype()-Methode geerbt, sowie die ToString()-Methode, die das Objekt in eine Textrepräsentation von einer Zeile umwandelt.
Um ein Objekt mit Eigenschaften zu erzeugen, können Sie Get-Member mit dem Parameter -Property eine Hash-Table mit allen Eigenschaften übergeben, die Ihr neues Objekt besitzen soll:
$ComputerInfoProperties = @{
Biosversion = ( Get-CIMInstance Win32_Bios ).Version
RAM = ( Get-CIMInstance Win32_Computersystem ).TotalPhysicalMemory
Betriebssytem = ( get-CIMInstance Win32_OperatingSystem ).Caption
Name = hostname.exe
}
New-object -TypeName PSObject -Property $ComputerInfoProperties
Name Biosversion RAM Betriebssytem
---- ----------- --- -------------
BigWin ALASKA - 1072009 34322423808 Microsoft Windows 10 Enterprise
Wie Sie an der Ausgabe sehen können, werden die Eigenschaften nicht in der gleichen Reihenfolge ausgegeben werden, wie Sie in der Hash-Table angegeben sind. Das liegt daran, dass eine Hash-Table keine vorgegebene Sortierung wie ein Array hat. Um die Reihenfolge beizubehalten, wird eine sortierte Hash-Table benötigt:
$ComputerInfoProperties = [ordered]@{
Biosversion = ( Get-CIMInstance Win32_Bios ).Version
RAM = ( Get-CIMInstance Win32_Computersystem ).TotalPhysicalMemory
Betriebssytem = ( get-CIMInstance Win32_OperatingSystem ).Caption
Name = hostname.exe
}
New-object -TypeName PSObject -Property $ComputerInfoProperties
> Biosversion RAM Betriebssytem Name
> ----------- --- ------------- ----
> ALASKA - 1072009 34322423808 Microsoft Windows 10 Enterprise BigWin
[PsCustomObject]@{
Biosversion = ( Get-CIMInstance Win32_Bios ).Version
RAM = ( Get-CIMInstance Win32_Computersystem ).TotalPhysicalMemory
Betriebssytem = ( get-CIMInstance Win32_OperatingSystem ).Caption
Name = hostname.exe
}
> Biosversion RAM Betriebssytem Name
> ----------- --- ------------- ----
> ALASKA - 1072009 34322423808 Microsoft Windows 10 Enterprise BigWin
Um Ihr eigenes PSCustomObject zu erzeugen, brauchen Sie also nichts weiter zu tun, als alle relevanten Informationen in eine Hash-Table zu schreiben und für die Typumwandlung [PSCustomObject] voran zu stellen.
Um einem bestehenden Objekt weitere Eigenschaften oder Methoden hinzuzufügen, verwenden Sie Add-Member:
$ip = Get-NetIPAddress -PrefixOrigin Dhcp,Manual
$Computer | Add-Member -MemberType NoteProperty -Name IP -Value $ip.IPAddress
$Code = {(Get-CimInstance -ClassName win32_operatingsystem).LastBootUpTime }
Add-Member -InputObject $Computer -MemberType ScriptMethod -Name StTm -Value $Code
$Computer.StTm()
> Montag, 25. Mai 2020 21:54:17
$Code = {(Get-CimInstance -ClassName win32_operatingsystem).LastBootUpTime }
$Computer | Add-Member -MemberType ScriptProperty -Name Startzeit -Value $Code
$Computer.StartZeit
> Montag, 25. Mai 2020 21:54:17
$AdditionalCode = { param($Computer) Test-NetConnection -ComputerName $Computer }
$Computer | Add-Member -MemberType ScriptMethod -Name ping -Value $AdditionalCode
$Computer.Ping("Server2")
In Zeile 1 und 2 wurde eine Eigenschaft IPAddresse vom Typ NoteProperty hinzugefügt. Noteproperties sind einfache Textfelder und können im Prinzip beliebige Werte beinhalten.
Zeile 3 und 4 wurde die Scriptmethode Startzeit hinzugefügt. Es handelt sich hier um ein Powershell-Skript, das beim Aufrufen der Methode ausgeführt wird. Denken Sie daran, dass Methoden mit runden Klammern aufgerufen werden müssen.
Da die Startzeit eigentlich eine variable Eigenschaft ist, kann sie auch als Eigenschaft angelegt werden, die aber dynamisch bei Aufruf bestimmt wird. Das passiert in Zeile 7 und 8 mit der Scriptproperty.
Im Zeile 11 und 12 wird eine Methode mit Übergabeparametern erzeugt. Der Parameter wird in den runden Klammern angegeben. Achten Sie darauf, dass beim Anlegen von Methoden immer ein Scriptblock übergeben werden muss – also der auszuführende Code in geschweiften Klammern steht.
Eine sehr ausführliche Auflistung zur Arbeit mit Powershell Custom Objects hat Kevin Marquette in dem Artikel Everything you wanted to know about PSCustomObject zusammengestellt.