HOWTO · PowerShell

PowerShell で Try-Catch ブロックを使用してエラーを処理する方法

この記事では、PowerShell のエラー アクション設定と、PowerShell の Try Catch ブロックと Finally ブロックを使用してそれらをインターセプトしてエラー処理を実行する方法について説明します。

このページの内容

PowerShell では、try と catch が終了エラーを処理します。多くのコマンドレットはエラーを非終了エラーとして報告するため、操作の失敗が catch ブロックに到達すべき場合は -ErrorAction Stop を追加してください。$ErrorActionPreference はそのスコープにおける非終了エラーの既定の処理を設定し、-ErrorAction は 1 つのコマンドに対する動作を設定します。

PowerShell の $ErrorActionPreference 変数

$ErrorActionPreference は、そのスコープで PowerShell が非終了エラーにどのように応答するかを制御します。その既定値は Continue です。PowerShell はエラーを報告し、次のステートメントへ進みます。これを Stop に設定すると、非終了エラーは終了エラーに昇格します。そのため、現在のフローを中断し、周囲の catch で処理できます。catch がエラーを処理した後は、実行は周囲の制御フローに従います。エラーがスクリプト全体を自動的に終了させるわけではありません。

スクリプトの一部だけにこの動作が必要な場合は、スコープを限定した変更を使用してください。古い値を保存し、後続のコマンドで以前の設定を使用すべき場合は finally ブロックで復元してください。この設定は、PowerShell のエラー アクション設定を尊重するコマンドに適用されます。あらゆる種類の失敗に対する明示的な処理に代わるものではありません。

PowerShell の ErrorAction 共通パラメーター

-ErrorAction は、多くのコマンドレットと関数でサポートされる共通パラメーターです。その値はそのコマンドに適用され、その呼び出しについては $ErrorActionPreference より優先されます。たとえば、Get-Content $path -ErrorAction Stop は、非終了の読み取りエラーをそのコマンドについては終了エラーにします。その後、周囲の catch がそれを処理できます。このパラメーターはコマンドのエラーの処理方法を変更します。回復ロジックは周囲のスクリプトに属します。

値には Continue と Stop が含まれ、サポートされる場合は SilentlyContinue、Ignore、Inquire、Suspend などのアクションも含まれます。より広いスコープを変更するのではなく、失敗をキャッチすべき操作に対して -ErrorAction Stop を優先してください。コマンドは、この設定とは無関係に終了エラーを生成することもあります。

PowerShell try-catch ブロックを使用する

失敗する可能性のあるステートメントは try の中に配置してください。終了エラーは制御を一致する catch に移します。型なしの catch はあらゆる終了エラーを処理し、catch [System.IO.IOException] のような型付きの形式はその型のエラーを処理します。特定の catch は一般的な catch より前に配置してください。$Error は PowerShell の自動エラー履歴コレクションであり、現在の失敗のみを表す変数ではありません。catch ブロック内では、$_($PSItem としても利用可能)が現在のエラー レコードを表します。その Exception プロパティまたは FullyQualifiedErrorId プロパティは診断に役立ちます。

finally ブロックは省略可能で、try ステートメントから制御が離れるときに実行されます。通常どおり完了した場合でも、エラーが処理された場合でも同様です。操作の前に開いたリソースの破棄など、クリーンアップに使用してください。catch ブロックはエラーを回復、ログ記録、または再スローできます。それをキャッチすること自体は、周囲のスクリプトが残りの作業を続けるべきかどうかを決めるものではありません。

次の実行可能な例は成功パスに従い、クリーンアップ行の前にステータス行を出力します。このコードには外部ファイルへの依存はありません。

try {
    $reportName = "daily-report.txt"
    Write-Output "Prepared $reportName"
}
finally {
    Write-Output "Finished report step"
}
Prepared daily-report.txt
Finished report step

非終了エラーをキャッチすべきコマンドレットについては、try の中でそのコマンドレットに -ErrorAction Stop を追加してください。本番スクリプトではパスやその他の入力を明示的に保ち、そのうえで操作に基づいてログ記録、再試行、回復、再スローのいずれかを選択してください。このサンプルは成功パスを示しています。失敗を処理する必要があるコマンドの周囲に、同じ制御フロー構造を適用してください。