次の方法で共有


ForEach-Object

入力オブジェクトのコレクション内の各項目に対して操作を実行します。

構文

ForEach-Object
            [-InputObject <PSObject>]
            [-Begin <ScriptBlock>]
            [-Process] <ScriptBlock[]>
            [-End <ScriptBlock>]
            [-RemainingScripts <ScriptBlock[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]
ForEach-Object
            [-InputObject <PSObject>]
            [-MemberName] <String>
            [-ArgumentList <Object[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]
ForEach-Object
            -Parallel <scriptblock>
            [-InputObject <psobject>]
            [-ThrottleLimit <int>]
            [-TimeoutSeconds <int>]
            [-AsJob]
            [-UseNewRunspace]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

説明

ForEach-Object コマンドレットは、入力オブジェクトのコレクション内の各項目に対して操作を実行します。 入力オブジェクトは、コマンドレットにパイプ処理することも、 InputObject パラメーターを使用して指定することもできます。

Windows PowerShell 3.0 以降では、 ForEach-Object コマンドを作成する 2 つの異なる方法があります。

  • スクリプト ブロックの構文。 スクリプト ブロックを使用して操作を指定できます。 スクリプト ブロック内で、 $_ 変数を使用して現在のオブジェクトを表します。 スクリプト ブロックは 、Process パラメーターの値です。 スクリプト ブロックには、任意の PowerShell スクリプトを含めることができます。

    たとえば、次のコマンドは、コンピューター上の各 プロセスの ProcessName プロパティの値を取得します。

    Get-Process | ForEach-Object {$_.ProcessName}

    ForEach-Objectは、about_Functions で説明されているように、beginprocess、およびend ブロックをサポートします。

    スクリプト ブロックは、呼び出し元のスコープで実行されます。 そのため、ブロックはそのスコープ内の変数にアクセスでき、コマンドレットの完了後にそのスコープに保持される新しい変数を作成できます。

  • 簡略化された構文。 簡略化された構文を使用して、パイプライン内のオブジェクトのプロパティまたはメソッド名を指定します。 ForEach-Object は、パイプライン内の各オブジェクトのプロパティまたはメソッドの値を返します。

    たとえば、次のコマンドは、コンピューター上の各 プロセスの ProcessName プロパティの値も取得します。

    Get-Process | ForEach-Object ProcessName

    簡略化された構文は、Windows PowerShell 3.0 で導入されました。 詳細については、「 about_Simplified_Syntax」を参照してください。

  • 並列実行スクリプト ブロック。 PowerShell 7.0 以降では、各スクリプト ブロックを並列で実行する 3 つ目のパラメーター セットを使用できます。 ThrottleLimit パラメーターは、一度に実行される並列スクリプトの数を制限します。 前と同様に、 $_ 変数を使用して、スクリプト ブロック内の現在の入力オブジェクトを表します。 Using: スコープ修飾子を使用して、実行中のスクリプトに変数参照を渡します。

    PowerShell 7 では、ループイテレーションごとに新しい実行空間が作成され、最大限の分離が確保されます。 これは、新しい実行空間の作成に比べて作業が少ない場合や、多くの反復で大きな作業が実行されている場合に、パフォーマンスとリソースに大きな影響を与える可能性があります。 PowerShell 7.1 の時点では、実行空間プールからの実行空間は既定で再利用されます。 ThrottleLimit パラメーターは、実行空間プールのサイズを設定します。 既定の実行空間プール のサイズは 5 です。 UseNewRunspace スイッチを使用して、イテレーションごとに新しい実行空間を作成できます。

    既定では、並列スクリプト ブロックは、並列タスクを開始した呼び出し元の現在の作業ディレクトリを使用します。

    詳細については、この記事の 「メモ 」セクションを参照してください。

例 1: 配列内の整数を除算する

この例では、3 つの整数の配列を受け取り、それぞれの整数を 1024 で除算します。

30000, 56798, 12432 | ForEach-Object -Process {$_/1024}

29.296875
55.466796875
12.140625

例 2: ディレクトリ内のすべてのファイルの長さを取得する

この例では、PowerShell インストール ディレクトリのファイルとディレクトリを $PSHOME処理します。

Get-ChildItem $PSHOME | ForEach-Object -Process {
    if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }
}

オブジェクトがディレクトリでない場合、スクリプト ブロックはファイルの名前を取得し、 Length プロパティの値を 1024 で除算し、スペース (" ") を追加して次のエントリから区切ります。 このコマンドレットでは、 PSIsContainer プロパティを使用して、オブジェクトがディレクトリであるかどうかを判断します。

例 3: 最新のシステム イベントを操作する

次の使用例は、システム イベント ログから 1000 件の最新のイベントをテキスト ファイルに書き込みます。 現在の時刻は、イベントの処理の前後に表示されます。

Get-EventLog -LogName System -Newest 1000 |
    ForEach-Object -Begin {Get-Date} -Process {
        Out-File -FilePath Events.txt -Append -InputObject $_.Message
    } -End {Get-Date}

Get-EventLog は、システム イベント ログから最新の 1000 個のイベントを取得し、それらを ForEach-Object コマンドレットにパイプします。 Begin パラメーターには、現在の日付と時刻が表示されます。 次に、 Process パラメーターは、 Out-File コマンドレットを使用して、events.txt という名前のテキスト ファイルを作成し、そのファイル内の各イベントのメッセージ プロパティを格納します。 最後に、 End パラメーターは、すべての処理が完了した後の日付と時刻を表示するために使用されます。

例 4: レジストリ キーの値を変更する

次の使用例は、 キーのすべてのサブキーの HKCU:\Network レジストリ エントリの値を大文字のテキストに変更します。

Get-ItemProperty -Path HKCU:\Network\* |
  ForEach-Object {
    Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
  }

この形式を使用して、レジストリ エントリ値のフォームまたはコンテンツを変更できます。

ネットワーク キーの各サブキーは、サインオン時に再接続するマップされたネットワーク ドライブを表します。 RemotePath エントリには、接続されているドライブの UNC パスが含まれています。 たとえば、E: ドライブを\\Server\Shareにマップすると、RemotePath レジストリ値が HKCU:\Network に設定された E サブキーが\\Server\Shareに作成されます。

このコマンドでは、 Get-ItemProperty コマンドレットを使用して ネットワーク キーのすべてのサブキーを取得し、 Set-ItemProperty コマンドレットを使用して各キーの RemotePath レジストリ エントリの値を変更します。 Set-ItemProperty コマンドでは、パスはレジストリ キーの PSPath プロパティの値です。 これは、レジストリ エントリではなく、レジストリ キーを表す Microsoft .NET Framework オブジェクトのプロパティです。 このコマンドは、文字列REG_SZである RemotePath 値の ToUpper() メソッドを使用します。

Set-ItemPropertyは各キーのプロパティを変更するため、プロパティにアクセスするには ForEach-Object コマンドレットが必要です。

例 5: $null自動変数を使用する

この例では、 $null 自動変数を ForEach-Object コマンドレットにパイプ処理する効果を示します。

1, 2, $null, 4 | ForEach-Object {"Hello"}

Hello
Hello
Hello
Hello

PowerShell は $null を明示的なプレースホルダーとして扱うため、 ForEach-Object コマンドレットは、パイプされた他のオブジェクトの場合と同様に、 $null の値を生成します。

例 6: プロパティ値を取得する

この例では、 コマンドレットの MemberName パラメーターを使用して、インストールされているすべての PowerShell モジュールの ForEach-Object プロパティの値を取得します。

Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | foreach Path

2 番目のコマンドは、最初のコマンドと同じです。 Foreach コマンドレットのForEach-Objectエイリアスを使用し、MemberName パラメーターの名前を省略します(省略可能)。

ForEach-Object コマンドレットは、Format コマンドレットやプロパティ値の型を変更する Select-Object コマンドレットとは異なり、型を変更せずに値を取得するため、プロパティ値を取得する場合に便利です。

例 7: モジュール名をコンポーネント名に分割する

この例では、2 つのドット区切りのモジュール名をコンポーネント名に分割する 3 つの方法を示します。 このコマンドは、文字列の Split メソッドを呼び出します。 3 つのコマンドは異なる構文を使用しますが、同等で交換可能です。 出力は、3 つのケースすべてで同じです。

"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object {$_.Split(".")}
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object -MemberName Split -ArgumentList "."
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    foreach Split "."

Microsoft
PowerShell
Core
Microsoft
PowerShell
Host

最初のコマンドでは、スクリプト ブロックと現在のオブジェクト演算子 $_を含む従来の構文を使用します。 ドット構文を使用して、区切り記号引数を囲むメソッドとかっこを指定します。

2 番目のコマンドでは 、MemberName パラメーターを使用して Split メソッドを指定し 、ArgumentList パラメーターを使用してドット (.) を分割区切り記号として識別します。

3 番目のコマンドは、foreach コマンドレットのForEach-Objectエイリアスを使用し、MemberName パラメーターと ArgumentList パラメーターの名前を省略します(省略可能)。

例 8: 2 つのスクリプト ブロックで ForEach-Object を使用する

この例では、2 つのスクリプト ブロックを位置指定して渡します。 すべてのスクリプト ブロックは Process パラメーターにバインドされます。 ただし、これらは Begin パラメーターと Process パラメーターに渡されたかのように扱われます。

1..2 | ForEach-Object { 'begin' } { 'process' }

begin
process
process

例 9: 2 つ以上のスクリプト ブロックで ForEach-Object を使用する

この例では、4 つのスクリプト ブロックを位置指定して渡します。 すべてのスクリプト ブロックは Process パラメーターにバインドされます。 ただし、これらは BeginProcess、End の各パラメーターに渡されたかのように扱われます。

1..2 | ForEach-Object { 'begin' } { 'process A' }  { 'process B' } { 'end' }

begin
process A
process B
process A
process B
end

最初のスクリプト ブロックは常に begin ブロックにマップされ、最後のブロックは end ブロックにマップされ、2 つの中間ブロックは process ブロックにマップされます。

例 10: パイプライン項目ごとに複数のスクリプト ブロックを実行する

前の例に示すように、 Process パラメーターを使用して渡された複数のスクリプト ブロックが Begin パラメーターと End パラメーターにマップされます。 このマッピングを回避するには、 Begin パラメーターと End パラメーターに明示的な値を指定する必要があります。

1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null

one
two
three
one
two
three

例 11: 低速スクリプトを並列バッチで実行する

この例では、文字列を評価し、1 秒間スリープするスクリプト ブロックを実行します。

$Message = "Output:"

1..8 | ForEach-Object -Parallel {
    "$Using:Message $_"
    Start-Sleep 1
} -ThrottleLimit 4

Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8

ThrottleLimit パラメーターの値は 4 に設定され、入力は 4 つのバッチで処理されます。 Using: スコープ修飾子は、各並列スクリプト ブロックに$Message変数を渡すために使用されます。

例 12: ログ エントリを並列で取得する

この例では、ローカル Windows マシン上の 5 つのシステム ログから 50,000 個のログ エントリを取得します。

$logNames = 'Security', 'Application', 'System', 'Windows PowerShell',
    'Microsoft-Windows-Store/Operational'

$logEntries = $logNames | ForEach-Object -Parallel {
    Get-WinEvent -LogName $_ -MaxEvents 10000
} -ThrottleLimit 5

$logEntries.Count

50000

Parallel パラメーターは、入力ログ名ごとに並列で実行されるスクリプト ブロックを指定します。 ThrottleLimit パラメーターを使用すると、5 つのスクリプト ブロックすべてが同時に実行されます。

例 13: ジョブとして並列で実行する

この例では、スクリプト ブロックを同時に 2 つずつ実行するジョブを作成します。

PS> $job = 1..10 | ForEach-Object -Parallel {
    "Output: $_"
    Start-Sleep 1
} -ThrottleLimit 2 -AsJob

PS> $job

Id     Name            PSJobTypeName   State         HasMoreData     Location      Command
--     ----            -------------   -----         -----------     --------      -------
23     Job23           PSTaskJob       Running       True            PowerShell    …

PS> $job.ChildJobs

Id     Name            PSJobTypeName   State         HasMoreData     Location      Command
--     ----            -------------   -----         -----------     --------      -------
24     Job24           PSTaskChildJob  Completed     True            PowerShell    …
25     Job25           PSTaskChildJob  Completed     True            PowerShell    …
26     Job26           PSTaskChildJob  Running       True            PowerShell    …
27     Job27           PSTaskChildJob  Running       True            PowerShell    …
28     Job28           PSTaskChildJob  NotStarted    False           PowerShell    …
29     Job29           PSTaskChildJob  NotStarted    False           PowerShell    …
30     Job30           PSTaskChildJob  NotStarted    False           PowerShell    …
31     Job31           PSTaskChildJob  NotStarted    False           PowerShell    …
32     Job32           PSTaskChildJob  NotStarted    False           PowerShell    …
33     Job33           PSTaskChildJob  NotStarted    False           PowerShell    …

ThrottleLimit パラメーターは、一度に実行される並列スクリプト ブロックの数を制限します。 AsJob パラメーターを指定すると、ForEach-Object コマンドレットは出力をコンソールにストリーミングするのではなく、ジョブ オブジェクトを返します。 $job変数は、出力データを収集し、実行中の状態を監視するジョブ オブジェクトを受け取ります。 $job.ChildJobs プロパティには、並列スクリプト ブロックを実行する子ジョブが含まれています。

例 14: スレッド セーフ変数参照の使用

この例では、スクリプト ブロックを並列で呼び出して、一意の名前の Process オブジェクトを収集します。

$threadSafeDictionary = [System.Collections.Concurrent.ConcurrentDictionary[string,object]]::new()
Get-Process | ForEach-Object -Parallel {
    $dict = $Using:threadSafeDictionary
    $dict.TryAdd($_.ProcessName, $_)
}

$threadSafeDictionary["pwsh"]

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     82    82.87     130.85      15.55    2808   2 pwsh

ConcurrentDictionary オブジェクトの 1 つのインスタンスが各スクリプト ブロックに渡され、オブジェクトが収集されます。 ConcurrentDictionary はスレッド セーフであるため、各並列スクリプトで変更しても安全です。 System.Collections.Generic.Dictionary などのスレッド セーフでないオブジェクトは、ここでは安全に使用できません。

この例は、 Parallel パラメーターの非効率的な使用です。 このスクリプトは、入力オブジェクトをコンカレント ディクショナリ オブジェクトに追加します。 これは簡単で、個別のスレッドで各スクリプトを呼び出すオーバーヘッドの価値はありません。 ForEach-Objectスイッチを使用せずにを実行すると、より効率的かつ高速になります。 この例は、スレッド セーフ変数を使用する方法を示すことを目的としています。

例 15: 並列実行によるエラーの書き込み

この例では、書き込まれたエラーの順序がランダムであるエラー ストリームに並列で書き込みます。

1..3 | ForEach-Object -Parallel {
    Write-Error "Error: $_"
}

Write-Error: Error: 1
Write-Error: Error: 3
Write-Error: Error: 2

例 16: 並列実行でのエラーの終了

この例では、1 つの並列実行スクリプト ブロックで終了エラーを示します。

1..5 | ForEach-Object -Parallel {
    if ($_ -eq 3)
    {
        throw "Terminating Error: $_"
    }

    Write-Output "Output: $_"
}

Exception: Terminating Error: 3
Output: 1
Output: 4
Output: 2
Output: 5

Output: 3 は、そのイテレーションの並列スクリプト ブロックが終了したために書き込まれることはありません。

PipelineVariable 共通パラメーター変数は、 スコープ修飾子を使用しても、ForEach-Object -ParallelシナリオではサポートUsing:

例 17: 入れ子になった並列スクリプト ブロックで変数を渡す

ForEach-Object -Parallelスコープスクリプトブロックの外部に変数を作成し、Using:スコープ修飾子を使用してスクリプトブロック内で使用できます。 PowerShell 7.2 以降では、 ForEach-Object -Parallel スコープスクリプトブロック内に変数を作成し、入れ子になったスクリプトブロック内で使用できます。

$test1 = 'TestA'
1..2 | ForEach-Object -Parallel {
    $Using:test1
    $test2 = 'TestB'
    1..2 | ForEach-Object -Parallel {
        $Using:test2
    }
}

TestA
TestA
TestB
TestB
TestB
TestB

PowerShell 7.2 より前のバージョンでは、入れ子になった scriptblock は $test2 変数にアクセスできないため、エラーがスローされます。

例 18: スクリプトを並列で実行する複数のジョブを作成する

ThrottleLimit パラメーターは、 ForEach-Object -Parallelの各インスタンスで実行される並列スクリプトの数を制限します。 AsJob パラメーターを使用するときに作成できるジョブの数は制限されません。 ジョブ自体は同時に実行されるため、複数の並列ジョブを作成し、それぞれが同時スクリプト ブロックのスロットル制限数まで実行できます。

$jobs = for ($i=0; $i -lt 10; $i++) {
    1..10 | ForEach-Object -Parallel {
        ./RunMyScript.ps1
    } -AsJob -ThrottleLimit 5
}

$jobs | Receive-Job -Wait

この例では、実行中のジョブを 10 個作成します。 各ジョブでは、5 つのスクリプトが同時に実行されなくなります。 同時に実行されるインスタンスの合計数は 50 に制限されます (10 ジョブは ThrottleLimit の 5 倍)。

パラメーター

-ArgumentList

メソッド呼び出しに対する引数の配列を指定します。 ArgumentListの動作 () の詳細については、about_Splattingを参照してください。

このパラメーターは、Windows PowerShell 3.0 で導入されました。

型:Object[]
Aliases:Args
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-AsJob

並列呼び出しを PowerShell ジョブとして実行します。 実行中のスクリプト ブロックからの出力ではなく、1 つのジョブ オブジェクトが返されます。 ジョブ オブジェクトには、実行する各並列スクリプト ブロックの子ジョブが含まれています。 任意の PowerShell ジョブ コマンドレットでジョブ オブジェクトを使用して、実行中の状態を確認し、データを取得できます。

このパラメーターは PowerShell 7.0 で導入されました。

型:SwitchParameter
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-Begin

このコマンドレットが入力オブジェクトを処理する前に実行されるスクリプト ブロックを指定します。 このスクリプト ブロックは、パイプライン全体に対して 1 回だけ実行されます。 begin ブロックの詳細については、「about_Functions」を参照してください。

型:ScriptBlock
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-Confirm

コマンドレットを実行する前に確認を求めるメッセージが表示されます。

型:SwitchParameter
Aliases:cf
配置:Named
規定値:False
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-End

このコマンドレットがすべての入力オブジェクトを処理した後に実行されるスクリプト ブロックを指定します。 このスクリプト ブロックは、パイプライン全体に対して 1 回だけ実行されます。 end ブロックの詳細については、「about_Functions」を参照してください。

型:ScriptBlock
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-InputObject

入力オブジェクトを指定します。 ForEach-Object は、各入力オブジェクトに対してスクリプト ブロックまたは操作ステートメントを実行します。 オブジェクトを含む変数を入力するか、オブジェクトを取得するコマンドまたは式を入力します。

ForEach-Object パラメーターを使用する場合、コマンドの結果をForEach-Objectにパイプするのではなく、InputObject 値は 1 つのオブジェクトとして扱われます。 これは、値がコマンドの結果であるコレクションである場合でも当てはまります ( -InputObject (Get-Process)など)。 InputObject は、配列またはオブジェクトのコレクションから個々のプロパティを返すことはできません。そのため、定義されたプロパティに特定の値を持つオブジェクトのオブジェクトのコレクションに対して操作を実行するためにForEach-Objectを使用する場合は、このトピックの例に示すように、パイプラインでForEach-Objectを使用することをお勧めします。

型:PSObject
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:True
ワイルドカード文字を受け取る:False

-MemberName

取得するメンバー プロパティの名前または呼び出すメンバー メソッドを指定します。 メンバーは、静的メンバーではなく、インスタンス メンバーである必要があります。

ワイルドカード文字は許可されますが、結果の文字列が一意の値に解決される場合にのみ機能します。 たとえば、 Get-Process | foreach -MemberName *Nameを実行すると、ワイルドカード パターンが複数のメンバーと一致し、コマンドが失敗します。

このパラメーターは、Windows PowerShell 3.0 で導入されました。

型:String
配置:0
規定値:None
必須:True
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:True

-Parallel

入力オブジェクトの並列処理に使用するスクリプト ブロックを指定します。 操作を記述するスクリプト ブロックを入力します。

このパラメーターは PowerShell 7.0 で導入されました。

型:ScriptBlock
配置:Named
規定値:None
必須:True
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-Process

各入力オブジェクトに対して実行される操作を指定します。 このスクリプト ブロックは、パイプライン内のすべてのオブジェクトに対して実行されます。 process ブロックの詳細については、「about_Functions」を参照してください。

Process パラメーターに複数のスクリプト ブロックを指定すると、最初のスクリプト ブロックは常に begin ブロックにマップされます。 スクリプト ブロックが 2 つしかない場合、2 番目のブロックは process ブロックにマップされます。 3 つ以上のスクリプト ブロックがある場合、最初のスクリプト ブロックは常に begin ブロックにマップされ、最後のブロックは end ブロックにマップされ、中央のブロックは process ブロックにマップされます。

型:ScriptBlock[]
配置:0
規定値:None
必須:True
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-RemainingScripts

Process パラメーターによって取得されないすべてのスクリプト ブロックを指定します。

このパラメーターは、Windows PowerShell 3.0 で導入されました。

型:ScriptBlock[]
配置:Named
規定値:None
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-ThrottleLimit

並列で実行されるスクリプト ブロックの数を指定します。 実行中のスクリプト ブロック数が ThrottleLimit を下回るまで、入力オブジェクトはブロックされます。 既定値は 5 です。

ThrottleLimit パラメーターは、 ForEach-Object -Parallelの各インスタンスで実行される並列スクリプトの数を制限します。 AsJob パラメーターを使用するときに作成できるジョブの数は制限されません。 ジョブ自体は同時に実行されるため、複数の並列ジョブを作成し、それぞれが同時スクリプト ブロックのスロットル制限数まで実行できます。

このパラメーターは PowerShell 7.0 で導入されました。

型:Int32
配置:Named
規定値:5
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-TimeoutSeconds

すべての入力が並列に処理されるまで待機する秒数を指定します。 指定したタイムアウト時間が経過すると、実行中のすべてのスクリプトが停止します。 また、処理する残りの入力オブジェクトは無視されます。 既定値の 0 はタイムアウトを無効にし、 ForEach-Object -Parallel は無期限に実行できます。 コマンド ラインで Ctrl+C と入力すると、実行中の ForEach-Object -Parallel コマンドが停止します。 このパラメーターは 、AsJob パラメーターと共に使用することはできません。

このパラメーターは PowerShell 7.0 で導入されました。

型:Int32
配置:Named
規定値:0
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-UseNewRunspace

並列呼び出しでは、実行スペース プールから実行空間を再利用するのではなく、ループイテレーションごとに新しい実行空間を作成します。

このパラメーターは PowerShell 7.1 で導入されました

型:SwitchParameter
配置:Named
規定値:False
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

-WhatIf

コマンドレットを実行した場合の動作を示します。 コマンドレットは実行されません。

型:SwitchParameter
Aliases:wi
配置:Named
規定値:False
必須:False
パイプライン入力を受け取る:False
ワイルドカード文字を受け取る:False

入力

PSObject

任意のオブジェクトをこのコマンドレットにパイプできます。

出力

PSObject

このコマンドレットは、入力によって決定されるオブジェクトを返します。

メモ

PowerShell には、ForEach-Objectの次のエイリアスが含まれています。

  • すべてのプラットフォーム:
    • %
    • foreach

ForEach-Object コマンドレットは、foreach ステートメントに入力をパイプできない点を除き、foreach ステートメントとよく似ています。 foreachステートメントの詳細については、about_Foreachを参照してください。

PowerShell 4.0 以降では、コレクションで使用するために Where メソッドと ForEach メソッドが追加されました。 これらの新しいメソッドの詳細については、 about_Arrays

ForEach-Object -Parallelの使用

  • ForEach-Object -Parallel は、新しい実行空間内の各スクリプト ブロックを実行します。 新しい実行空間では、順次処理で ForEach-Object を実行するよりも大幅に多くのオーバーヘッドが発生します。 並列実行のオーバーヘッドがスクリプト ブロックの実行に比べて小さい場合は、 Parallel を使用することが重要です。 例えば次が挙げられます。

    • マルチコア マシンでのコンピューティング集中型スクリプト
    • 結果の待機またはファイル操作の実行に時間を費やすスクリプト

    Parallel パラメーターを使用すると、スクリプトの実行速度が通常よりもはるかに遅くなる可能性があります。 特に、並列スクリプトが単純な場合。 Parallel を試して、それが有益な場所を見つけます。

  • 並列で実行する場合、 ScriptProperties または ScriptMethods で修飾されたオブジェクトは、スクリプトが最初にアタッチされていたのとは異なる実行空間で実行されている場合、正しく機能することが保証されません。

    Scriptblock 呼び出しは、実際に呼び出された場所に関係なく、常に ホーム ランスペースで実行を試みます。 ただし、 ForEach-Object -Parallel は使用後に削除される一時的な実行空間を作成するため、スクリプトを実行するための実行空間はもうありません。

    この動作は、 ホーム ランスペースがまだ存在する限り機能します。 ただし、スクリプトが呼び出し元の実行空間にのみ存在し、 ホーム ランスペースに存在しない外部変数に依存している場合は、目的の結果が得られない場合があります。

  • 終了しないエラーは、スクリプト ブロックの並列実行で発生するため、コマンドレット エラー ストリームに書き込まれます。 並列スクリプト ブロックの実行順序は非決定論的であるため、エラー ストリームにエラーが表示される順序はランダムです。 同様に、警告、詳細、情報などの他のデータ ストリームに書き込まれたメッセージは、不確定な順序でそれらのデータ ストリームに書き込まれます。

    例外などの終了エラーは、発生するスクリプト ブロックの個々の並列インスタンスを終了します。 1 つのスクリプト ブロックで終了エラーが発生しても、 ForEach-Object コマンドレットが終了しない可能性があります。 他のスクリプトブロックは、並列で実行され、終了エラーが発生しない限り、引き続き実行されます。 終了するエラーは、エラー データ ストリームに、 の FullyQualifiedErrorId を持つ PSTaskException として書き込まれます。 終了エラーは、PowerShell try/catch または trap ブロックを使用して、終了しないエラーに変換できます。

  • PipelineVariable 共通パラメーター変数は、 スコープ修飾子を使用しても、並列シナリオではサポートUsing:

    重要

    ForEach-Object -Parallel パラメーター セットは、個別のプロセス スレッドでスクリプト ブロックを並列に実行します。 Using:修飾子を使用すると、コマンドレット呼び出しスレッドから実行中の各スクリプト ブロック スレッドに変数参照を渡すことができます。 スクリプト ブロックは異なるスレッドで実行されるため、参照によって渡されるオブジェクト変数は安全に使用する必要があります。 一般に、変更されない参照先オブジェクトから読み取るのも安全です。 オブジェクトの状態を変更する必要がある場合は、スレッド セーフなオブジェクト (.NET System.Collection.Concurrent 型など) を使用する必要があります (例 14 を参照)。