PowerShellでの例外処理の方法 try-catch文とErrorAction

こんにちは。
けいぞうです。

今回は「PowerShellでの例外処理の方法 try-catch文とErrorAction」についての記事です。

PowerShellでのtry-catch構文

PowerShellでは他のプログラミング言語と同様にtry-catch文で例外のハンドリングを行うことが可能です。

以下、PowerShellのtry-catchの構文です

try
{
    #処理内容
}
catch
{
    #例外エラー発生時の処理内容
}
finally
{
    #例外の有無に関わらず実行する内容
}

基本的に他の言語と同じですね。

以下、何らかのメール送信処理を例外ハンドリングしたい場合の例文です。

#メール送信処理
try
{
    Send-MailMessage -To "mailto@example.com" -From "mailfrom@example.com" -SmtpServer "smtpserver" -Subject "件名" -Body "本文" -Encoding UTF8 -ErrorAction Stop
}
catch
{
    Write-output $error
}
finally
{
    Write-output "メール送信処理終了"
}

詳しくは後述しますが、tryの中で例外エラーを検知したいコマンドレットに「-ErrorAction Stop」を付与することで、例外エラーの際にcatchすることができます。

また、エラーの内容は$errorに格納されます。

これは直前のエラー内容が格納されている自動変数よ呼ばれるものです。

自動変数については以下の記事で、他の自動変数にも触れています。

エラーハンドリングの種類について

コマンドレットに「-ErrorAction Stop」を付与するとcatchできると書きましたが、このErrorActionの引数には「Stop」以外の値を指定することも可能です。

以下にErrorActionに指定できる引数をまとめました。

指定できる値説明
Continue エラーを出力して、後続処理を進める
catchの中には入らない
SilentlyContinue エラーを出力せず、後続処理を進める
自動変数$errorにエラー内容が追加される
Stop 処理が中断してCatchの中に入る
Ignoreエラーを無視する
自動変数$errorにエラー内容が追加されない
Inquireエラー後の動作をダイアログで選択させる
SuspendPowerShellワークフロー内でコマンドがエラーになった場合に中断する

suspendについては、ワークフローのみで使用できる値になります。

詳細は、以下を参照。

https://docs.microsoft.com/ja-jp/system-center/sma/overview-powershell-workflows?view=sc-sma-2019

ErrorActionPreference を使う方法

ErrorAction引数を指定しなくてもよい記述方法が、この「ErrorActionPreference」を使う方法です。

基本エラー時の動作のdefaultは「Continue」と同じ動きになるのですが、このErrorActionPreferenceをスクリプトの先頭で指定することによって、デフォルトの挙動を変更することができます。

$ErrorActionPreference = "Stop"

エラー内容の取得方法について

前述したように、PowerShellのエラーについては「$error」という変数に自動的に内容が格納されます。

$errorはArrayListになっており、最後に起こったエラーが一番先頭に格納されます。

直前のエラー内容は0番目、その前のエラー内容は1番目に格納されている、といった具合になります。

> $error[0]
Send-MailMessage : リモート名を解決できませんでした。: 'smtpserver'
発生場所 行:3 文字:5
+     Send-MailMessage -To "mailto@example.com" -From "mailfrom@example ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage]、SmtpException
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage



> $error[1]
Get-Error : 用語 'Get-Error' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ Get-Error
+ ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-Error:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException