PowerShellのWait-Jobでジョブの完了を待つ方法をわかりやすく解説

PowerShellでは、バックグラウンドで実行されるジョブ(非同期処理)を管理できる便利な機能があります。その中でも「Wait-Job」コマンドは、ジョブの完了を待機するために使用される重要なコマンドです。複数の処理を並行して行いたいときや、ある処理が完了してから次の処理に移りたいときに活躍します。この記事では、Wait-Jobの基本的な使い方から実践的な使用例まで、初心者にもわかりやすく解説していきます。

Wait-Jobとは?

PowerShellでコマンドを非同期的に実行したい場合、「Start-Job」などを使ってバックグラウンドジョブとして実行することができます。しかし、処理の終了を確認せずに次の命令を実行してしまうと、意図しない動作になることがあります。

そこで登場するのが「Wait-Job」です。
Wait-Jobコマンドレットは、1つまたは複数のジョブが完了するまでスクリプトの実行を一時停止させます。これにより、ジョブの終了を待ってから次の処理に移ることが可能になります。


基本的な構文

Wait-Job -Job <Jobオブジェクト>

または、ジョブIDやジョブ名を指定することも可能です。

Wait-Job -Id 1
Wait-Job -Name "MyJob"

このコマンドは、対象のジョブが完了するまで処理をブロックし、完了後に制御を返します。


Wait-Jobの基本的な使い方

以下は、簡単なバックグラウンドジョブの例です。

$job = Start-Job -ScriptBlock {
Start-Sleep -Seconds 5
"ジョブ完了"
}

Wait-Job -Job $job

Receive-Job -Job $job

このスクリプトでは、5秒間スリープするジョブをバックグラウンドで実行しています。Wait-Jobによってジョブが終わるのを待ち、Receive-Jobでその出力を受け取っています。


複数ジョブをWait-Jobで待機する

Wait-Jobは、複数のジョブにも対応しています。たとえば、次のように複数のバックグラウンドジョブを実行し、それらすべてが完了するのを待つことができます。

$jobs = @()
$jobs += Start-Job -ScriptBlock { Start-Sleep -Seconds 3; "ジョブ1完了" }
$jobs += Start-Job -ScriptBlock { Start-Sleep -Seconds 5; "ジョブ2完了" }

Wait-Job -Job $jobs

foreach ($job in $jobs) {
Receive-Job -Job $job
}

このように、複数のジョブを配列で管理しておけば、Wait-Jobで一括して完了を待つことができます。


タイムアウト付きで待機する

Wait-Jobにはタイムアウト機能もあります。指定した秒数の間だけ待機し、ジョブが終わらなければ制御を戻すことができます。

Wait-Job -Job $job -Timeout 3

この例では、3秒間だけジョブの完了を待ちます。ジョブがそれまでに終わらなければ、制御が戻ります。

タイムアウトが発生したかどうかを確認するには、$job.Stateを確認するとよいでしょう。

if ($job.State -ne 'Completed') {
Write-Output "ジョブはまだ完了していません。"
}

ジョブの状態確認と活用方法

ジョブの状態を確認したい場合、Get-Jobを使って現在の状態を確認することができます。

Get-Job

ジョブの状態には以下のようなものがあります:

  • Running:実行中
  • Completed:完了
  • Failed:エラーで失敗
  • Stopped:手動で停止

ジョブの状態を見ながら処理を分岐させることで、より柔軟なスクリプトが作成できます。


Wait-Job使用時の注意点

  • 必ずReceive-Jobで結果を取得すること:ジョブが終了しても、出力を受け取らないとメモリを消費し続けるため、Receive-Jobを使って結果を受け取りましょう。
  • 不要なジョブはRemove-Jobで削除する:ジョブを使い終わったら、メモリ解放のために削除するのが望ましいです。
Remove-Job -Job $job

実用的なシナリオ例:ファイルの一括処理

以下は、複数ファイルを並列処理し、すべての処理が完了するまで待機するスクリプト例です。

$files = Get-ChildItem -Path "C:\Logs" -Filter *.log
$jobs = @()

foreach ($file in $files) {
$jobs += Start-Job -ScriptBlock {
param($path)
# ファイル処理の代わりにSleepで模擬
Start-Sleep -Seconds 2
"Processed: $path"
} -ArgumentList $file.FullName
}

Wait-Job -Job $jobs

foreach ($job in $jobs) {
$output = Receive-Job -Job $job
Write-Output $output
Remove-Job -Job $job
}

このように、Wait-Jobは複数のファイルを並列処理して効率的に結果を得たいときに非常に有効です。


まとめ

Wait-Jobは、PowerShellで非同期処理を扱う際に非常に便利なコマンドです。特に、処理の完了を待ってから次に進みたい場合や、複数のジョブをまとめて管理したい場合には欠かせません。タイムアウトや状態確認と組み合わせることで、より堅牢なスクリプトを作成することができます。

バックグラウンドジョブを活用することで、PowerShellスクリプトのパフォーマンスや柔軟性を向上させることができます。ぜひ、Wait-Jobを使いこなして、効率的な自動化を実現してください。

タイトルとURLをコピーしました