tech.guitarrapc.cóm

Technical updates

PowerShellのコマンドレット例外を取得する

前日、牟田口先生とやり取りをしててそういえばということで記事にしておきます。

PowerShell 2.0からtry{}catch{}finally{}ステートメントがサポートされていますが、単純にコマンドレットで利用しようとしてもCatch節で例外を捉えられません。これはtrap{}ステートメントでも同様です。

どのようにしたら例外として捉えるかみてみましょう。

サンプル

例えば、存在しないZドライブをlsしてみます。

try
{
  Get-ChildItem z:\
}
catch
{
  "ほげほげ例外"
}

ほげほげ例外と出てほしかったのに、例外が出ます。

Get-ChildItem : Cannot find drive. A drive with the name 'z' does not exist.
At line:4 char:5
+     Get-ChildItem z:\
+     ~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound: (z:String) [Get-ChildItem], DriveNotFoundException
  + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

対処例

コマンドレットの例外を捉えるには、対象のコマンドレットの-ErrorActionパラメータにStopを指定します。 ErrorActionパラメーターを使うと、コマンドレットがエラーを起こした時の挙動を決められます。

try
{
  Get-ChildItem z:\ -ErrorAction Stop
}
catch
{
  "ほげほげ例外"
}

期待通り例外を捉えることができました。

ほげほげ例外

デフォルトの挙動を変更する

デフォルト挙動は$ErrorActionPreference変数で定義されています。 デフォルト値Continueだと例外をキャッチできず、処理をそのまま続行してしまいます。

挙動を変更するには、Stopなど希望する挙動を代入します。

$ErrorActionPreference = "Stop"

PowerShell 3.0における挙動を抜粋します。

PS> Get-Help about_Commonparameters

# 省略
-ErrorAction[:{SilentlyContinue | Continue | Inquire | Stop)]
    Alias: ea

    Determines how the cmdlet responds to a non-terminating error
    from the command. This parameter works only when the command generates
    a non-terminating error, such as those from the Write-Error cmdlet.

    The ErrorAction parameter overrides the value of the
    $ErrorActionPreference variable for the current command.
    Because the default value of the $ErrorActionPreference variable
    is Continue, error messages are displayed and execution continues
    unless you use the ErrorAction parameter.

    The ErrorAction parameter has no effect on terminating errors (such as
    missing data, parameters that are not valid, or insufficient
    permissions) that prevent a command from completing successfully.

    Valid values:

      Stop. Displays the error message and stops executing the
      command.

      Inquire. Displays the error message and prompts you for
      confirmation before continuing execution. This value is rarely
      used.

      Continue. Displays the error message and continues executing
      the command. "Continue" is the default value.

      SilentlyContinue. Suppresses the error message and continues
      executing the command.

      Ignore.  Suppresses the error message and continues
      executing the command. Unlike SilentlyContinue, Ignore
      does not add the error message to the $Error automatic
      variable.

    NOTE: The Ignore value was introduced in Windows PowerShell 3.0.

まとめ

コマンドレットの例外は-ErrorActionを利用しましょう。

参考

PowerShellの例外処理について