PowerShellには例外を発生させるthrowキーワードおよびそれを捕捉するためのtry~catchブロックが存在します。
例としてはこのようになります。
try {
Write-Host 'throw前の処理'
throw 'エラーが発生!!'
# 例外が発生しているのでここには到達しない
Write-Host 'ここには到達しない'
} catch {
# $_という変数にエラー情報が入っている。
Write-Host $_
}
# catch後の処理なのでここには到達する。
Write-Host 'catch後の処理'
結果はこのようになります。
throw前の処理
エラーが発生!!
catch後の処理
このような機構が存在しますので、以下のコードを動かすと一見、エラーをキャッチできそうに見えますが、
try {
Write-Host 'Remove-Item前'
# 存在しないファイルを削除する。
Remove-Item -Path 'C:\temp\存在しないファイル.txt' -Force
# 例外が発生するのでここには到達しない?
Write-Host 'Remove-Item後'
}
catch {
Write-Host $_
}
動かしてみると以下の結果になります。
Remove-Item前
Remove-Item : パス 'C:\temp\存在しないファイル.txt' が存在しないため検出できません。
発生場所 C:\temp\test.ps1:5 文字:2
+ Remove-Item -Path 'C:\temp\存在しないファイル.txt' -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\temp\存在しないファイル.txt:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item後
【Remove-Item後】というメッセージが出力されていることにご注目ください。
そう、PowerShellにはこのようにエラーが起きても処理を継続するコマンドレットがあります。
このような場合でもエラーを捕捉してエラーハンドリングを行う場合はどうすればよいでしょうか?
いくつか方法がありますが、今回は$ErrorActionPreference変数を使う方法をご紹介いたします。
$ErrorActionPreference変数に特定の値をセットすることで終了しないエラーに応答する方法を変更することができます。
今回はこの変数に'Stop'という値をセットします。
早速、先ほどのコードの先頭行にセットしてみます。
$ErrorActionPreference = 'Stop'
try {
Write-Host 'Remove-Item前'
# 存在しないファイルを削除する。
Remove-Item -Path 'C:\temp\存在しないファイル.txt' -Force
# 例外が発生するのでここには到達しない?
Write-Host 'Remove-Item後'
}
catch {
Write-Host $_
}
上記コードを実行すると結果は以下のようになります。
Remove-Item前
パス 'C:\temp\存在しないファイル.txt' が存在しないため検出できません。
エラーを捕捉できるようになりました。