PowerShell Objekte für eigenen Zweck sinnvoll erweitern
PowerShell Member Types
PowerShell Objekte für eigenen Zweck sinnvoll erweitern

Überblick

Die objektorientierte Programmierung (OOP) ist ein, nicht wegzudenkender Bestandteil der PowerShell. Wenn wir mit Objekten in der Shell arbeiten, nutzen wir deren Eigenschaften und Methoden, um Werte auszulesen oder Aktionen auszulösen. Dieser Informations- und Actionsumfang (Member => Eigenschaften, Methoden und Ereignisse) ist auf den jeweiligen Objekt-Typ beschränkt.

Diese Objekt Erweiterung ist immer dann sinnvoll, wenn wir zusätzliche Daten über die Pipe transportieren wollen oder dauerhaft in der Sitzung eigene Aktionen in Objekten anstoßen wollen.

Neben vorhanden Objekte können neue Objekte über den Typ [PSCustomObject] erzeugt werden. Dieses leere Objekt kann, um einen Satz von eigenen Eigenschaften und Ereignisse ergänzt werden.

Mit Add-Member können Sie ein konkretes Objekt, um neue Eigenschaften und Methoden ergänzen. Mit Update-TypeData können Sie einen Typen in der aktuellen Session ergänzen, so dass alle Objekte von diesem Typ von der Erweiterung profitieren können. Das sind 2 einfache Möglichkeiten der Objekt Erweiterung, um Individualität im Pipeline-Fluss zu bekommen.

Beispiel: PowerShell Objekt erweitern

TIPP - Zwei weitere spannende Artikel die gut zu diesem pasen sind: "PowerShell Einstieg für Anfänger und Profis" "PowerShell Objekte in 3 Schritten erfolgreich analysieren", und "PowerShell Pipeline Sinn & Nutzen erklärt".

Objekt Member analysieren

Zuerst versschafen wir uns einen Überblick, welche Eigenschaften, Methoden und Ereignisse ein Object besitzt. U.a. erfahren wir auch so, wie das Objekt bereits für die PowerShell erweitert wurde.

Objekt Erweiterungen eines Prozess-Objektes

Die folgende Code-Zeile zeigt eine Liste von Eigenschaften, Methoden und Ereignisse die native im .NET-Typen [System.Diagnostics.Process] implementiert wurden.

Get-Process | Get-Member -View 'Adapted'

Neben diesen nativen .NET Eigenschaften, Methoden und Ereignisse lassen wir uns nun die Eigenschaften, Methoden und Ereignisse anzeigen die bereits eine PowerShell Erweiterungen erhalten haben.

Get-Process | Get-Member -View 'Extended'
# ? Gruppiert nach Eigenschaften, Methoden und Ereignisse-Typ inkl. Anzahl
Get-Process | Get-Member -View 'All' | Group-Object -Property 'MemberType' -NoElement | Sort-Object -Property 'Count' -Descending

Wenn nun die benötigte Eigenschaft oder Methode nicht vorhanden ist? Kein Problem! Das Typen-System der PowerShell ist flexibel. Wir ergänzen das aktuelle Objekt mit Add-Member. Dieses Verfahren hat den Vorteil, dass wir nicht komplett neue Typen erzeugen müssen.

TIPP - Wenn Sie mehrt über Objekt-Analyse verstehen wollen, dann lesen Sie PowerShell Objekte in 3 Schritten erfolgreich analysieren

PowerShell Objekt erweitern

Ein Objekt kann mit unterschiedlichen Eigenschaften und Methoden erweitert werden. Zum Beispiel soll in einem Anwendungsfall das Ergebnis unmittelbar nach der Berechnung einmalig in eine Eigenschaft geschrieben werden (NoteProperty). In einem anderen Fall soll diese Berechnung jedesmal erfolgen, wenn die Eigenschaft gelesen werden soll (ScriptProperty). Folgende Objekt Erweiterungen sind denkbar:

Art Beschreibung
AliasProperty Alias für eine andere Property
NoteProperty einfache Read/Write Property
ScriptProperty ScriptBlock-Code der beim Lesen ausgeführt wird
PropertySet Eine Gruppe von Properties
ScriptMethode ScriptBlock-Code der beim Aufruf ausgeführt wird inkl. Parameter-Argumenten-Übergabe

Nun wollen wir aber Objekte erweitern. Dazu benötigen wir z.B. den ersten Prozess.

$p1 = Get-Process | Select-Object -First 1

Dieses Object in $p1 ergänzen wir einmal um eine NoteProperty, ScriptProperty und ScriptMethod.

# ? Dem Object eine NoteProperty hinzufügen
$p1 | Add-Member -Name 'Jetzt_A' -Value ( Get-Date ) -MemberType  'NoteProperty'

# ? Dem Object eine ScriptProperty hinzufügen
$p1 | Add-Member -Name 'Jetzt_B' -Value { Get-Date } -MemberType 'ScriptProperty'

# ? Dem Object eine ScriptMethod hinzufügen
$p1 | Add-Member -Name 'Jetzt_C' -Value { param([int]$Year) return Get-Date -Year $Year } -MemberType 'ScriptMethod'

Jetzt können wir mit der neuen Objekt Erweiterung arbeiten.

# ? Die neuen Properties und Methods anzeigen
$p1 | Get-Member -Name 'Jetzt*' -View 'Extended'

# * Beispiel testen:
$p1.Jetzt_A       # ? NoteProperty   aufrufen => statisches Datum
$p1.Jetzt_B       # ? ScriptProperty aufrufen => dynamisches Datum
$p1.Jetzt_C(2050) # ? ScriptMethod   aufrufen => dynamisches Datum

Bis hierhin erweiterte (Add-Member) die Objekte direkt in der Pipeline. Diese Art von Objekt Erweiterung wirkt sich nicht auf andere Objekte des gleichen Typs aus. Dies kann für den aktuellen Fall sinnvollsein. Sollte jedoch die Objekt Erweiterung sämtliche Prozess in der aktuellen PowerShell-Sitzung betreffen, so müssen wir dies anders implementieren.

Sämtliche Objekte eines Typs erweitern. In diesem Fall nehmen wir die Objekt Erweiterung direkt am Typ vor Update-TypeData. Diese Erweiterung wirkt sich nur in der Session auf alle Objekte vom gleichen Typ aus.

# ? Session-weite Erweiterungen
Update-TypeData -TypeName 'System.Diagnostics.Process' -MemberName 'WorkingSet64MB' -Value { [int]($this.WorkingSet64 / 1MB) } -MemberType 'ScriptProperty' -Force

# ? Alle Process-Objects haben jetzt eine neue Property WorkingSet64MB
Get-Process | Get-Member -View 'Extended'
Get-Process | Select-Object -Property 'Name', 'WorkingSet64MB'

Im folgenden Beispiel sollen alle Objects der PowerShell eine Methode OpenTypeNameSearch bekommen. Wird diese Methode aufgerufen öffnet sich im Browser die Google-Suche die nach dem konkreten Typennamen sucht, um so mehr über diesen Typ zu erfahren.

Update-TypeData -TypeName 'System.Object' -MemberName 'OpenTypeNameSearch' -MemberType 'ScriptMethod' -Force -Value {
    $FullTypeName = $this.GetType().FullName
    $SearchUrl = "https://www.google.com/search?q=$FullTypeName"
    Start-Process -FilePath $SearchUrl
}

# .OpenTypeNameSearch() testen

$p1 = Get-Process | Select-Object -First 1
$p1.OpenTypeNameSearch() # Google-Suche nach System.Diagnostics.Process startet

$s1 = Get-Service | Select-Object -First 1
$s1.OpenTypeNameSearch() # Google-Suche nach System.ServiceProcess.ServiceController

In diesem Beispiel wird der Type [System.Object] bereichert. Sämtliche anderen Typen wurden früher oder später von Object abgeleitet was zu folge hat das die Methode OpenTypeNameSearch an allen Objekten, egal von welchem Typ vorhanden ist.

PowerShell Objekt Erweiterung für Object

Wollen Sie dauerhaft von dieser Typen-Erweiterung profitieren so könnten Sie diesen Code in einer der profile.ps1 Dateien speichern.

$profile.AllUsersAllHosts
$profile.AllUsersCurrentHost
$profile.CurrentUserAllHosts
$profile.CurrentUserCurrentHost

Oder in einem eigenen Modul (..PSM1) ablegen.

PowerShell Quiz / Wissenstest

Testen Sie Ihr PowerShell Wissen mit 6 zufälligen Fragen. Jedes Quiz ist kostenlos, anonym, die Auswertung erfolgt im Anschluss und zu Gewinnen gibt es Stolz und Ehre.

Viel Spaß und Erfolg!

Bitte bewerten Sie diesen Artikel


Dieser Beitrag hat 2 Kommentare

Schreibe einen Kommentar