全2話で PowerShell で、複数のデータ(オブジェクト)を複数のコマンドレットで処理する際の、処理の流れについてプログラムを実行して検証します。
データ全体に対して並び替えの処理を行う Sort-Object による処理の流れの違いについても検証します。
※ Windows PowerShell 5.1.19041.5965 を使用します。
※プログラムは自己責任でご利用ください。
Sort-Object を入れる前の処理の流れ
以下は、3つのオブジェクト 1, 3, 2 を “Input: 数値” の形式で出力した後、 “Output: 数値” の形式でアプリに表示する PowerShell のプログラムです。
1, 3, 2 |
ForEach-Object { Write-Host "Input: $_"; $_ } |
ForEach-Object { Write-Host "Output: $_" }
これを実行する前に、このプログラムで使用するコマンドレットと、2行目の後半の ; $_ について説明します。
ForEach-Object は受け取ったオブジェクトを順次処理する
ForEach-Object コマンドレットでは、パイプラインの上流から1個ずつ渡されてくるオブジェクトを逐次処理します。
※パイプラインの上流から渡されたオブジェクトを1個ずつ処理するだけで、この ForEach-Object のスコープでループ処理を行うわけではありません。
ForEach-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn
ForEach-Object
コマンドレットは、入力オブジェクトのコレクション内の各項目に対して操作を実行します。 入力オブジェクトは、コマンドレットにパイプ処理することも、 InputObject パラメーターを使用して指定することもできます。
ForEach-Object コマンドレットについては、以下の記事も参照してください。
Write-Host コマンドレットで、オブジェクトを表示
Write-Host コマンドレットは、ホスト(例では Windows PowerShell アプリ)に、オブジェクトの内容を表示します。
カスタマイズされた出力をホストに書き込みます。
Write-Host "Red on white text." -ForegroundColor red -BackgroundColor white
このコマンドは、”白いテキストに赤” という文字列を表示します。
Write-Host (Microsoft.PowerShell.Utility) – PowerShell | Microsoft LearnForegroundColor
パラメーターで定義されているように、テキストは赤です。BackgroundColor
パラメーターで定義されているように、背景は白です。
最後に実行した文(式)がパイプで渡すオブジェクトに設定される
2行目は、 Write-Host コマンドレットで “Input: $_” を出力した後に ; 6 と書かれています。
; は、プログラムの文 (Write-Host “Input: $_” など)の区切り文字で、次の新たな文を記述する際に用います。
6 は、”文字列” や 1 + 2 と同じ式ですが、 PowerShell のパイプラインでは、式は文としても扱います。
ところで上記①や②は右辺が式です。代入文の右辺は文じゃなかったの?と思われると思いますが、パイプラインの節で述べた通り、単独の式もパイプラインであり、パイプラインは文なので、三段論法でいくと式は文として扱われることになります。
PowerShellにおける「文」と「式」についての考察 – PowerShell Scripting Weblog
この 6 という式の値は、パイプを経た次の処理に渡されるオブジェクトとして $_ 自動変数に格納されます。
その結果、パイプを経た次の処理で “Output: $_” を表示した結果は 1, 3, 2 ではなく、全て 6 になりました。
PS G:\Dev\PowerShell> 1, 3, 2 |
>> ForEach-Object { Write-Host "Input: $_"; 6 } |
>> ForEach-Object { Write-Host "Output: $_" }
Input: 1
Output: 6
Input: 3
Output: 6
Input: 2
Output: 6
パイプに渡すオブジェクトがないと処理が終了する
この ; 6 を消した、以下のプログラムを実行するとどうなるでしょう。
1, 3, 2 |
ForEach-Object { Write-Host "Input: $_"} |
ForEach-Object { Write-Host "Output: $_" }
Write-Host コマンドレットは出力を返さないため、パイプを経た次の処理にオブジェクトが渡されなくなり、次の処理 (例では “Output: $_” の表示) も行われなくなりました。
PS G:\Dev\PowerShell> 1, 3, 2 |
>> ForEach-Object { Write-Host "Input: $_"} |
>> ForEach-Object { Write-Host "Output: $_" }
Input: 1
Input: 3
Input: 2
このコマンドレットは出力を返しません。 ホストにオブジェクトを送信します。 ホストは、このコマンドレットが送信するオブジェクトを表示します。
Write-Host (Microsoft.PowerShell.Utility) – PowerShell | Microsoft Learn
オブジェクトが渡されない “Output: $_” を表示する部分の $_ を取り除いても出力はされなかったので、パイプにオブジェクトが渡されなくなった時点で処理が終了すると推測できます。
PS G:\Dev\PowerShell> 1, 3, 2 |
>> ForEach-Object { Write-Host "Input: $_"} |
>> ForEach-Object { Write-Host "Output: ?" }
Input: 1
Input: 3
Input: 2
実行結果
冒頭で紹介したプログラムを Windows PowerShell アプリを起動して、プログラムのコピーを貼り付けて Enter キーで実行します。
※ Windows 10 の場合、エクスプローラのアドレスバーで powershell⏎ と入力すると、そのフォルダをカレントディレクトリにして Windows PowerShell アプリを起動できます。

結果は、一番上流にある 1, 3, 2 という3つの数値のオブジェクト1つずつ、順番に処理されました。
1番目のオブジェクト (数値 1) の処理が完了した後に、2番目のオブジェクト (数値 3) の処理が行われ、最後に3番目のオブジェクト (数値 2) の処理が行われました。
PS G:\Dev\PowerShell> 1, 3, 2 |
>> ForEach-Object { Write-Host "Input: $_"; $_ } |
>> ForEach-Object { Write-Host "Output: $_" }
Input: 1
Output: 1
Input: 3
Output: 3
Input: 2
Output: 2
今回はここまで
今回は、パイプでつながった処理は、オブジェクト1つずつ順番に実行されることがわかりました。
後半では、このプログラムの中間の処理に Sort-Object コマンドレットを入れた場合の、処理の流れの変化について紹介します。
参照サイト Thank You!
- PowerShell とは – PowerShell | Microsoft Learn
- ForEach-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn
- Write-Host (Microsoft.PowerShell.Utility) – PowerShell | Microsoft Learn
- Sort-Object (Microsoft.PowerShell.Utility) – PowerShell | Microsoft Learn
- PowerShellにおける「文」と「式」についての考察 – PowerShell Scripting Weblog
記事一覧 → Compota-Soft-Press
コメント