PowerShell HelpFile - about_pipelines
 記事記号:[me1555] 初版:2011/May/10

この文書は、Windows PowerShellのヘルプ機能で表示される内容を再構成したものです。

トピック
    about_pipelines

簡易説明
    Windows PowerShell でのパイプラインによるコマンドの結合。

詳細説明
    パイプラインとは、パイプライン演算子 (|) (ASCII 124) を使用して連結
    された一連のコマンドです。各パイプライン演算子は、直前のコマンドの
    結果を次のコマンドに渡します。
     
    パイプラインを使用すると、一方のコマンドにより出力されたオブジェクト
    を他方のコマンドの入力として使用できます。そのコマンドの出力をさらに別の
    コマンドに渡すこともできます。その結果、一連の単純なコマンドから非常に強力
    なコマンド チェーン、または "パイプライン" を作成できます。

    次に例を示します。

	Command-1 | Command-2 | Command-3

    この例では、Command-1 により出力されるオブジェクトが Command-2 に渡されます。
    Command-2 は、これらのオブジェクトを処理し、Command-3 に渡します。Command-3 
    は、これらのオブジェクトを処理し、パイプラインでの次の処理に渡します。このパ
    イプラインにはこれ以上コマンドが存在しないので、結果がコンソールに表示されま
    す。

    パイプラインでは、左から右に、表示された順序でコマンドが処理されます。
    単一の操作として処理され、出力が生成されると、そのまま表示されます。

    簡単な例を次に示します。Notepad プロセスを取得してプロセスを停止するには、
    次のコマンドを実行します。

         get-process notepad |stop-process

    最初のコマンドでは、Get-Process コマンドレットを使用して Notepad プロセスを
    表すオブジェクトを取得します。次に、パイプライン演算子 (|) によってプロセス 
    オブジェクトが Stop-Process コマンドレットに渡され、Notepad プロセスが停止し
    ます。指定されたプロセスがパイプラインを介して渡されるため、Stop-Process コ
    マンドに Name や ID などのプロセスを指定するパラメーターが含まれていないこと
    に注意してください。

    実際の使用例を次に示します。このコマンド パイプラインでは、現在のディレクト
    リからテキスト ファイルを取得し、10,000 バイトを超えるファイルだけを選択して
    長さで並べ替えた後、各ファイルの名前と長さを表に示します。

        Get-ChildItem -path *.txt | Where-Object {$_.length -gt 10000} | 
        Sort-Object -property Length | Format-Table -property name, length

    このパイプラインは、指定した順序で並べられた 4 つのコマンドから構成されてい
    ます。コマンドは横に並べて記述されますが、次の図ではプロセスの流れを縦方向に
    示しています。

       Get-ChildItem -path *.txt

                  |
                  |   (FileInfo objects )
                  |   (    .txt         )
                  |
                  V                   

       Where-Object {$_.length -gt 10000}

                  |
                  |   (FileInfo objects )
                  |   (    .txt         )
                  |   ( Length > 10000  )
                  |
                  V

       Sort-Object -property Length

                  |
                  |   (FileInfo objects  )
                  |   (    .txt          )
                  |   ( Length > 10000   )
                  |   ( Sorted by length )
                  |
                  V

       Format-Table -property name, length

                  |   
                  |   (FileInfo objects     )
                  |   (    .txt             )
                  |   ( Length > 10000      )
                  |   ( Sorted by length    )
                  |   (Formatted in a table )
                  |
                  V
        Name                       Length
        ----                       ------
        tmp1.txt                    82920
        tmp2.txt                   114000
        tmp3.txt                   114000

パイプラインの使用

    Windows PowerShell コマンドレットは、パイプラインでの使用を想定して設計され
    ています。たとえば、一般的な使用例では、Get コマンドレットで取得した結果をパ
    イプ処理し、同じ名詞の処理コマンドレット (Set、Start、Stop、Rename コマンド
    レットなど) に渡すことができます。

    たとえば、Get-Service コマンドレットからすべてのサービスをパイプ処理して、St
    art-Service または Stop-Service コマンドレットに渡すことができます (ただし、
    無効になっているサービスは、この方法では再開できません)。

    次のコマンド パイプラインを実行すると、コンピューター上で WMI サービスが起動
    されます。

	get-service wmi |start-service

    Windows PowerShell プロバイダーのオブジェクトの取得または設定を行うコマンド
    レット (Item および ItemProperty コマンドレットなど) も、パイプラインで使用
    できるように設計されています。

    たとえば、Windows PowerShell レジストリ プロバイダーの Get-Item または Get-C
    hildItem コマンドの結果をパイプ処理して、New-ItemProperty コマンドレットに渡
    すことができます。次のコマンドは、8124 という値を持つ新しいレジストリ エント
    リ NoOfEmployees を MyCompany レジストリ キーに追加します。

       get-item -path HKLM:\Software\MyCompany | new-Itemproperty -name NoOfEmpl
       oyees -value 8124

    Get-Member、Where-Object、Sort-Object、Group-Object、および Measure-Object 
    などの多くのユーティリティ コマンドレットは、ほぼパイプラインにのみ使用され
    ます。これらのコマンドレットには、あらゆるオブジェクトをパイプ処理で渡すこと
    ができます。

    たとえば、コンピューター上のすべてのプロセスをパイプ処理して Sort-Object コ
    マンドに渡し、それらをハンドル数に基づいて並べ替えることができます。

	get-process | sort-object -property handles
    
    また、Format-List および Format-Table などの書式設定用コマンドレット、Export
    -Clixml および Export-CSV などの Export コマンドレット、Out-Printer などの O
    ut コマンドレットにも、任意のオブジェクトをパイプ処理で渡すことができます。

    たとえば、Winlogon プロセスを Format-List コマンドレットにパイプ処理して渡し、
    プロセスのすべてのプロパティを一覧表示できます。

	get-process winlogon | format-list -property *

    少し練習するだけで、単純なコマンドをパイプラインで連結することが、時間や労力
    の軽減、また効率の良いスクリプトの作成につながるということを実感できます。

パイプラインの動作

     オブジェクトがパイプ処理される、つまり一方のコマンドの出力に含まれるオブジ
     ェクトが他方のコマンドに渡されると、Windows PowerShell はパイプ処理されたオ
     ブジェクトを受け取り側のコマンドレットのいずれかのパラメーターに関連付けます。

     このため、Windows PowerShell には入力オブジェクトをコマンドレット パラメータ
     ーに関連付ける "パラメーターをバインドする" コンポーネントが存在し、このコン
     ポーネントは次の条件を満たすパラメーターを検索します。
    
     -- パイプラインからの入力を許可するパラメーター (すべてのパラメーターが許可
        するわけではないため)
     -- 渡されるオブジェクトの型またはオブジェクトの変換が可能な目的の型を受け入
        れるパラメーター
     -- コマンドでまだ使用されていないパラメーター

     たとえば、Start-Service コマンドレットには多くのパラメーターが存在しますが、
     パイプラインの入力を許可するのは Name および InputObject の 2 つのパラメー
     ターのみです。Name パラメーターは文字列を受け取り、InputObjectパラメーター
     はサービス オブジェクトを受け取ります。このため、文字列およびサービス オブ
     ジェクト (または文字列およびサービス オブジェクトに変換可能なプロパティを持
     つオブジェクト) をパイプ処理して、Start-Service に渡すことができます。

     Windows PowerShell のパラメーター バインド コンポーネントが、パイプ処理され
     たオブジェクトを受け取り側のコマンドレット パラメーターに関連付けることがで
     きない場合、コマンドは失敗し、見つからなかったパラメーター値の入力を求める
     メッセージが Windows PowerShell によって表示されます。

     パラメーター バインド コンポーネントを強制して、パイプ処理されたオブジェク
     トを特定のパラメーターに関連付けることはできません。また、ユーザーがパラメ
     ーターを提示することもできません。その代わり、パイプ処理はコンポーネントの
     ロジックによって最大限効率的に管理されます。

個別の処理

     パイプ処理によるコマンドへのオブジェクトの送信は、コマンドのパラメーターに
     よるオブジェクトの送信とよく似ています。

     たとえば、コンピューター上のサービスを表すオブジェクトをパイプ処理で Format
     -Table コマンドに渡す操作について考えます。

		  get-service | format-table -property name, dependentservices

     この操作は、サービス オブジェクトを変数に格納し、Format-Table の InputObjec
     t パラメーターを使用してサービス オブジェクトを送信する操作と非常に似ていま
     す。

		  $services = get-service
                  format-table -inputobject $services -property name, dependents
                  ervices

     または、コマンドをパラメーター値に埋め込む操作と似ています。

                  format-table -inputobject (get-service wmi) -property name, de
                  pendentservices

     ただし、大きな違いがあります。つまり、複数のオブジェクトをコマンドに渡す場合、
     パイプ処理ではオブジェクトが一度に 1 つずつコマンドに渡されます。一方、コマ
     ンド パラメーターを使用する場合は、オブジェクトが単一の配列オブジェクトとし
     て渡されます。

     見かけは機能上の違いですが、これによって興味深い効果、場合によっては便利な効
     果を得ることができます。

     たとえば、複数のプロセス オブジェクトをパイプ処理して、Get-Process コマンド
     レットから Get-Member コマンドレットに渡す場合、Windows PowerShell ではプロ
     セス オブジェクトは一度に 1 つずつ Get-Member に渡されます。Get-Member は、
     プロセス オブジェクトの .NET クラス (型)、プロパティ、およびメソッドを表示
     します(Get-Member では、重複は取り除かれます。このため、すべてのオブジェク
     トの型が同じである場合は、1 つのオブジェクト型のみが表示されます)。

     この場合、Get-Member によって各プロセス オブジェクト (System.Diagnostics.Pr
     ocess オブジェクト) のプロパティとメソッドが表示されます。

                 get-process | get-member

                    TypeName: System.Diagnostics.Process

                 Name      MemberType     Definition
                 ----      ----------     ----------
                 Handles   AliasProperty  Handles = Handlecount
                 Name      AliasProperty  Name = ProcessName
                 NPM       AliasProperty  NPM = NonpagedSystemMemorySize
                 ...
    
      一方、Get-Member の InputObject パラメーターを使用すると、System.Diagnosti
      cs.Process オブジェクトの配列が 1 つの単位として Get-Member に渡されます。
      このため、オブジェクトの配列のプロパティが表示されます (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()
                ...

     結果が意図したものと異なるかもしれませんが、しくみを理解することで、適切に
     利用できます。たとえば、プロセス オブジェクトの配列には Count プロパティが
     あります。これを利用して、コンピューター上のプロセスの数をカウントすること
     ができます。

		(get-process).count
                
     この違いが重要になることがあります。したがって、オブジェクトをパイプ処理し
     てコマンドレットに渡す場合は、オブジェクトが一度に 1 つずつ渡されることに
     注意してください。

パイプライン入力の許可

    パイプラインでオブジェクトを受け取るには、受け取る側のコマンドレットにパイプ
    ライン入力を許可するパラメーターが存在している必要があります。Get-Help コマ
    ンドを Full または Parameter パラメーターと一緒に使用すると、パイプライン入
    力を許可するコマンドレットのパラメーターを特定できます (存在する場合)。

    Get-Help の既定の表示では、パラメーター属性のテーブルに "パイプライン入力を許
    可する" という項目が表示されます。このテーブルは、Get-Help コマンドレットの F
    ull または Parameter パラメーターを設定した場合にのみ表示されます。

    たとえば、Start-Service コマンドレットのどのパラメーターがパイプライン入力を
    許可しているかを調べるには、次のように入力します。
       
        get-help start-service -full

        get-help start-service -parameter *

    たとえば、Start-Service コマンドレットのヘルプによると、パイプライン入力を許
    可する ("true") パラメーターは Name および InputObject パラメーターです。そ
    の他のパラメーターでは、"パイプライン入力を許可する" 行の値が "false" になっ
    ています。

        -name <string[]>
           開始するサービスのサービス名を指定します。
           パラメーター名は省略可能です。-Name またはそのエイリアスである -Servi
           ceName を使用するか、パラメーター名を省略することができます。

           必須                         true
           位置                         1
           既定値
      -->  パイプライン入力を許可する   true (ByValue, ByPropertyName)
           ワイルドカード文字を許可する true

        -inputObject <ServiceController[]>
           開始するサービスを表す ServiceController オブジェクトを指定します。
           オブジェクトが格納されている変数を入力するか、オブジェクトを取得
           するコマンドまたは式を記述します。

           必須                         false
           位置                         named
           既定値
      -->  パイプライン入力を許可する   true (ByValue)
           ワイルドカード文字を許可する false

     これは、パイプラインを介してオブジェクト (PsObjects) を Where-Object コマン
     ドレットに渡すことができ、渡されたオブジェクトは Windows PowerShell によっ
     て InputObject パラメーターに関連付けられることを示しています。


パイプライン入力を許可する方法

     コマンドレット パラメーターでパイプライン入力を許可するには、次の 2 つの方
     法があります。

     -- ByValue: "値に基づいて" 入力を許可するパラメーターは、パイプ処理された
        オブジェクトの .NET 型がパラメーターの値と同じであるか、オブジェクトを
        その型に変換可能な場合にオブジェクトを許可します。

        たとえば、Start-Service の Name パラメーターは、値に基づいてパイプライ
        ン入力を許可します。この場合、文字列オブジェクトまたは文字列に変換する
        ことができるオブジェクトが許可されます。

     -- ByPropertyName: "プロパティ名に基づいて" 入力を許可するパラメーターは、
        パイプ処理されたオブジェクトにパラメーターと同じ名前のプロパティが存在す
        る場合にオブジェクトを許可します。

        たとえば、Start-Service の Name パラメーターは、Name プロパティを持つオ
        ブジェクトを許可します。

        (オブジェクトのプロパティを一覧表示するには、オブジェクトをパイプ処理し
        て Get-Member に渡します。)

     一部のパラメーターでは、値およびプロパティ名のどちらに基づいてもオブジェク
     トを許可できます。これらのパラメーターは、簡単にパイプライン入力を受け取る
      ことができるように設計されています。

パイプライン エラーの調査

     パイプラインのエラーによりコマンドが失敗する場合は、エラーを調査し、コマン
     ドを書き直すことができます。

     たとえば、次のコマンドでは、Get-Item コマンドレットを使用して移動先のパスを
     取得し、そのパスをパイプ処理で Move-ItemProperty コマンドレットに渡すことに
     より、レジストリ エントリを一方のレジストリ キーから他方のレジストリ キーに
     移動します。

     具体的には、このコマンドは Get-Item コマンドレットを使用して移動先のパスを
     取得します。結果を Move-ItemProperty コマンドレットに渡すために、パイプライ
     ン演算子が使用されます。Move-ItemProperty コマンドは、移動するレジストリ 
     エントリの現在のパスおよび名前を指定します。

          get-item -path hklm:\software\mycompany\sales | 
          move-itemproperty -path hklm:\software\mycompany\design -name product

     このコマンドは失敗し、Windows PowerShell により次のエラー メッセージが表示
     されます。

         Move-ItemProperty: 入力オブジェクトをコマンドのパラメーターにバインドで
         きません。コマンドがパイプライン入力を受け入れないか、または入力とその
         プロパティが、パイプライン入力を受け入れるいずれのパラメーターにも一致
         しません。
         行:1 文字:23
         + $a | move-itemproperty <<<<  -path hklm:\software\mycompany\design 
         -name product

    調査するには、Trace-Command コマンドレットを使用して Windows PowerShell のパ
    ラメーター バインド コンポーネントをトレースします。次のコマンドでは、コマン
    ドの処理中にパラメーター バインド コンポーネントがトレースされます。-pshost 
    パラメーターを使用して結果をコンソールに表示し、後で参照できるように、-filep
    ath コマンドを使用して結果を debug.txt ファイルに送信します。

         trace-command -name parameterbinding -expression {get-item -path hklm:\
         software\mycompany\sales | move-itemproperty -path hklm:\software\mycom
         pany\design -name product} -pshost -filepath debug.txt

    トレース結果は非常に長いものですが、Get-Item コマンドレットにバインドされて
    いる値、さらに Move-ItemProperty コマンドレットにバインドされている名前付き
    の値が示されています。

       ... 
        BIND NAMED cmd line args [Move-ItemProperty]
            BIND arg [hklm:\software\mycompany\design] to parameter [Path]
        ...
            BIND arg [product] to parameter [Name]
        ....
        BIND POSITIONAL cmd line args [Move-ItemProperty]
        ...

    最後に、Move-ItemProperty の Destination パラメーターへのパスのバインドに失
    敗したことが示されています。
        ...
        BIND PIPELINE object to parameters: [Move-ItemProperty]
            PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
            RESTORING pipeline parameter's original values
            Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyN
            ame NO COERCION
            Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyNa
            me NO COERCION
        ...

     エラーを調査するには、Get-Help コマンドレットを使用して Destination パラメ
     ーターの属性を表示します。次のコマンドを入力すると、Destination パラメータ
     ーに関する詳細情報を取得できます。

	get-help move-itemproperty -parameter destination

     結果には、Destination が "プロパティ名に基づいて" のみパイプライン入力を受
     け取ることが示されています。つまり、パイプ処理されたオブジェクトに Destinat
     ion という名前のプロパティが存在している必要があります。

        -destination <string>
            移動先のパスを指定します。

            必須                         true
            位置                         2
            既定値
            パイプライン入力を許可する   true (ByPropertyName)
            ワイルドカード文字を許可する true    

     パイプ処理で Move-ItemProperty コマンドレットにパイプされるオブジェクトのプ
     ロパティを表示するには、オブジェクトをパイプ処理して Get-Member コマンドレ
     ットに渡します。次のコマンドでは、コマンドの最初の部分の結果をパイプ処理し
     て Get-Member コマンドレットに渡します。

          get-item -path hklm:\software\mycompany\sales |get-member 

     出力では、項目が Microsoft.Win32.RegistryKey で、この項目には Destination 
     プロパティが含まれないことが示されます。これがコマンドが失敗した理由です。

     コマンドを修正するには、Move-ItemProperty コマンドレットに移動先を指定する
     必要があります。Get-ItemProperty コマンドを使用してパスを取得することはでき
     ますが、コマンドの Move-ItemProperty 部分で名前と移動先を指定する必要があり
     ます。
          
         get-item -path hklm:\software\mycompany\design | 
         move-itemproperty -dest hklm:\software\mycompany\design -name product

     コマンドが成功したかどうかを確認するには、Get-ItemProperty コマンドを使用し
     ます。

	get-itemproperty hklm:\software\mycompany\sales

     結果から、Product レジストリ エントリが Sales キーに移動されたことがわかり
     ます。

        PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\so
                       ftware\mycompany\sales
        PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\so
                       ftware\mycompany
        PSChildName  : sales
        PSDrive      : HKLM
        PSProvider   : Microsoft.PowerShell.Core\Registry
        Product      : 18

関連項目
    about_objects
    about_parameters
    about_command_syntax
    about_foreach
	
記事で解説しているパソコンの環境
 基本ソフト: Windows 7
 キーワード: Windows PowerShell、ヘルプ、HelpFile、about_pipelines
ご利用数: 1917619
感想・要望・問い合わせは こちら