Windows PowerShellNeuer Ansatz für die Pipeline

Don Jones

Es wurde viel darüber geredet, wie anders, neuartig und interessant Windows PowerShell ist. Trotzdem basiert Windows PowerShell auf Konzepten im Bereich Befehlszeilenschnittstellen, die es bereits seit Jahrzehnten hauptsächlich in UNIX- und Linux-basierten Betriebssystemen gibt. Die Tatsache, dass die Terminologie von Windows PowerShell und ihren Vorläufern sehr ähnlich ist, führt oft dazu, dass

die flexiblen und einzigartigen Features von Windows PowerShell™ in einer Windows®-Umgebung leicht übersehen werden.

Eines der am häufigsten diskutierten, aber auch am häufigsten missverstandenen Features von Windows PowerShell ist die Pipeline. Dies ist darauf zurückzuführen, dass die entsprechende Terminologie in den frühen 70er Jahren definiert wurde, die damals ganz andere und weniger leistungsfähige Funktionen repräsentierte.

Der Ursprung von Pipes

Eine der ersten UNIX-Shells überhaupt war die Thompson-Shell. Sie war sehr einfach und enthielt nur die grundlegendsten Elemente der Skriptsprache ohne Variablen. Die Shell war absichtlich schlicht gehalten, da ihr Zweck einzig im Ausführen von Programmen bestand. Sie führte jedoch ein wichtiges Konzept ein, das damaligen Shells überlegen war: Pipes. Mithilfe der Symbole < und > konnte die Shell angewiesen werden, die Eingabe und Ausgabe an und von verschiedenen Befehlen umzuleiten. Der Benutzer war jetzt in der Lage, beispielsweise die Befehlsausgabe an eine Datei umzuleiten.

Diese Syntax wurde später erweitet, sodass die Ausgabe eines Befehls auch zur Eingabe eines anderen Befehls geleitet werden konnte. Somit bestand die Möglichkeit, lange Befehlsfolgen zum Durchführen komplizierterer Aufgaben zu verketten. In Version 4 der Shell wurde der senkrechte Strich „|“ für das Weiterleiten übernommen, der seitdem als Pipezeichen bezeichnet wird. Selbst in den frühesten Versionen von MS-DOS® wurden einfache Weiterleitungsfunktionen mithilfe dieser Zeichen implementiert, sodass Benutzer beispielsweise die Ausgabe des Befehls „type“ in die Eingabe des Befehls „more“ leiten konnten, wodurch für lange Textdateien eine Anzeige von jeweils einer Seite erstellt werden konnte.

Obwohl die Thompson-Shell mit der Veröffentlichung von UNIX-Version 6 im Jahr 1975 allgemein als unzulänglich angesehen wurde, hatte sich das Konzept von Pipes bei Shellentwicklern und Benutzern durchgesetzt. Noch heute wird es bei einer Reihe von Technologien verwendet.

Weiterleiten von Text

Eine Einschränkung fast aller Shells besteht darin, dass sie von Natur aus textorientiert sind. In UNIX-basierten Betriebssystemen ist dies eigentlich keine Einschränkung, sondern spiegelt wider, wie das Betriebssystem an sich funktioniert. Fast jede Ressource in UNIX kann als Datei dargestellt werden, sodass das Weiterleiten von Text von einem Befehl in einen anderen eine leistungsstarke und flexible Funktion darstellt.

Im Bereich Verwaltungsinformationen hat Text jedoch eine eher einschränkende Wirkung. Wenn Sie sich beispielsweise eine Liste von auf einem Windows-Computer ausgeführten Diensten ansehen, wäre Ihnen diese sehr wahrscheinlich verständlich. Der Dienstname wäre vielleicht in der ersten Spalte enthalten, der Startmodus in der zweiten. Das menschliche Gehirn ist leistungsfähig genug, um, diese Textanzeige sofort klar zu analysieren und in sinnvolle und nützliche Informationen zu übersetzen. Computer sind leider nicht so clever: Damit ein Computer mit dieser Liste sinnvoll arbeiten kann, müssten Sie ihm beispielsweise mitteilen, dass die erste Spalte aus den Zeichen 1 bis 20 besteht und die zweite Spalte aus den Zeichen 22 bis 40 und so weiter.

Lange Zeit war diese Art der Textdateianalyse die einzige Möglichkeit für Administratoren, mehrere Befehle miteinander zu verketten. Tatsächlich zeichnen sich Skriptprogrammiersprachen wie VBScript und Perl hauptsächlich durch die Zeichenfolgemanipulation aus, weil sie in der Lage sind, die Textausgabe eines Programms oder Befehls aufzunehmen, zu analysieren und schließlich nützliche Daten auszugeben, die für eine nachfolgende Aufgabe verwendet werden können. Ich habe beispielsweise VBScript-Aufträge geschrieben, bei denen die Textausgabe des Dir-Befehls aufgenommen, diese Ausgabe auf Dateinamen und Daten analysiert und dann alte, nicht verwendete Dateien in ein Archiv verschoben wurden. Die Zeichenfolgenanalyse ist äußerst knifflig, da es fast immer zu Ausnahmen, also Varianten bei den Eingabedaten kommt, sodass die Logik im Skript geändert werden muss, um alle möglichen Kombinationen zu berücksichtigen.

Als Form der administrativen Skripterstellung oder Automatisierung in einer Windows-Umgebung ist die Zeichenfolgenanalyse weniger nützlich. Dies ist darauf zurückzuführen, dass in Windows nicht viele Informationen in einem leicht zugänglichen Textformat gespeichert werden. Stattdessen werden Datenspeicher wie Active Directory®, die Windows-Registrierung und der Zertifikatsspeicher eingesetzt, sodass Skriptersteller zunächst mithilfe eines Tools eine Textausgabe generieren und diese anschließend mit einem Skript analysieren und schließlich einsetzen müssen.

Objekte sind einfacher

Windows-Softwareentwickler hatten es schon immer ein bisschen leichter. Zu Anfang wurde COM von Microsoft speziell entwickelt, um die komplexen internen Funktionsweisen von Windows auf benutzerfreundlichere Art und Weise darzustellen. Heute führt Microsoft® .NET Framework dieselbe Aufgabe durch: es bietet eine standardisierte Darstellung der internen Funktionsweise der Software.

Generisch stellt sowohl COM als auch .NET Elemente als Objekte zur Verfügung. (Ein Softwareentwickler ist mit dieser Vereinfachung möglicherweise nicht einverstanden, aber im Kontext dieses Artikels reicht ein einfacher Begriff aus.) Alle diese Objekte verfügen über Mitglieder verschiedener Arten. Im Rahmen dieser Abhandlung sind die Eigenschaften und Methoden der Objekte von besonderem Interesse. Eine Eigenschaft beschreibt im Wesentlichen ein Objekt auf eine bestimmte Art und Weise bzw. ändert das Objekt oder sein Verhalten. Ein Dienstobjekt beispielsweise könnte über eine Eigenschaft verfügen, die den Namen des Diensts enthält, und eine andere, die den Startmodus enthält. Methoden sorgen dafür, dass ein Objekt eine bestimmte Aktion durchführt. Ein Dienstobjekt enthält beispielsweise Methoden mit der Bezeichnung „Stop“, „Start“, „Pause“ und „Resume“, also die verschiedene Aktionen, die mit dem Dienst durchgeführt werden können.

Programmierer oder Skriptersteller verweisen auf die Mitglieder eines Objekts mit einer punktierten Schreibweise. Objekte werden oft Variablen zugeordnet, sodass das Objekt physisch manipuliert werden kann. Wenn ein Dienst beispielsweise der Variablen „$service“ zugeordnet ist, kann dieser Dienst mithilfe der Syntax „$service.Stop“ angehalten werden. Der Anzeigename des Diensts lässt sich durch Anzeigen von $service.Name abrufen.

Objekte in der Pipe

Da Windows ein großes, komplexes Betriebssystem ist und die Verwaltungsdaten nicht als Textdarstellung speichert, eignen sich ältere Shellverfahren nicht besonders gut für Windows. Angenommen ein Befehlszeilentool namens „SvcList.exe“ erstellt eine formatierte Liste von Diensten und deren Startmodi. In der Windows-Befehlszeilenshell (eine Shell, die ihren Ursprung in der Jahrzehnte alten MS-DOS-Shell hat) ließe sich etwa Folgendes ausführen:

SvcList.exe | MyScript.vbs 

Diese Anweisung ruft eine Liste von Diensten ab und leitet diese Liste an eine VBScript-Datei weiter. Die VBScript-Datei müsste so geschrieben werden, dass die formatierte Liste analysiert und die gewünschten Aufgaben ausgeführt werden, beispielsweise die Ausgabe aller Dienste mit dem Startmodus „Disabled“. Diese Aufgabe wäre zeitaufwändig. Letztendlich besteht das Problem darin, dass die Ausgabe von SvcList.exe einmalig ist und kein einheitliches Format vorliegt, über das andere Befehle die Ausgabe nutzen können.

Objekte können dieses einheitliche Format jedoch bereitstellen, und aus diesem Grund funktioniert die Windows PowerShell-Pipeline mit ganzen Objekten und nicht nur mit Text. Beim Ausführen eines Cmdlet wie Get-WMIObject wird eine Gruppe bzw., aus Sicht des Programmierers, eine Sammlung von Objekten erstellt. Jedes Objekt ist mit umfassenden Eigenschaften und Methoden für die Bearbeitung ausgestattet. Beim Weiterleiten der Objekte zum Where-Object-Cmdlet ist eine Filterung möglich, sodass nur die gewünschten Objekte angezeigt werden. Where-Object muss keinen Text analysieren, weil es keinen Text, sondern Objekte empfängt. Beispiel:

Get-WMIObject Win32_Service | Where-Object {$_.StartMode -eq “Disabled” }

Oder vorzugsweise die kürzere Syntax in Form von Aliasen:

gwmi Win32_Service | where {$_.StartMode -eq “Disabled” }

Interessant ist, dass Windows PowerShell immer Objekte entlang der Pipeline weiterleitet. Erst am Ende der Pipeline, wenn die Objekte nicht weitergeleitet werden können, generiert die Shell eine Textdarstellung der Objekte mithilfe integrierter Formatierungsregeln. Sehen Sie sich zum Beispiel Folgendes an:

Gwmi Win32_Service | where {$_.StartName –eq “LocalSystem” } | select Name,StartMode

Dieser aus drei Cmdlets bestehende Satz ruft alle Dienste von meinem lokalen Computer ab, filtert alle Dienste aus, die nicht das LocalSystem-Konto zum Anmelden verwenden, und übergibt die übrigen an das Select-Object-Cmdlet, das nur die beiden Eigenschaften ausgibt, die es auswählen sollte (Name und StartMode). Das Ergebnis ist ein einfacher Bericht der Dienste, die sich (vielleicht zur Sicherheitsüberwachung) als LocalSystem anmelden.

Da alle Cmdlets ein einheitliches Datenformat, also Objekte haben, können sie Daten ohne komplizierte Zeichenfolgenanalyse gemeinsam verwenden. Da Windows PowerShell systemeigen die Möglichkeit hat, eine Textdarstellung eines Objekts zu erstellen, ist das Ende dieser Pipe also eine für den Benutzer lesbare Textausgabe. Abbildung 1 zeigt ein Beispiel für die erstellte Ausgabe.

Abbildung 1 Eine Textausgabe, die von einer Reihe weitergeleiteter Cmdlets erstellt wird, die anhand von Objekten übergeben werden

Abbildung 1** Eine Textausgabe, die von einer Reihe weitergeleiteter Cmdlets erstellt wird, die anhand von Objekten übergeben werden **

Das Potenzial von Pipes

Das Weiterleiten in Windows PowerShell funktioniert auf so eindrucksvolle Weise, weil in Windows PowerShell ausschließlich Objekte sowie ihre zu verwendenden Eigenschaften und Methoden vorliegen. Selbst eine Textdatei ist aus technischer Sicht eine Sammlung von Zeichenfolgeobjekten, wobei jede Zeile in der Datei als einmaliges und unabhängiges Zeichenfolgeobjekt dient. Erstellen Sie beispielsweise eine Textdatei (mithilfe von Editor) mit der Bezeichnung C:\Computers.txt. Füllen Sie die Datei mit Text, und führen Sie Folgendes in Windows PowerShell aus:

Get-Content C:\Computers.txt | Select-Object Length | Format-List

Wenn Sie lieber weniger Code eingeben, können Sie auch hier wieder Aliase verwenden:

gc C:\Computers.txt | select Length | fl

Dieser Code stellt eine Liste bereit, die anzeigt, wie lang jede Zeile Ihrer Textdatei in Zeichen ist. Get-Content ruft die Zeichenfolgeobjekte aus der Datei ab, Select-Object erfasst die Eigenschaft „Length“ jedes Zeichenfolgeobjekts, und Format-List erstellt eine einfache, für den Benutzer lesbare Textausgabe. Dies ist zwar kein wirklich praktisches Verwaltungstool, trotzdem wird illustriert, dass in Windows PowerShell sogar eine einfache Textzeile ein Objekt ist.

Das Weiterleiten von Objekten von Cmdlet zu Cmdlet (oder auch von Cmdlet zu Skript) ermöglicht das Erstellen unglaublich leistungsfähiger „Einzeiler“. Dabei handelt es sich um einfache Zeichenfolgen von Cmdlets, die in einer langen Pipeline verbunden sind und einen Satz von Objekten ganz nach Wunsch weiter verfeinern. Praktisch ohne jede Skripterstellung oder Programmierung können Windows PowerShell-Cmdlets bemerkenswerte Ergebnisse erzielen, wenn sie in einer entsprechenden Pipeline miteinander verkettet sind.

Unterstützung zukünftiger Generationen

Diese Funktionen werden noch erweitert, da zukünftige Microsoft-Serverprodukte ebenfalls auf Grundlage der Windows PowerShell erstellt werden. Wenn Sie beispielsweise einen neuen Exchange Server 2007-Computer implementieren, können Sie mithilfe von Windows PowerShell alle Postfächer abrufen, diejenigen ausfiltern, die sich nicht im selben Büro befinden wie der neue Mailserver, und diese Postfächer dann zum neuen Server verschieben – und das alles in einer einzigen Textzeile ohne Skripterstellung. Das Exchange Server 2007-Team hat eine ausführliche Liste leistungsfähiger Einzeiler veröffentlicht. Hierdurch wird verdeutlicht, wie leistungsstark die Pipeline ist und welche administrativen Aufgaben sich mit ihrer Hilfe durchführen lassen.

Windows PowerShell baut zwar auf den traditionellen Prinzipien und Philosophien der UNIX-Welt auf, ist aber speziell für die Windows-Verwaltung konzipiert. Lassen Sie sich aufgrund der Gemeinsamkeiten in der Terminologie nicht zu der Annahme verleiten, dass Windows PowerShell lediglich eine Ableitung der UNIX-Shell für Windows ist. Windows PowerShell ist eng mit der Arbeitsweise von Windows verknüpft und enthält völlig neue Konzepte, die die Windows-Plattform auf ideale Weise nutzen.

Don Jones ist Windows PowerShell MVP und Autor von Windows PowerShell 101 (ScriptingTraining.com). Sie erreichen Don Jones unter www.ScriptingAnswers.com.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.