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





Inhaltsverzeichnis