Engineering Note

プログラミングなどの技術的なメモ

PowerShellスクリプトでバックグラウンド処理を実行する

PowerShellでは、バックグラウンドジョブと呼ばれるものを実行することで並列処理をすることができます。

今回はこちらの使い方について簡単にメモします。

 

 

Start-Jobとは

PowerShellではStart-Jobコマンドで、バックグラウンドジョブを開始することができます。

なお、バックグラウンドジョブとは別プロセスを実行することになります。

また、PowerShell 6.0 以降では、シェルコマンドのようにバックグラウンド演算子(アンパサンド("&"))を使用してジョブを開始できます。

 

docs.microsoft.com

 

Start-Jobを実行する

Start-Jobコマンドの後のScriptBlockパラメータとして実行するコマンドを渡してあげます。

for ( $i=0; $i -lt 5; $i++ ) {
    Start-Job -ScriptBlock { sleep 3; "done!" }
}

Get-Job -State Running | Wait-Job | Receive-Job

 

Id     Name            PSJobTypeName   State         HasMoreData     Lo
                                                                     ca
                                                                     ti
                                                                     on
--     ----            -------------   -----         -----------     --
1      Job1            BackgroundJob   Running       True            lo
3      Job3            BackgroundJob   Running       True            lo
5      Job5            BackgroundJob   Running       True            lo
7      Job7            BackgroundJob   Running       True            lo
9      Job9            BackgroundJob   Running       True            lo
done!
done!
done!
done!
done!

 

ScriptBlock内で変数を展開する

上記のようにScriptBlockパラメータに変数を渡した場合、以下のようにその展開がうまくいきません。

for ( $i=0; $i -lt 5; $i++ ) {
    # 変数$iの展開がうまくできない
    # Start-Job { sleep 3; "test_$i has done!" }
}

Get-Job -State Running | Wait-Job | Receive-Job

 

# 実行結果
Id     Name            PSJobTypeName   State         HasMoreData     Lo
                                                                     ca
                                                                     ti
                                                                     on
--     ----            -------------   -----         -----------     --
11     Job11           BackgroundJob   Running       True            lo
13     Job13           BackgroundJob   Running       True            lo
15     Job15           BackgroundJob   Running       True            lo
17     Job17           BackgroundJob   Running       True            lo
19     Job19           BackgroundJob   Running       True            lo
test_ has done!
test_ has done!
test_ has done!
test_ has done!
test_ has done!

 

上記のような場合、ScriptBlock変数を作成し、そちらをパラメータとして渡すことでうまく展開することができます。

for ( $i=0; $i -lt 5; $i++ ) {
    $cmd = "sleep 3; echo 'test_$i has done!'"
    $sb = [scriptblock]::Create($cmd)
    Start-Job -ScriptBlock $sb
}

Get-Job -State Running | Wait-Job | Receive-Job

 

# 実行結果
Id     Name            PSJobTypeName   State         HasMoreData     Lo
                                                                     ca
                                                                     ti
                                                                     on
--     ----            -------------   -----         -----------     --
21     Job21           BackgroundJob   Running       True            lo
23     Job23           BackgroundJob   Running       True            lo
25     Job25           BackgroundJob   Running       True            lo
27     Job27           BackgroundJob   Running       True            lo
29     Job29           BackgroundJob   Running       True            lo
test_0 has done!
test_1 has done!
test_2 has done!
test_3 has done!
test_4 has done!

 

Start-Jobの詳しい使い方については以下のドキュメントが参考になります。

PowerShell自体はあまり使う機会がないですが、Linuxのシェルコマンドのように覚えるといろいろなことができるので、必要に応じて学んでいきたいです。