tech.guitarrapc.cóm

Technical updates

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

前日、牟田口先生とやり取りをしててそういえばということで記事にしておきます。 PowerShell v2.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を指定します。
try
{
	Get-ChildItem z:\ -ErrorAction Stop
}
catch
{
	"ほげほげ例外"
}
これで、例外が取得できます。
ほげほげ例外
このErrorActionパラメータにより、コマンドレットがエラーを起こした時の挙動を決められます。

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

デフォルト挙動は、 $ErrorActionPreference で定義されています。 通常デフォルトでのErrorActionはContinue のため、エラーをキャッチできず、処理をそのまま続行してしまうという事です。 これを変更する場合は、Stopなど希望する挙動を代入します。
$ErrorActionPreference = "Stop"
PowerShell V3.0 における挙動には以下のモノがあります。
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.

まとめ

.NET の例外は、try{}catch{} で取得できるんですけどね。 コマンドレットの例外は、-ErrorActionを利用しましょうでした。

参考

PowerShellの例外処理について