Foreach-Object コマンドレットの使用

オブジェクトのコレクション内のループ

ForEach-Object コマンドレットを使用すると、コレクション内の各アイテムをループ処理し、動作を実行することができます。そのことを念頭に置くと、多くの場合、ForEach-Object を使用する必要はありません。既定では、多くのコマンドレットがコレクション内のすべてのアイテムの処理に対応しているためです。たとえば、Get-Process コマンドレットを呼び出すと、コンピュータで実行されているすべての処理に関する情報が自動的に返されます。コレクション内をループするために ForEach-Object を使用する必要はありません (これは VBScript とは違います。通常、VBScript の場合、コレクション内の全アイテムを取得するには、毎回 For Each を設定する必要があります)。

一方、その他の書式を設定したり、コレクション内のオブジェクトに対する変更を加えたりするときがあります。この場合、通常、ForEach-Object を使用する必要があります。たとえば、処理名の一覧を表示し、処理名をシアン色で表記したいとします (心配は無用です。Scripting Guys は皆さんの選択した内容や、選択した理由を批判することはありません)。次のコマンドは失敗します。というのも、Write-Host コマンドレットはパイプラインで送信されたデータの処理方法がわからないためです。

Get-Process | Write-Host $_.name -foregroundcolor cyan

より具体的には、次のエラー メッセージが返されます。

発生場所 行:1 文字:25
+ get-process | write-host  <<<< $_.name -foregroundcolor cyan Write-Host : The input object 
Write-Host : 入力オブジェクトをコマンドのパラメータにバインドできません。
コマンドがパイプライン入力を受け入れないか、
または入力とそのプロパティが、パイプライン入力を受け入れるいずれのパラメータにも一致しません。

それでは、このような場合にどうすればよいでしょうか。もちろん、ForEach-Object を使用します。

Get-Process | ForEach-Object {Write-Host $_.name -foregroundcolor cyan}

今回は、処理情報を取得し、Write-Host ではなく ForEach-Object にパイプ処理します。これは、パイプラインを越えて渡されたオブジェクト コレクションを処理する方法を ForEach-Object が理解しているためです。コレクション内をループし、各オブジェクトに 1 つずつ何かを実行します。これらのオブジェクトはどうなるでしょうか。簡単です。ForEach-Object は波かっこで囲まれたコマンドを実行します。この場合、コレクション内の各アイテムについて Write-Host コマンドレットを使用して、Name プロパティ値を画面にシアン色で書き出します。

コマンドの実行後のコンソール ウィンドウの表示を次に示します。

Windows PowerShell

ForEach-Object のエイリアス
  • foreach

関連リンク