PowerShellでのエラー/例外処理についてにもうすこし突っ込んだことを書いたよ。(2018/11/30)
PowerShellでtry~catch
をしようとしても、うまくいかない、という事がある。
Cmdletが実行されたときに発生した問題(あえて例外とは書かないよ)は、コンソールに赤字で表示される(標準エラーではなさそう…)が、Cmdletを実行してるコンテキスト(例えば実装中のスクリプトとか)では例外としては扱われない1。
例外をキャッチする
そんな時、-ErrorAction Stop
をつけるか、$ErrorActionPreference="Stop"
としておくと、Cmdletは例外を投げてくれる。
試す。
まず、以下だと例外投げてくれないので、赤文字が出る。
PS C:\Users\bounoki> try {
Get-LocalUser nosuchuser
} catch [Exception] {
}
Get-LocalUser : ユーザー nosuchuser が見つかりませんでした。
発生場所 行:2 文字:5
+ Get-LocalUser nosuchuser
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (nosuchuser:String) [Get-LocalUser], UserNotFoundException
+ FullyQualifiedErrorId : UserNotFound,Microsoft.PowerShell.Commands.GetLocalUserCommand
PS C:\Users\bounoki>
以下だと例外投げてくれるので赤文字が出ない。
PS C:\Users\bounoki> try {
Get-LocalUser nosuchuser -ErrorAction Stop
} catch [Exception] {
}
PS C:\Users\bounoki>
PS C:\Users\bounoki> $ErrorActionPreference = "Stop"
try {
Get-LocalUser nosuchuser
} catch [Exception] {
}
PS C:\Users\bounoki>
例外の種類を気にしながらキャッチする
上のやり方だとException
で捕まえられるけど、もっと具体的な例外でキャッチするにはどうしたらよいか。
赤文字の内容見て「UserNotFoundException
を捕まえよう」と考えて直そうとすると、うまくいかない。
これ、PowerShellのErrorAction
をStop
にしてスクリプトを止めようとすると、System.Management.Automation.ActionPreferenceStopException
がスローされるという仕様らしい。
PS C:\Users\bounoki> try {
Get-LocalUser nosuchuser -ErrorAction Stop
} catch [System.Management.Automation.ActionPreferenceStopException] {
}
PS C:\Users\bounoki>
例外を特定して処理したい場合は、ActionPreferenceStopException
を投げたきっかけの例外をif文で判断すればいいらしい、とTechNetのフォーラムで見つけた。
PS C:\Users\bounoki> try {
Get-LocalUser nosuchuser -ErrorAction Stop
} catch [System.Management.Automation.ActionPreferenceStopException] {
if( $_.Exception -is [Microsoft.PowerShell.Commands.UserNotFoundException]) {
Write-Host "ユーザーがみつからないよ"
}
}
ユーザーがみつからないよ
PS C:\Users\bounoki>
でも、これだとException
でcatchしたのとあまり変わらないじゃん!
結局、catch句で条件分岐しなきゃいけないのかな。
だったら、例外吐きそうなのがCmdletくらいの場合Exception
で取っても同じかなあ。
自分で例外をthrowするようなスクリプトを作ったときには役に立ちそう。
-
たぶん内部的に発生した.NET側の例外などは、Cmdlet内でcatchするような実装になってるのではなかろうか。→ PowerShellでのエラー/例外処理についてにもうすこし突っ込んだことを書いたよ。(2018/11/30) ↩