Ich habe ein neues Feature in der Powershell entdeckt, dass mir bei meinem Scripting-Alltag das Leben deutlich erleichtert: Klassen.

Analog zu anderen Sprachen kann man in der Powershell Datenkonstrukte definieren und diese an vorhandene Cmdlets oder selbst geschriebene Funktionen weiter reichen. Für gewöhnlich nimmt man dazu entweder ein Array, eine Hashtable oder (in manchen Fällen) fragt die erforderlichen Einzelwerte eines Datensets in Form von Parametern ab.

Möchte man jedoch sicherstellen, dass man ein definiertes Set an Daten übergeben wird, kann man dieses Ziel bisher nur schwer erreichen:

  • Ein Array kann beliebige Daten enthalten, oder auch die benötigten Daten in der falschen Reihenfolge. Es gibt keine Möglichkeit, zuverlässig zu überprüfen, ob ein übergebenes Array die angeforderten Daten enthält, dass die Funktion zum Arbeiten benötigt.
  • Eine Hashtable kann beliebig definiert werden. Schränkt man den Funktionsparameter so ein, dass er nur noch eine Hashtable entgegen nimmt, hat man dennoch keine Garantie, dass die übergebene Hashtable die korrekten Datenfelder beinhaltet.
  • Jeden abzurufenden Wert in einen eigenen Parameter zu hüllen, ist zwar eine valide Möglichkeit, aber in manchen Situationen dennoch unpraktisch, da die Korrektheit der Daten in jeder Funktion separat geprüft werden muss (Das kann man zwar ebenfalls wieder in eine Funktion extrahieren, aber irgendwann wird es dann auch unübersichtlich)

Mit Klassen in Powershell (Version 5) kann man diese Probleme umgehen und sie sind denkbar einfach geschrieben:

class MyClass{
  [string]$Name
  [int]$Age
}

Dies erzeugt einen Datentyp mit dem Namen MyClass und den Eigenschaften Name und Age. Ein Objekt wird denkbar einfach mit folgender Zeile erzeugt:

$object = New-Object -TypeName MyClass

 Und befüllen ist ähnlich leicht:

$object.Name = "Hans"
$object.Age = 34

Wollen wir nun eine Funktion schreiben, die ein Objekt der Klasse "MyClass" entgegen nehmen soll, können wir folgenden Funktionsaufruf definieren:

function HelloPerson{
	[CmdletBinding()]
	param(
		[Parameter(Mandatory=$true)][MyClass]$Person
	)
	begin{}
	process{
		$HelloWorld = "Hello " + $Person.Name
		$HelloWorld
	}
	end{}
}

Die Funktion wird für den Parameter Person jetzt nur noch ein Objekt der Klasse MyClass entgegen nehmen.

Darüber hinaus kann man auch Methoden für die Powershell-Klassen definieren. Es steht also nichts im Wege, innerhalb der Klasse eine Methode Check() zu definieren, die überprüft, ob die Werte der Klasse valide sind.

Die Prüfung kann man dann in jeder weiteren Funktion mit

$object.check()

abhandeln und direkt mit dem Inhalt der eigentlichen Aufgabe ausführen.

Wie man Methoden in Klassen definiert, dazu schreibe ich später mehr, sobald ich mich damit befasst habe.