Windows PowerShellのFunction入門 (Begin、Process、Endブロック編)
この記事はWindows PowerShellのBegin
、Process
、End
ブロック、そしてFunction
/Filter
/ScriptBlock
スクリプトファイルの違いに関する基本的な話です
PowerShellの処理はBegin
、Process
、End
の3つのブロックに分かれています
# Sample1.ps1の内容 Begin{ Write-Host 'Begin'; } Process{ Write-Host 'Process'; } End{ Write-Host 'End'; }
PS> ./Sample.ps1; Begin Process End
パイプラインから値を渡されたとき、Begin
は最初の1回目のProcess
が動く前に、Process
は値を渡される毎に、End
は最後のProcess
が動いた後に実行されます
なお、パイプラインで値を渡す意図がある場合でもForEach-Object
の中で呼ぶとForEach-Object
の中で個別に実行されてしまうので、注意してください
Function SampleFunction1{ Begin{ Write-Host 'Begin'; } Process{ Write-Host 'Process'; } End{ Write-Host 'End'; } } PS> 1..3 | SampleFunction1 Begin Process Process Process End PS> 1..3 | Foreach-Object{SampleFunction1} Begin Process End Begin Process End Begin Process End
Begin
、Process
、End
ブロックの記述はそれぞれ省略することができます
何も書かれていない場合、Filter
とスクリプトファイルはProcess
ブロックとして、Function
とScriptBlock
はEnd
ブロックとして処理が動きます
# Sample2.ps1の内容 Write-Host 'Sample2.sp1';
PS> 1..3 | ./Sample2.ps1 Sample2.sp1 Sample2.sp1 Sample2.sp1
Function SampleFunction2{ Write-Host 'SampleFunction2'; } [ScriptBlock] $ScriptBlock1 = {Write-Host 'ScriptBlock1'}; Filter SampleFilter{ Write-Host 'SampleFilter'; } PS> 1..3 | SampleFunction2 SampleFunction2 PS> 1..3 | &($ScriptBlock1) ScriptBlock1 PS> 1..3 | SampleFilter SampleFilter SampleFilter SampleFilter
また、Begin
、Process
、End
ブロックを明記することにより、書かなかったブロックが存在しないFunction
/Filter
/ScriptBlock
/スクリプトファイルを作ることもできます
# Endブロックが存在しないFunction Function SampleFunction3{ Begin{ Write-Host 'Begin'; } Process{ Write-Host 'Process'; } }
Begin
、Process
、End
ブロックの何れかを記述した場合、デフォルトで省略されていたブロック (Function
ならEnd
ブロック) も明記する必要が生じます
Function SampleFunction4{ Process{ Write-Host 'Process'; } # Endブロック内の処理にはならず、Function作成時にエラーになる Write-Host 'End'; }
なお、Begin
、Process
、End
ブロックをすべて明記した場合、Function
/Filter
に違いはなくなるようです……が私はよくわかっていません
Function
とFilter
はGet-Item
で情報を取得すれば、CommandType
がFilter
かFunction
かで違いが出ますが、処理に違いはないようです
解説記事なのに最後の所がぼやけていて申し訳ありませんが、私は基本的にはFunctionを用い、パイプラインによる処理の連鎖の中で特定のForEach-Objectが大きくなったり繰り返し同じ記述をすることになった場合Filterで処理を外に出すという使い分けをしています