PowerShellのスクリプトでよく見かける「ForEach-Object
」。
一見すると「ループ処理?」と思われがちですが、実はこのコマンドレットは、パイプラインと連携する最強の処理ツールなのです。
foreach
構文との違いや、{}
(スクリプトブロック)での使い方、変数の扱い方など、正しく使うことで処理の効率が大きく向上します。
この記事では、PowerShell初心者〜中級者向けに、ForEach-Object
の基本から応用までを、具体例付きでわかりやすく解説していきます。
ForEach-Objectとは?

ForEach-Object
は、PowerShellのパイプラインで1件ずつ処理を実行するためのコマンドレットです。
パイプライン(|
)で前のコマンドから流れてきたオブジェクトを、ひとつずつ取り出して処理します。このコマンドレットにより、大量のデータも効率的に処理することができます。
エイリアス(別名)として、%
も使えます:
# この2つは同じ
Get-Process | ForEach-Object { $_.Name }
Get-Process | % { $_.Name }
基本構文とパイプライン処理の流れ

基本構文:
<オブジェクトのリスト> | ForEach-Object { スクリプトブロック }
例:1〜5を出力して2倍にする
1..5 | ForEach-Object { $_ * 2 }
実行結果:
2
4
6
8
10
処理の流れ
1..5
で、数値1から5の配列が生成される- パイプライン
|
で ForEach-Object に送られる - ForEach-Object は各数値(1,2,3,4,5)を順番に
$_
に格納 { $_ * 2 }
のスクリプトブロックが各要素に対して実行される- 結果が順番に出力される
$_の意味と役割

$_
は、パイプラインで流れてきた”現在のアイテム”を指す特殊変数です。PowerShell 7からは$PSItem
も同じ意味で使えますが、一般的には$_
が広く使われています。
例:
"apple","banana","orange" | ForEach-Object { Write-Host "果物は $_ です" }
出力:
果物は apple です
果物は banana です
果物は orange です
オブジェクトのプロパティやメソッドへのアクセス
$_
を通じて、オブジェクトのプロパティやメソッドにもアクセスできます:
Get-Process | ForEach-Object {
"$($_.Name) は $($_.WorkingSet64 / 1MB) MB のメモリを使用中"
}
ここで$( )
は式を評価し、文字列に埋め込むための構文です。
よくある使い方パターン

ファイル名のリストを表示:
Get-ChildItem *.txt | ForEach-Object { $_.Name }
条件付きで処理:
1..10 | ForEach-Object {
if ($_ % 2 -eq 0) {
"$_ は偶数です"
}
}
出力:
2 は偶数です
4 は偶数です
6 は偶数です
8 は偶数です
10 は偶数です
オブジェクトの変更:
Get-Service | ForEach-Object {
$_.DisplayName = $_.DisplayName.ToUpper()
$_ # 変更したオブジェクトを出力
}
複数のコマンドを実行:
Get-ChildItem *.log | ForEach-Object {
Write-Host "処理中: $($_.Name)" -ForegroundColor Green
$content = Get-Content $_.FullName
"ファイル「$($_.Name)」には $($content.Count) 行あります"
}
Begin / Process / End の3つのブロック
ForEach-Object
は、3つのスクリプトブロックを指定することもできます。
これにより処理の前後でも特別な操作が可能になります。
Get-Process | ForEach-Object -Begin {
"開始"
$total = 0
} -Process {
"プロセス名: $($_.Name)"
$total++
} -End {
"終了 - 合計 $total 個のプロセスがありました"
}
-Begin
:パイプライン処理の前に1回だけ実行される-Process
:オブジェクト1件ごとに実行される(省略時の{ }
はこれと同じ)-End
:すべての処理が終わった後に1回だけ実行される
応用例:合計値の計算
Get-Process | ForEach-Object -Begin {
$totalMem = 0
} -Process {
$totalMem += $_.WorkingSet64
} -End {
"全プロセスの合計メモリ使用量: $($totalMem / 1MB) MB"
}
foreachとの違いは?

PowerShellにはForEach-Object
とは別に、foreach
キーワードも存在します。
この2つは似ていますが、用途が異なります。
# ForEach-Object(パイプラインで使用)
Get-Process | ForEach-Object { $_.Name }
# foreach(スクリプトブロック内でコレクション全体に対して使用)
$processes = Get-Process
foreach ($process in $processes) {
$process.Name
}
主な違い
機能 | ForEach-Object | foreach(キーワード) |
---|---|---|
パイプライン対応 | ◎(得意) | ×(使えない) |
一括処理 | △(1つずつ) | ◎(配列全体を一度に取得) |
変数 | $_ | 自分で指定($process など) |
処理速度 | 大量データで遅い | 一般的に高速 |
メモリ使用 | 少ない(ストリーム処理) | 多い(全データをメモリに保持) |
使い分けポイント
- パイプラインの中で使いたい →
ForEach-Object
- 配列全体に対して繰り返したい →
foreach
- メモリが限られている →
ForEach-Object
- 処理速度重視 →
foreach
応用例:ファイル処理・リモート操作など

複数ファイルを一括リネーム:
Get-ChildItem *.log | ForEach-Object {
$newName = "Archive_" + $_.Name
Rename-Item $_ -NewName $newName
"リネーム: $($_.Name) → $newName"
}
複数サーバーにPing:
"192.168.0.1","8.8.8.8","example.com" | ForEach-Object {
$result = Test-Connection $_ -Count 1 -Quiet
[PSCustomObject]@{
Target = $_
Online = $result
}
}
CSVファイルの処理:
Import-Csv users.csv | ForEach-Object {
# 各ユーザー(行)に対する処理
$_.Department = $_.Department.ToUpper()
if ([int]$_.Age -gt 30) {
$_.IsExperienced = "Yes"
} else {
$_.IsExperienced = "No"
}
$_ # 修正したオブジェクトを出力
} | Export-Csv users_modified.csv -NoTypeInformation
並列処理(PowerShell 7以降):
# -Parallelパラメータを使用した並列処理
Get-ChildItem -Path C:\Logs\*.log | ForEach-Object -Parallel {
# 各ファイルを別々のスレッドで処理
$content = Get-Content $_.FullName
"ファイル $($_.Name) 処理完了: $($content.Count) 行"
} -ThrottleLimit 5 # 同時に実行するスレッド数を5に制限
まとめ
ForEach-Object
は、PowerShellらしい「パイプライン的思考」での反復処理に非常に役立つコマンドレットです。
ポイントまとめ:
$_
は現在のオブジェクトを指す特殊変数-Begin
,-Process
,-End
の3段階で制御可能foreach
キーワードとは用途や特性が異なる- ファイル処理・ネットワーク操作など実践的な場面で活躍
- PowerShell 7では並列処理もサポート
ベストプラクティス:
- 複雑なスクリプトブロックは見やすく整形する
- 大量のオブジェクトを処理する場合はメモリ消費に注意
- 必要に応じて
ForEach-Object
とforeach
を使い分ける - 処理の進捗状況を表示すると長時間の処理も安心
最初は難しそうに見えても、使い慣れると柔軟で強力なスクリプトが書けるようになります。
日常業務や自動化スクリプトに、ぜひ活用してみてください!
PowerShellでの効率的なデータ処理の鍵は、このパイプラインとForEach-Objectの組み合わせにあります。
基本を押さえて、ぜひあなたのスクリプトをパワーアップしましょう!
コメント