Zum Hauptinhalt springen

Die Powershell-Pipeline

Die Powershell Pipeline erlaubt es, Daten zur Verarbeitung von einem Cmdlet zu einem anderen Cmdlet weiterzuleiten. Die Pipeline verhält sich dabei wie eine Schleife, ruft also Code-Blöcke (hier in Form von Cmdlets) wiederholt auf. Man kann eine Pipeline-Verarbeitung immer durch eine Schleife ersetzen.

Die Daten werden in der Pipeline seriell verarbeitet, also ein Objekt nach dem anderen. Das ist speicherschonend, da immer nur die Objekte im Arbeitsspeicher gehalten werden müssen, die aktuell verarbeitet werden. Dafür ist die Pipeline-Verarbeitung CPU-intensiver, da für jede Verarbeitung ein sogenannter Runspace aufgemacht wird. Grundsätzlich gilt als Faustregel also, dass die Pipeline weniger RAM benötigt als eine Schleifenbasierte Verarbeitung, aber dafür deutlich mehr CPU-Ressourcen.

Um Daten von einem Cmdlet an ein anderes weiterzuleiten, verwenden Sie den senkrechten Strich |.

Get-Process | Get-Member

Die Pipeline nutzt die Standardausgabe als Zwischenspeicher. Die Standardausgabe (Stdout) ist der Ort, den fast alle Cmdlets zur Ausgabe von Daten verwenden, die in die Konsole schreiben. Wenn auf ein Cmdlet kein Pipe-Symbol folgt, werden die Daten von Powershell in Text umgewandelt und in die Konsole geschrieben – es sei denn, das Cmdlet leitet die Ausgabe selbst z.B. in eine Textdatei aus..

Get-ChildItem -file | Measure-Object -Property Length -Sum -Minimum -Maximum

> Count : 4920
> Average :
> Sum : 2581740570
> Maximum : 133315992
> Minimum : 0 
> Property : Length

Im obigen Beispiel liefert Get-Childitem alle Dateiobjekte des aktuellen Ordners zurück. Measure-Object summiert die Anzahl aller Objekte, und berechnet über die Eigenschaft Length außerdem die Gesamtsumme, den kleinsten Wert und den größten Wert. Spannend ist, dass Measure-Object nicht die Dateien und Ordner weiterleitet. Die Objekte werden an Measure-Object übergeben, der Berechnungen über eine angegeben Eigenschaft ausführt und am Ende ein GenericMeasureInfo-Objekt ausgibt. Die Datei- und Ordnerobjekte sind dabei auf der Strecke geblieben. Da auf die Ausgabe des GenericMeasureInfo-Objekts kein Pipe-Symbol mehr erfolgt, wird die Ausgabe in Text umgewandelt und in der Konsole geschrieben.

Sie können die Ausgabe der Pipeline aber auch in einer Variablen auffangen, um anschließend wieder auf das Objekt zuzugreifen:

$MeasureInfo = Get-ChildItem | Measure-Object -Property Length -Sum
$MeasureInfo.Sum / 1MB
> 2462,13967323303

Natürlich können Sie die Ausgabe jetzt auch wieder mit den Format-Operator verschönern:

"{0:0.000} MB" -f ($MeasureInfo.Sum/1MB)

Viele Cmdlets können Objekteaus der Pipeline verarbeiten, die aus der gleichen Funktionsgruppe stammen. Das erste Beispiel benötigt ein installiertes Hyper-V:

Get-VM | Set-VM -ProcessorCount 2
Get-LocalUser -Name Holger | Set-LocalUser -AccountNeverExpires 
Get-Service -Name wuauserv | Stop-Service

 Es gibt aber eine Reihe von Cmdlets, die nur in der Pipeline eingesetzt werden können, aber dafür universell mit jedem übergebenen Objekt umgehen können:

  • Select-object
  • Where-object
  • Foreach-Object
  • Group-Object
  • Sort-Object
  • Measure-Object
  • Compare-Object
  • Format-Table
  • Format-List
  • Out-Gridview

um nur einige zu nennen. Viele dieser Cmdlets sind spezialisiert auf die Ausgabe, aber einige sind sehr hilfreich für die Filterung von Daten.