Zusammenfassen von Befehlen in Pipelines in Windows PowerShell (about_pipelines)
# THEMA
about_pipelines
# KURZBESCHREIBUNG
Zusammenfassen von Befehlen in Pipelines in Windows PowerShell
# DETAILBESCHREIBUNG
Eine Pipeline besteht aus einer Reihe von Befehlen, die durch
Pipelineoperatoren (|, ASCII 124) verbunden sind. Jeder
Pipelineoperator sendet die Ergebnisse des vorangehenden Befehls
an den nächsten Befehl.
Über Pipelines können Sie die von einem Befehl ausgegebenen
Objekte zur Verarbeitung als Eingabe an einen anderen Befehl
senden. Auch die Ausgabe dieses Befehls können Sie an einen
weiteren Befehl senden. Auf diese Weise verfügen Sie über eine
sehr leistungsstarke Befehlskette oder "Pipeline", die aus einer
Reihe einfacher Befehle besteht.
Beispiel:
Befehl-1 | Befehl-2 | Befehl-3
In diesem Beispiel werden die von Befehl-1 ausgegebenen Objekte
an Befehl-2 gesendet. Befehl-2 verarbeitet die Objekte und sendet
sie an Befehl-3. Befehl-3 verarbeitet die Objekte und übergibt
sie über die Pipeline. Da in der Pipeline keine weiteren Befehle
enthalten sind, wird das Ergebnis an der Konsole angezeigt.
In einer Pipeline werden die Befehle von links nach rechts in der
Reihenfolge verarbeitet, in der sie angezeigt werden. Die
Verarbeitung wird als einzelner Vorgang behandelt, und die
Ausgabe wird angezeigt, sobald sie generiert wurde.
Im Folgenden finden Sie ein einfaches Beispiel. Mit dem folgenden
Befehl wird der Editor-Prozess ab und dann beendet.
get-process notepad | stop-process
Im ersten Befehl wird mit dem Cmdlet "Get-Process" ein Objekt
abgerufen, das den Editor-Prozess darstellt. Mit einem
Pipelineoperator (|) wird das Prozessobjekt an das Cmdlet
"Stop-Process" gesendet, das den Editor-Prozess beendet. Der
Befehl "Stop-Process" enthält keinen Namen oder ID-Parameter zum
Angeben des Prozesses, da der angegebene Prozess über die
Pipeline übergeben wird.
Im Folgenden finden Sie ein praktisches Beispiel. Mit dieser
Befehlspipeline werden die Textdateien im aktuellen Verzeichnis
abgerufen, nur Dateien mit mehr als 10.000 Bytes Länge
ausgewählt, diese nach Länge sortiert und anschließend der Name
und die Länge jeder Datei in einer Tabelle angezeigt.
Get-ChildItem -path *.txt | Where-Object {$_.length -gt 10000} |
Sort-Object -property Length | Format-Table -property name, length
Diese Pipeline besteht aus vier Befehlen in der angegebenen
Reihenfolge. Der Befehl wird horizontal geschrieben, doch wird
der Prozess in der folgenden Grafik vertikal dargestellt.
Get-ChildItem -path *.txt
|
| ( FileInfo-Objekte )
| ( .txt )
|
V
Where-Object {$_.length -gt 10000}
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
|
V
Sort-Object -property Length
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
| ( Nach Länge sortiert )
|
V
Format-Table -property name, length
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
| ( Nach Länge sortiert )
| (Als Tabelle formatiert)
|
V
Name Length
---- ------
tmp1.txt 82920
tmp2.txt 114000
tmp3.txt 114000
VERWENDEN VON PIPELINES
Die Windows PowerShell-Cmdlets wurden für die Verwendung in
Pipelines entwickelt. Beispielsweise können Sie die Ergebnisse
von Get-Cmdlet meist über die Pipeline an ein Aktions-Cmdlet (z.
B. ein Set-, Start-, Stop- oder Rename-Cmdlet) mit demselben
Substantiv übergeben.
So können Sie über die Pipeline einen beliebigen Dienst vom
Cmdlet "Get-Service" an das Cmdlet "Start-Service" oder
"Stop-Service" übergeben (jedoch können Sie auf diese Weise keine
deaktivierten Dienste erneut starten).
Mit der folgenden Befehlspipeline wird der WMI-Dienst auf dem
Computer gestartet:
get-service wmi | start-service
Die Cmdlets, mit denen Objekte der Windows PowerShell-Anbieter
abgerufen und festgelegt werden, z. B. die Item-Cmdlets und
ItemProperty-Cmdlets, wurden ebenfalls für die Verwendung in
Pipelines entwickelt.
Beispielsweise können Sie die Ergebnisse des Befehls "Get-Item"
oder "Get-ChildItem" im Windows PowerShell-Registrierungsanbieter
über die Pipeline an das Cmdlet "New-ItemProperty" übergeben. Mit
dem folgenden Befehl wird dem Schlüssel "MeinUnternehmen" der
neue Registrierungseintrag "AnzMitarbeiter" mit dem Wert 8214
hinzugefügt.
get-item -path HKLM:\Software\MeinUnternehmen | new-Itemproperty -name AnzMitarbeiter -value 8124
Zahlreiche Dienstprogramm-Cmdlets, z. B. Get-Member,
Where-Object, Sort-Object, Group-Object und Measure-Object,
werden fast ausschließlich in Pipelines verwendet. An diese
Cmdlets können Sie beliebige Objekte über die Pipeline übergeben.
Sie können Sie z. B. alle Prozesse auf dem Computer über die
Pipeline an den Befehl "Sort-Object" übergeben und sie nach der
Anzahl der Handles im Prozess sortieren.
get-process | sort-object -property handles
Zudem können Sie sämtliche Objekte über die Pipeline an die
Formatierungs-Cmdlets, z. B. Format-List und Format-Table, die
Export-Cmdlets, z. B. Export-Clixml und Export-CSV, sowie die
Out-Cmdlets, z. B. Out-Printer, übergeben.
So können Sie den Prozess "Winlogon" über die Pipeline an das
Cmdlet "Format-List" übergeben, um alle Eigenschaften des
Prozesses in einer Liste anzuzeigen.
get-process winlogon | format-list -property *
Mit einem bisschen Übung werden Sie feststellen, dass Sie durch
Kombination einfacher Befehle in Pipelines Zeit und
Eingabeaufwand sparen und die Skripterstellung effizienter gestalten.
FUNKTIONSWEISE VON PIPELINES
Wenn Sie Objekte über die Pipeline übergeben, d. h., die Objekte
in der Ausgabe eines Befehls an einen anderen Befehl senden,
versucht Windows PowerShell, die über die Pipeline übergebenen
Objekte einem der Parameter des empfangenden Cmdlets zuzuordnen.
Dazu sucht die Parameterbindungskomponente von Windows
PowerShell, mit der Eingabeobjekte Cmdlet-Parametern zuordnet
werden, einen Parameter, der die folgenden Kriterien erfüllt:
-- Der Parameter muss Eingaben von einer Pipeline akzeptieren
(dies trifft nicht auf alle zu).
-- Der Parameter muss den Typ des gesendeten Objekts oder einen
Typ akzeptieren, in den das Objekt konvertiert werden kann.
-- Der Parameter darf nicht bereits im Befehl verwendet werden.
Das Cmdlet "Start-Service" beispielsweise verfügt über
zahlreiche Parameter, doch nur zwei von diesen, Name und
InputObject akzeptieren Pipelineeingaben. Der Name-Parameter
akzeptiert Zeichenfolgen, und der InputObject-Parameter
akzeptiert Dienstobjekte. Deshalb können Sie Zeichenfolgen und
Dienstobjekte (sowie Objekte mit Eigenschaften, die in
Zeichenfolgen- und Dienstobjekte konvertiert werden können) über
die Pipeline an Start-Service übergeben.
Wenn die Parameterbindungskomponente von Windows PowerShell die
über die Pipeline übergebenen Objekte keinem Parameter des
empfangenden Cmdlets zuordnen kann, kann der Befehl nicht
ausgeführt werden, und Sie werden von Windows PowerShell
aufgefordert, die fehlenden Parameterwerte einzugeben.
Sie können nicht erzwingen, dass die Parameterbindungskomponente
die über die Pipeline übergebenen Objekte einem bestimmten
Parameter zuordnet, Sie können nicht einmal einen Parameter
vorschlagen. Stattdessen verwaltet die Logik der Komponente den
Pipelinevorgang so effizient wie möglich.
EINZELVERARBEITUNG
Das Übergeben von Objekten über die Pipeline an einen Befehl
ähnelt dem Senden von Objekten mit einem Parameter des Befehls.
Beispielsweise können Sie Objekte, die die Dienste auf dem
Computer darstellen, über die Pipeline an den Befehl
"Format-Table" übergeben:
get-service | format-table -property name, dependentservices
Dies ähnelt dem Speichern der Dienstobjekte in einer Variablen
und dem Senden des Dienstobjekts mit dem InputObject-Parameter
von Format-Table:
$services = get-service
format-table -inputobject $services -property name, dependentservices
Es ähnelt auch dem Einbetten des Befehls im Parameterwert:
format-table -inputobject (get-service wmi) -property name, dependentservices
Jedoch besteht ein wichtiger Unterschied. Wenn Sie mehrere
Objekte über die Pipeline an einen Befehl übergeben, sendet
Windows PowerShell die Objekte einzeln an den Befehl. Wenn Sie
einen Befehlsparameter verwenden, werden die Objekte als
einzelnes Arrayobjekt gesendet.
Dieser scheinbar technische Unterschied kann interessante und
manchmal nützliche Folgen haben.
Wenn Sie z. B. mehrere Prozessobjekte vom Cmdlet "Get-Process"
über die Pipeline an das Cmdlet "Get-Member" übergeben, sendet
Windows PowerShell jedes Prozessobjekt einzeln an Get-Member.
Get-Member zeigt die .NET-Klasse (den Typ) der Prozessobjekte
und deren Eigenschaften und Methoden an.
(Get-Member entfernt Duplikate, wenn alle Objekte vom gleichen
Typ sind, wird daher nur ein Objekttyp angezeigt.)
In diesem Fall zeigt Get-Member die Eigenschaften und Methoden
jedes Prozessobjekts an, d. h. ein System.Diagnostics.Process-Objekt.
get-process | get-member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize
...
Wenn Sie jedoch den InputObject-Parameter von Get-Member
verwenden, empfängt Get-Member ein Array von System.Diagnostics.
Process-Objekten als einzelne Einheit, und es werden die
Eigenschaften eines Objektarrays angezeigt. (Beachten Sie das
Arraysymbol ([]) nach dem Typnamen von System.Object.)
get-member -inputobject (get-process)
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
Address Method System.Object& Address(Int32 )
Clone Method System.Object Clone()
...
Dies stellt möglicherweise nicht das von Ihnen beabsichtigte
Ergebnis dar, aber sobald Sie die Funktionsweise erkannt haben,
können Sie es problemlos verwenden. Ein Array von Prozessobjekten
verfügt beispielsweise über eine Count-Eigenschaft, mit der Sie
die Anzahl der Prozesse auf dem Computer zählen können.
(get-process).count
Dieser Unterschied kann wichtig sein, vergessen Sie daher nicht,
dass Objekte einzeln übermittelt werden, wenn Sie diese über die
Pipeline an ein Cmdlet übergeben.
PIPELINEEINGABEN AKZEPTIEREN
Um Objekte in einer Pipeline zu empfangen, muss das empfangende
Cmdlet einen Parameter aufweisen, der Pipelineeingaben
akzeptiert. Sie können den Befehl "Get-Help" mit dem
Full-Parameter oder dem Parameter-Parameter verwenden, um ggf.
die Parameter eines Cmdlet zu bestimmen, die Pipelineeingaben
akzeptieren.
In der Standardanzeige von Get-Help wird das Element
"Pipelineeingaben akzeptieren" in einer Tabelle von
Parameterattributen angezeigt. Diese Tabelle wird nur angezeigt,
wenn Sie den Full-Parameter oder den Parameter-Parameter des
Cmdlet "Get-Help" verwenden.
Wenn Sie z. B. bestimmen möchten, welcher Parameter des Cmdlet
"Start-Service" Pipelineeingaben akzeptiert, geben Sie Folgendes ein:
get-help start-service -full
get-help start-service -parameter *
In der Hilfe für das Cmdlet "Start-Service" wird z. B. angezeigt,
dass der Name-Parameter und der InputObject-Parameter
Pipelineeingaben akzeptieren. Alle anderen Parameter weisen in
der Zeile "Pipelineeingaben akzeptieren?" den Wert "False" auf.
-name <string[]>
Gibt die Dienstnamen für die zu startenden Dienste an.
Der Parametername ist optional. Sie können "-Name" oder
den zugehörigen Alias "-ServiceName" verwenden oder aber
den Parameternamen auslassen.
Erforderlich? true
Position? 1
Standardwert
--> Pipelineeingaben akzeptieren? true (ByValue, ByPropertyName)
Platzhalterzeichen akzeptieren? true
-inputObject <ServiceController[]>
Gibt ServiceController-Objekte an, die die zu startenden
Dienste darstellen. Geben Sie eine Variable ein, die die
Objekte enthält, oder geben Sie einen Befehl oder einen
Ausdruck ein, mit dem die Objekte abgerufen werden.
Erforderlich? false
Position? benannt
Standardwert
--> Pipelineeingaben akzeptieren? true (ByValue)
Platzhalterzeichen akzeptieren? false
Dies bedeutet, dass Sie Objekte (PsObjects) über die Pipeline an
das Cmdlet "Where-Object" übergeben können und dieses von
Windows PowerShell dem InputObject-Parameter zugeordnet wird.
METHODEN ZUM AKZEPTIEREN VON PIPELINEEINGABEN
Parameter von Cmdlets können Pipelineeingaben mit zwei
verschiedenen Methoden akzeptieren:
-- ByValue: Parameter, die Eingaben "nach Wert" akzeptieren,
können über die Pipeline übergebene Objekte mit dem gleichen
.NET-Typ wie die entsprechenden Parameterwerte oder Objekte
akzeptieren, die in diesen Typ konvertiert werden können.
Der Name-Parameter von Start-Service akzeptiert z. B.
Pipelineeingaben nach Wert. Er akzeptiert Zeichenfolgenobjekte
oder Objekte, die in Zeichenfolgen konvertiert werden können.
-- ByPropertyName: Parameter, die Eingaben "nach Eigenschaftenwert"
akzeptieren, können über die Pipeline übergebene Objekte
nur akzeptieren, wenn eine Eigenschaft des Objekts denselben
Namen wie der Parameter besitzt.
Der Name-Parameter von Start-Service akzeptiert z. B. Objekte
mit einer Name-Eigenschaft.
(Zum Auflisten der Eigenschaften eines Objekts übergeben Sie
dieses über die Pipeline an das Cmdlet "Get-Member".)
Einige Parameter akzeptieren Objekte nach Wert oder nach
Eigenschaftennamen. Diese Parameter wurden so entworfen, dass
sie Eingaben von der Pipeline problemlos akzeptieren.
ERMITTELN VON PIPELINEFEHLERN
Wenn ein Befehl aufgrund eines Pipelinefehlers nicht
ordnungsgemäß ausgeführt wird, können Sie den Fehler untersuchen
und den Befehl umschreiben.
Mit dem folgenden Befehl wird z. B. versucht, einen
Registrierungseintrag aus einem Registrierungsschlüssel in einen
anderen zu verschieben, indem mit dem Cmdlet "Get-Item" der
Zielpfad abgerufen und dann der Pfad über die Pipeline an das
Cmdlet "Move-ItemProperty" übergeben wird.
Genauer gesagt wird in diesem Befehl mit dem Cmdlet "Get-Item"
der Zielpfad abgerufen. Das Ergebnis wird mit einem
Pipelineoperator an das Cmdlet "Move-ItemProperty" gesendet. Mit
dem Befehl "Move-ItemProperty" werden der aktuelle Pfad und der
Name des zu verschiebenden Registrierungseintrags angegeben.
get-item -path hklm:\software\meinunternehmen\vertrieb |
move-itemproperty -path hklm:\software\meinunternehmen\design -name produkt
Der Befehl wird nicht ordnungsgemäß ausgeführt, und von Windows
PowerShell wird die folgende Fehlermeldung angezeigt:
Move-ItemProperty: Das Eingabeobjekt kann nicht an die
Parameter für den Befehl gebunden werden, da der Befehl
keine Pipelineeingaben akzeptiert oder die Eingabe und deren
Eigenschaften mit keinem Parameter übereinstimmen, der
Pipelineeingaben akzeptiert.
Bei Zeile:1 Zeichen:23
+ $a | move-itemproperty <<<< -path hklm:\software\meinunternehmen\design -name produkt
Wenn Sie eine Überprüfung ausführen möchten, verwenden Sie das
Cmdlet "Trace-Command", um die Komponente ParameterBinding von
Windows PowerShell nachzuverfolgen. Mit dem folgenden Befehl wird
die Komponente "ParameterBinding" während der Befehlsverarbeitung
nachverfolgt. Mit dem -phost-Parameter werden die Ergebnisse an
der Konsole angezeigt, und mit dem -filepath-Parameter werden
diese zur späteren Referenz an die Datei "debug.txt" gesendet.
trace-command -name parameterbinding -expression {get-item -path hklm:\software\meinunternehmen\vertrieb |
move-itemproperty -path hklm:\software\meinunternehmen\design -name produkt} -pshost -filepath debug.txt
Die Ergebnisse der Ablaufverfolgung sind umfangreich, doch zeigen
diese die an das Cmdlet "Get-Item" gebundenen Werte und dann die
benannten Werte, die an das Cmdlet "Move-ItemProperty" gebunden sind.
...
BIND NAMED cmd line args [Move-ItemProperty]
BIND arg [hklm:\software\meinunternehmen\design] to parameter [Pfad]
...
BIND arg [produkt] to parameter [Name]
....
BIND POSITIONAL cmd line args [Move-ItemProperty]
...
Schließlich wird gezeigt, dass der Versuch, den Pfad an den
Destination-Parameter von Move-ItemProperty zu binden, nicht
erfolgreich war.
...
BIND PIPELINE object to parameters: [Move-ItemProperty]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values Parameter
[Destination] PIPELINE INPUT ValueFromPipelineByPropertyName
NO COERCION Parameter [Credential] PIPELINE INPUT
ValueFromPipelineByPropertyName NO COERCION
...
Zum Untersuchen des Fehlers zeigen Sie mit dem Cmdlet "Get-Help"
die Attribute des Destination-Parameters an. Mit dem folgenden
Befehl rufen Sie ausführliche Informationen zum Destination-
Parameter ab.
get-help move-itemproperty -parameter destination
Die Ergebnisse zeigen, dass Destination Pipelineeingaben nur
"nach Eigenschaftennamen" akzeptiert.
Das über die Pipeline übergebene Objekt muss daher die
Destination-Eigenschaft besitzen.
-destination <Zeichenfolge>
Gibt den Pfad zum Zielspeicherort an.
Erforderlich? true
Position? 2
Standardwert
Pipelineeingaben akzeptieren? true (ByPropertyName)
Platzhalterzeichen akzeptieren? true
Um alle Eigenschaften des über die Pipeline an das Cmdlet
"Move-ItemProperty" übergebenen Objekts anzuzeigen, übergeben
Sie es über die Pipeline an das Cmdlet "Get-Member". Im
folgenden Befehl werden die Ergebnisse des ersten Befehlsteils
über die Pipeline an das Cmdlet "Get-Member" übergeben.
get-item -path hklm:\software\meinunternehmen\vertrieb | get-member
Die Ausgabe zeigt, dass es sich bei dem Element um ein
Microsoft.Win32.RegistryKey handelt, der keine Destination-Eigen-
schaft besitzt. Dies erklärt das Fehlschlagen des Befehls.
Zum Korrigieren des Befehls muss das Ziel im Cmdlet
"Move-ItemProperty" angegeben werden. Mit dem Befehl
"Get-ItemProperty" können Sie den Pfad abrufen, jedoch müssen
der Name und das Ziel im Move-ItemProperty-Teil des Befehls
angegeben werden.
get-item -path hklm:\software\meinunternehmen\design |
move-itemproperty -dest hklm:\software\meinunternehmen\design -name produkt
Um die ordnungsgemäße Funktion des Befehls zu überprüfen,
verwenden Sie den Befehl "Get-ItemProperty":
get-itemproperty hklm:\software\meinunternehmen\vertrieb
Die Ergebnisse zeigen, dass der Registrierungseintrag "Produkt"
in den Schlüssel "Vertrieb" verschoben wurde.
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\meinun ternehmen\vertrieb
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\meinun ternehmen
PSChildName : vertrieb
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Produkt : 18
SIEHE AUCH
about_objects
about_parameters
about_command_syntax
about_foreach
C:\Windows>powershell get-help about_preference_variables -full
ColorConsole [Version 1.7.1000] PowerShell 2.0-Export
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2014 Microsoft Corporation.
about_pipelines
# KURZBESCHREIBUNG
Zusammenfassen von Befehlen in Pipelines in Windows PowerShell
# DETAILBESCHREIBUNG
Eine Pipeline besteht aus einer Reihe von Befehlen, die durch
Pipelineoperatoren (|, ASCII 124) verbunden sind. Jeder
Pipelineoperator sendet die Ergebnisse des vorangehenden Befehls
an den nächsten Befehl.
Über Pipelines können Sie die von einem Befehl ausgegebenen
Objekte zur Verarbeitung als Eingabe an einen anderen Befehl
senden. Auch die Ausgabe dieses Befehls können Sie an einen
weiteren Befehl senden. Auf diese Weise verfügen Sie über eine
sehr leistungsstarke Befehlskette oder "Pipeline", die aus einer
Reihe einfacher Befehle besteht.
Beispiel:
Befehl-1 | Befehl-2 | Befehl-3
In diesem Beispiel werden die von Befehl-1 ausgegebenen Objekte
an Befehl-2 gesendet. Befehl-2 verarbeitet die Objekte und sendet
sie an Befehl-3. Befehl-3 verarbeitet die Objekte und übergibt
sie über die Pipeline. Da in der Pipeline keine weiteren Befehle
enthalten sind, wird das Ergebnis an der Konsole angezeigt.
In einer Pipeline werden die Befehle von links nach rechts in der
Reihenfolge verarbeitet, in der sie angezeigt werden. Die
Verarbeitung wird als einzelner Vorgang behandelt, und die
Ausgabe wird angezeigt, sobald sie generiert wurde.
Im Folgenden finden Sie ein einfaches Beispiel. Mit dem folgenden
Befehl wird der Editor-Prozess ab und dann beendet.
get-process notepad | stop-process
Im ersten Befehl wird mit dem Cmdlet "Get-Process" ein Objekt
abgerufen, das den Editor-Prozess darstellt. Mit einem
Pipelineoperator (|) wird das Prozessobjekt an das Cmdlet
"Stop-Process" gesendet, das den Editor-Prozess beendet. Der
Befehl "Stop-Process" enthält keinen Namen oder ID-Parameter zum
Angeben des Prozesses, da der angegebene Prozess über die
Pipeline übergeben wird.
Im Folgenden finden Sie ein praktisches Beispiel. Mit dieser
Befehlspipeline werden die Textdateien im aktuellen Verzeichnis
abgerufen, nur Dateien mit mehr als 10.000 Bytes Länge
ausgewählt, diese nach Länge sortiert und anschließend der Name
und die Länge jeder Datei in einer Tabelle angezeigt.
Get-ChildItem -path *.txt | Where-Object {$_.length -gt 10000} |
Sort-Object -property Length | Format-Table -property name, length
Diese Pipeline besteht aus vier Befehlen in der angegebenen
Reihenfolge. Der Befehl wird horizontal geschrieben, doch wird
der Prozess in der folgenden Grafik vertikal dargestellt.
Get-ChildItem -path *.txt
|
| ( FileInfo-Objekte )
| ( .txt )
|
V
Where-Object {$_.length -gt 10000}
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
|
V
Sort-Object -property Length
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
| ( Nach Länge sortiert )
|
V
Format-Table -property name, length
|
| ( FileInfo-Objekte )
| ( .txt )
| ( Length > 10000 )
| ( Nach Länge sortiert )
| (Als Tabelle formatiert)
|
V
Name Length
---- ------
tmp1.txt 82920
tmp2.txt 114000
tmp3.txt 114000
VERWENDEN VON PIPELINES
Die Windows PowerShell-Cmdlets wurden für die Verwendung in
Pipelines entwickelt. Beispielsweise können Sie die Ergebnisse
von Get-Cmdlet meist über die Pipeline an ein Aktions-Cmdlet (z.
B. ein Set-, Start-, Stop- oder Rename-Cmdlet) mit demselben
Substantiv übergeben.
So können Sie über die Pipeline einen beliebigen Dienst vom
Cmdlet "Get-Service" an das Cmdlet "Start-Service" oder
"Stop-Service" übergeben (jedoch können Sie auf diese Weise keine
deaktivierten Dienste erneut starten).
Mit der folgenden Befehlspipeline wird der WMI-Dienst auf dem
Computer gestartet:
get-service wmi | start-service
Die Cmdlets, mit denen Objekte der Windows PowerShell-Anbieter
abgerufen und festgelegt werden, z. B. die Item-Cmdlets und
ItemProperty-Cmdlets, wurden ebenfalls für die Verwendung in
Pipelines entwickelt.
Beispielsweise können Sie die Ergebnisse des Befehls "Get-Item"
oder "Get-ChildItem" im Windows PowerShell-Registrierungsanbieter
über die Pipeline an das Cmdlet "New-ItemProperty" übergeben. Mit
dem folgenden Befehl wird dem Schlüssel "MeinUnternehmen" der
neue Registrierungseintrag "AnzMitarbeiter" mit dem Wert 8214
hinzugefügt.
get-item -path HKLM:\Software\MeinUnternehmen | new-Itemproperty -name AnzMitarbeiter -value 8124
Zahlreiche Dienstprogramm-Cmdlets, z. B. Get-Member,
Where-Object, Sort-Object, Group-Object und Measure-Object,
werden fast ausschließlich in Pipelines verwendet. An diese
Cmdlets können Sie beliebige Objekte über die Pipeline übergeben.
Sie können Sie z. B. alle Prozesse auf dem Computer über die
Pipeline an den Befehl "Sort-Object" übergeben und sie nach der
Anzahl der Handles im Prozess sortieren.
get-process | sort-object -property handles
Zudem können Sie sämtliche Objekte über die Pipeline an die
Formatierungs-Cmdlets, z. B. Format-List und Format-Table, die
Export-Cmdlets, z. B. Export-Clixml und Export-CSV, sowie die
Out-Cmdlets, z. B. Out-Printer, übergeben.
So können Sie den Prozess "Winlogon" über die Pipeline an das
Cmdlet "Format-List" übergeben, um alle Eigenschaften des
Prozesses in einer Liste anzuzeigen.
get-process winlogon | format-list -property *
Mit einem bisschen Übung werden Sie feststellen, dass Sie durch
Kombination einfacher Befehle in Pipelines Zeit und
Eingabeaufwand sparen und die Skripterstellung effizienter gestalten.
FUNKTIONSWEISE VON PIPELINES
Wenn Sie Objekte über die Pipeline übergeben, d. h., die Objekte
in der Ausgabe eines Befehls an einen anderen Befehl senden,
versucht Windows PowerShell, die über die Pipeline übergebenen
Objekte einem der Parameter des empfangenden Cmdlets zuzuordnen.
Dazu sucht die Parameterbindungskomponente von Windows
PowerShell, mit der Eingabeobjekte Cmdlet-Parametern zuordnet
werden, einen Parameter, der die folgenden Kriterien erfüllt:
-- Der Parameter muss Eingaben von einer Pipeline akzeptieren
(dies trifft nicht auf alle zu).
-- Der Parameter muss den Typ des gesendeten Objekts oder einen
Typ akzeptieren, in den das Objekt konvertiert werden kann.
-- Der Parameter darf nicht bereits im Befehl verwendet werden.
Das Cmdlet "Start-Service" beispielsweise verfügt über
zahlreiche Parameter, doch nur zwei von diesen, Name und
InputObject akzeptieren Pipelineeingaben. Der Name-Parameter
akzeptiert Zeichenfolgen, und der InputObject-Parameter
akzeptiert Dienstobjekte. Deshalb können Sie Zeichenfolgen und
Dienstobjekte (sowie Objekte mit Eigenschaften, die in
Zeichenfolgen- und Dienstobjekte konvertiert werden können) über
die Pipeline an Start-Service übergeben.
Wenn die Parameterbindungskomponente von Windows PowerShell die
über die Pipeline übergebenen Objekte keinem Parameter des
empfangenden Cmdlets zuordnen kann, kann der Befehl nicht
ausgeführt werden, und Sie werden von Windows PowerShell
aufgefordert, die fehlenden Parameterwerte einzugeben.
Sie können nicht erzwingen, dass die Parameterbindungskomponente
die über die Pipeline übergebenen Objekte einem bestimmten
Parameter zuordnet, Sie können nicht einmal einen Parameter
vorschlagen. Stattdessen verwaltet die Logik der Komponente den
Pipelinevorgang so effizient wie möglich.
EINZELVERARBEITUNG
Das Übergeben von Objekten über die Pipeline an einen Befehl
ähnelt dem Senden von Objekten mit einem Parameter des Befehls.
Beispielsweise können Sie Objekte, die die Dienste auf dem
Computer darstellen, über die Pipeline an den Befehl
"Format-Table" übergeben:
get-service | format-table -property name, dependentservices
Dies ähnelt dem Speichern der Dienstobjekte in einer Variablen
und dem Senden des Dienstobjekts mit dem InputObject-Parameter
von Format-Table:
$services = get-service
format-table -inputobject $services -property name, dependentservices
Es ähnelt auch dem Einbetten des Befehls im Parameterwert:
format-table -inputobject (get-service wmi) -property name, dependentservices
Jedoch besteht ein wichtiger Unterschied. Wenn Sie mehrere
Objekte über die Pipeline an einen Befehl übergeben, sendet
Windows PowerShell die Objekte einzeln an den Befehl. Wenn Sie
einen Befehlsparameter verwenden, werden die Objekte als
einzelnes Arrayobjekt gesendet.
Dieser scheinbar technische Unterschied kann interessante und
manchmal nützliche Folgen haben.
Wenn Sie z. B. mehrere Prozessobjekte vom Cmdlet "Get-Process"
über die Pipeline an das Cmdlet "Get-Member" übergeben, sendet
Windows PowerShell jedes Prozessobjekt einzeln an Get-Member.
Get-Member zeigt die .NET-Klasse (den Typ) der Prozessobjekte
und deren Eigenschaften und Methoden an.
(Get-Member entfernt Duplikate, wenn alle Objekte vom gleichen
Typ sind, wird daher nur ein Objekttyp angezeigt.)
In diesem Fall zeigt Get-Member die Eigenschaften und Methoden
jedes Prozessobjekts an, d. h. ein System.Diagnostics.Process-Objekt.
get-process | get-member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize
...
Wenn Sie jedoch den InputObject-Parameter von Get-Member
verwenden, empfängt Get-Member ein Array von System.Diagnostics.
Process-Objekten als einzelne Einheit, und es werden die
Eigenschaften eines Objektarrays angezeigt. (Beachten Sie das
Arraysymbol ([]) nach dem Typnamen von System.Object.)
get-member -inputobject (get-process)
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
Address Method System.Object& Address(Int32 )
Clone Method System.Object Clone()
...
Dies stellt möglicherweise nicht das von Ihnen beabsichtigte
Ergebnis dar, aber sobald Sie die Funktionsweise erkannt haben,
können Sie es problemlos verwenden. Ein Array von Prozessobjekten
verfügt beispielsweise über eine Count-Eigenschaft, mit der Sie
die Anzahl der Prozesse auf dem Computer zählen können.
(get-process).count
Dieser Unterschied kann wichtig sein, vergessen Sie daher nicht,
dass Objekte einzeln übermittelt werden, wenn Sie diese über die
Pipeline an ein Cmdlet übergeben.
PIPELINEEINGABEN AKZEPTIEREN
Um Objekte in einer Pipeline zu empfangen, muss das empfangende
Cmdlet einen Parameter aufweisen, der Pipelineeingaben
akzeptiert. Sie können den Befehl "Get-Help" mit dem
Full-Parameter oder dem Parameter-Parameter verwenden, um ggf.
die Parameter eines Cmdlet zu bestimmen, die Pipelineeingaben
akzeptieren.
In der Standardanzeige von Get-Help wird das Element
"Pipelineeingaben akzeptieren" in einer Tabelle von
Parameterattributen angezeigt. Diese Tabelle wird nur angezeigt,
wenn Sie den Full-Parameter oder den Parameter-Parameter des
Cmdlet "Get-Help" verwenden.
Wenn Sie z. B. bestimmen möchten, welcher Parameter des Cmdlet
"Start-Service" Pipelineeingaben akzeptiert, geben Sie Folgendes ein:
get-help start-service -full
get-help start-service -parameter *
In der Hilfe für das Cmdlet "Start-Service" wird z. B. angezeigt,
dass der Name-Parameter und der InputObject-Parameter
Pipelineeingaben akzeptieren. Alle anderen Parameter weisen in
der Zeile "Pipelineeingaben akzeptieren?" den Wert "False" auf.
-name <string[]>
Gibt die Dienstnamen für die zu startenden Dienste an.
Der Parametername ist optional. Sie können "-Name" oder
den zugehörigen Alias "-ServiceName" verwenden oder aber
den Parameternamen auslassen.
Erforderlich? true
Position? 1
Standardwert
--> Pipelineeingaben akzeptieren? true (ByValue, ByPropertyName)
Platzhalterzeichen akzeptieren? true
-inputObject <ServiceController[]>
Gibt ServiceController-Objekte an, die die zu startenden
Dienste darstellen. Geben Sie eine Variable ein, die die
Objekte enthält, oder geben Sie einen Befehl oder einen
Ausdruck ein, mit dem die Objekte abgerufen werden.
Erforderlich? false
Position? benannt
Standardwert
--> Pipelineeingaben akzeptieren? true (ByValue)
Platzhalterzeichen akzeptieren? false
Dies bedeutet, dass Sie Objekte (PsObjects) über die Pipeline an
das Cmdlet "Where-Object" übergeben können und dieses von
Windows PowerShell dem InputObject-Parameter zugeordnet wird.
METHODEN ZUM AKZEPTIEREN VON PIPELINEEINGABEN
Parameter von Cmdlets können Pipelineeingaben mit zwei
verschiedenen Methoden akzeptieren:
-- ByValue: Parameter, die Eingaben "nach Wert" akzeptieren,
können über die Pipeline übergebene Objekte mit dem gleichen
.NET-Typ wie die entsprechenden Parameterwerte oder Objekte
akzeptieren, die in diesen Typ konvertiert werden können.
Der Name-Parameter von Start-Service akzeptiert z. B.
Pipelineeingaben nach Wert. Er akzeptiert Zeichenfolgenobjekte
oder Objekte, die in Zeichenfolgen konvertiert werden können.
-- ByPropertyName: Parameter, die Eingaben "nach Eigenschaftenwert"
akzeptieren, können über die Pipeline übergebene Objekte
nur akzeptieren, wenn eine Eigenschaft des Objekts denselben
Namen wie der Parameter besitzt.
Der Name-Parameter von Start-Service akzeptiert z. B. Objekte
mit einer Name-Eigenschaft.
(Zum Auflisten der Eigenschaften eines Objekts übergeben Sie
dieses über die Pipeline an das Cmdlet "Get-Member".)
Einige Parameter akzeptieren Objekte nach Wert oder nach
Eigenschaftennamen. Diese Parameter wurden so entworfen, dass
sie Eingaben von der Pipeline problemlos akzeptieren.
ERMITTELN VON PIPELINEFEHLERN
Wenn ein Befehl aufgrund eines Pipelinefehlers nicht
ordnungsgemäß ausgeführt wird, können Sie den Fehler untersuchen
und den Befehl umschreiben.
Mit dem folgenden Befehl wird z. B. versucht, einen
Registrierungseintrag aus einem Registrierungsschlüssel in einen
anderen zu verschieben, indem mit dem Cmdlet "Get-Item" der
Zielpfad abgerufen und dann der Pfad über die Pipeline an das
Cmdlet "Move-ItemProperty" übergeben wird.
Genauer gesagt wird in diesem Befehl mit dem Cmdlet "Get-Item"
der Zielpfad abgerufen. Das Ergebnis wird mit einem
Pipelineoperator an das Cmdlet "Move-ItemProperty" gesendet. Mit
dem Befehl "Move-ItemProperty" werden der aktuelle Pfad und der
Name des zu verschiebenden Registrierungseintrags angegeben.
get-item -path hklm:\software\meinunternehmen\vertrieb |
move-itemproperty -path hklm:\software\meinunternehmen\design -name produkt
Der Befehl wird nicht ordnungsgemäß ausgeführt, und von Windows
PowerShell wird die folgende Fehlermeldung angezeigt:
Move-ItemProperty: Das Eingabeobjekt kann nicht an die
Parameter für den Befehl gebunden werden, da der Befehl
keine Pipelineeingaben akzeptiert oder die Eingabe und deren
Eigenschaften mit keinem Parameter übereinstimmen, der
Pipelineeingaben akzeptiert.
Bei Zeile:1 Zeichen:23
+ $a | move-itemproperty <<<< -path hklm:\software\meinunternehmen\design -name produkt
Wenn Sie eine Überprüfung ausführen möchten, verwenden Sie das
Cmdlet "Trace-Command", um die Komponente ParameterBinding von
Windows PowerShell nachzuverfolgen. Mit dem folgenden Befehl wird
die Komponente "ParameterBinding" während der Befehlsverarbeitung
nachverfolgt. Mit dem -phost-Parameter werden die Ergebnisse an
der Konsole angezeigt, und mit dem -filepath-Parameter werden
diese zur späteren Referenz an die Datei "debug.txt" gesendet.
trace-command -name parameterbinding -expression {get-item -path hklm:\software\meinunternehmen\vertrieb |
move-itemproperty -path hklm:\software\meinunternehmen\design -name produkt} -pshost -filepath debug.txt
Die Ergebnisse der Ablaufverfolgung sind umfangreich, doch zeigen
diese die an das Cmdlet "Get-Item" gebundenen Werte und dann die
benannten Werte, die an das Cmdlet "Move-ItemProperty" gebunden sind.
...
BIND NAMED cmd line args [Move-ItemProperty]
BIND arg [hklm:\software\meinunternehmen\design] to parameter [Pfad]
...
BIND arg [produkt] to parameter [Name]
....
BIND POSITIONAL cmd line args [Move-ItemProperty]
...
Schließlich wird gezeigt, dass der Versuch, den Pfad an den
Destination-Parameter von Move-ItemProperty zu binden, nicht
erfolgreich war.
...
BIND PIPELINE object to parameters: [Move-ItemProperty]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values Parameter
[Destination] PIPELINE INPUT ValueFromPipelineByPropertyName
NO COERCION Parameter [Credential] PIPELINE INPUT
ValueFromPipelineByPropertyName NO COERCION
...
Zum Untersuchen des Fehlers zeigen Sie mit dem Cmdlet "Get-Help"
die Attribute des Destination-Parameters an. Mit dem folgenden
Befehl rufen Sie ausführliche Informationen zum Destination-
Parameter ab.
get-help move-itemproperty -parameter destination
Die Ergebnisse zeigen, dass Destination Pipelineeingaben nur
"nach Eigenschaftennamen" akzeptiert.
Das über die Pipeline übergebene Objekt muss daher die
Destination-Eigenschaft besitzen.
-destination <Zeichenfolge>
Gibt den Pfad zum Zielspeicherort an.
Erforderlich? true
Position? 2
Standardwert
Pipelineeingaben akzeptieren? true (ByPropertyName)
Platzhalterzeichen akzeptieren? true
Um alle Eigenschaften des über die Pipeline an das Cmdlet
"Move-ItemProperty" übergebenen Objekts anzuzeigen, übergeben
Sie es über die Pipeline an das Cmdlet "Get-Member". Im
folgenden Befehl werden die Ergebnisse des ersten Befehlsteils
über die Pipeline an das Cmdlet "Get-Member" übergeben.
get-item -path hklm:\software\meinunternehmen\vertrieb | get-member
Die Ausgabe zeigt, dass es sich bei dem Element um ein
Microsoft.Win32.RegistryKey handelt, der keine Destination-Eigen-
schaft besitzt. Dies erklärt das Fehlschlagen des Befehls.
Zum Korrigieren des Befehls muss das Ziel im Cmdlet
"Move-ItemProperty" angegeben werden. Mit dem Befehl
"Get-ItemProperty" können Sie den Pfad abrufen, jedoch müssen
der Name und das Ziel im Move-ItemProperty-Teil des Befehls
angegeben werden.
get-item -path hklm:\software\meinunternehmen\design |
move-itemproperty -dest hklm:\software\meinunternehmen\design -name produkt
Um die ordnungsgemäße Funktion des Befehls zu überprüfen,
verwenden Sie den Befehl "Get-ItemProperty":
get-itemproperty hklm:\software\meinunternehmen\vertrieb
Die Ergebnisse zeigen, dass der Registrierungseintrag "Produkt"
in den Schlüssel "Vertrieb" verschoben wurde.
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\meinun ternehmen\vertrieb
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\meinun ternehmen
PSChildName : vertrieb
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Produkt : 18
SIEHE AUCH
about_objects
about_parameters
about_command_syntax
about_foreach
C:\Windows>powershell get-help about_preference_variables -full
ColorConsole [Version 1.7.1000] PowerShell 2.0-Export
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2014 Microsoft Corporation.