次の方法で共有


about_Try_Catch_Finally

簡単な説明

trycatch、およびfinally ブロックを使用して終了エラーを処理する方法について説明します。

詳細な説明

trycatch、およびfinally ブロックを使用して、スクリプト内の終了エラーに応答または処理します。 Trap ステートメントを使用して、スクリプト内の終了エラーを処理することもできます。 詳細については、 about_Trapを参照してください。

終了エラーは、ステートメントの実行を停止します。 PowerShell で何らかの方法で終了エラーが処理されない場合、PowerShell は現在のパイプラインを使用して関数またはスクリプトの実行も停止します。 C# などの他の言語では、終了エラーは例外と呼ばれます。

try ブロックを使用して、PowerShell でエラーを監視するスクリプトのセクションを定義します。 try ブロック内でエラーが発生すると、エラーは最初に$Error自動変数に保存されます。 PowerShell は、エラーを処理するために catch ブロックを検索します。 try ステートメントに一致するcatch ブロックがない場合、PowerShell は引き続き親スコープで適切なcatch ブロックまたはTrap ステートメントを検索します。 catch ブロックが完了した後、または適切なcatch ブロックまたはTrap ステートメントが見つからない場合は、finally ブロックが実行されます。 エラーを処理できない場合、エラーはエラー ストリームに書き込まれます。

catch ブロックには、エラーを追跡したり、スクリプトの予想されるフローを回復したりするためのコマンドを含めることができます。 catch ブロックでは、キャッチするエラーの種類を指定できます。 try ステートメントには、さまざまな種類のエラーに対して複数のcatch ブロックを含めることができます。

finally ブロックを使用すると、スクリプトで不要になったリソースを解放できます。

trycatch、および finally は、C# プログラミング言語で使用される trycatch、および finally キーワードに似ています。

構文

try ステートメントには、try ブロック、0 個以上のcatch ブロック、0 個または 1 個のfinally ブロックが含まれます。 try ステートメントには、少なくとも 1 つのcatch ブロックまたは 1 つのfinally ブロックが必要です。

try ブロックの構文を次に示します。

try {<statement list>}

try キーワードの後に、中かっこで囲まれるステートメント リストが続きます。 ステートメント リスト内のステートメントの実行中に終了エラーが発生した場合、スクリプトはエラー オブジェクトを try ブロックから適切な catch ブロックに渡します。

catch ブロックの構文を次に示します。

catch [[<error type>][',' <error type>]*] {<statement list>}

エラーの種類は角かっこで囲まれています。 最も外側の角かっこは、要素が省略可能であることを示します。

catchキーワードの後に、エラー・タイプ指定のオプション・リストとステートメント・リストが続きます。 try ブロックで終了エラーが発生した場合、PowerShell は適切なcatch ブロックを検索します。 見つかった場合は、 catch ブロック内のステートメントが実行されます。

catch ブロックでは、1 つ以上のエラーの種類を指定できます。 エラーの種類は、Microsoft .NET Framework 例外または .NET Framework 例外から派生した例外です。 catch ブロックは、指定した .NET Framework 例外クラスまたは指定したクラスから派生したクラスのエラーを処理します。

catch ブロックでエラーの種類が指定されている場合、そのcatchブロックはその種類のエラーを処理します。 catch ブロックでエラーの種類が指定されていない場合、そのcatchブロックは、try ブロックで発生したエラーを処理します。 tryステートメントには、指定したエラーの種類ごとに複数のcatch ブロックを含めることができます。

finally ブロックの構文を次に示します。

finally {<statement list>}

finally キーワードの後には、try ステートメントがエラーなしで実行された場合や、catch ステートメントでエラーがキャッチされた場合でも、スクリプトが実行されるたびに実行されるステートメント リストが続きます。

CTRL+C を押すとパイプラインが停止されることに注意してください。 パイプラインに送信されたオブジェクトは出力として表示されません。 したがって、"Finally block has run" などの表示するステートメントを含める場合、finally ブロックが実行された場合でも、CTRL+C を押した後は表示されません。

エラーのキャッチ

次のサンプル スクリプトは、catch ブロックを持つtry ブロックを示しています。

try { NonsenseString }
catch { "An error occurred." }

catch キーワードは、try ブロックまたは別のcatch ブロックのすぐ後に続く必要があります。

PowerShell では、コマンドレットまたはその他の項目として "NonsenseString" が認識されません。 このスクリプトを実行すると、次の結果が返されます。

An error occurred.

スクリプトで "NonsenseString" が検出されると、終了エラーが発生します。 catch ブロックは、ブロック内でステートメント リストを実行してエラーを処理します。

複数の catch ステートメントの使用

try ステートメントには、任意の数のcatch ブロックを含めることができます。 たとえば、次のスクリプトには、MyDoc.docをダウンロードするtry ブロックがあり、2 つのcatch ブロックが含まれています。

try {
   $wc = new-object System.Net.WebClient
   $wc.DownloadFile("http://www.contoso.com/MyDoc.doc","c:\temp\MyDoc.doc")
}
catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from http://www.contoso.com."
}
catch {
    "An error occurred that could not be resolved."
}

最初の catch ブロックは、 System.Net.WebException および System.IO.IOException 型のエラーを処理します。 2 番目の catch ブロックでは、エラーの種類が指定されていません。 2 番目の catch ブロックは、発生した他の終了エラーを処理します。

PowerShell は、継承によってエラーの種類と一致します。 catch ブロックは、指定した .NET Framework 例外クラスまたは指定したクラスから派生したクラスのエラーを処理します。 次の例には、"Command Not Found" エラーをキャッチする catch ブロックが含まれています。

catch [System.Management.Automation.CommandNotFoundException]
{"Inherited Exception" }

指定したエラーの種類 CommandNotFoundException は、 System.SystemException 型から継承します。 次の例では、コマンドが見つからないエラーもキャッチします。

catch [System.SystemException] {"Base Exception" }

この catch ブロックは、"Command Not Found" エラーと、 SystemException 型を継承するその他のエラーを処理します。

エラー クラスとその派生クラスの 1 つを指定する場合は、派生クラスの catch ブロックを一般クラスの catch ブロックの前に配置します。

Note

PowerShell では、すべての例外が RuntimeException 型でラップされます。 したがって、エラーの種類 System.Management.Automation.RuntimeException を指定すると、修飾されていない catch ブロックと同じように動作します。

Try Catch でのトラップの使用

try ブロック内で定義されたTrapを持つtry ブロックで終了エラーが発生した場合、一致するcatch ブロックがある場合でも、Trap ステートメントが制御を受け取ります。

Traptryより高いブロックに存在し、現在のスコープ内に一致するcatch ブロックがない場合、親スコープに一致するcatch ブロックがある場合でも、Trapは制御を受け取ります。

例外情報へのアクセス

catch ブロック内では、$_ ($PSItemとも呼ばれます) を使用して現在のエラーにアクセスできます。 オブジェクトの型は ErrorRecord です。

try { NonsenseString }
catch {
  Write-Host "An error occurred:"
  Write-Host $_
}

このスクリプトを実行すると、次の結果が返されます。

An Error occurred:
The term 'NonsenseString' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.

ScriptStackTraceExceptionErrorDetails など、アクセスできる追加のプロパティがあります。 たとえば、スクリプトを次のように変更するとします。

try { NonsenseString }
catch {
  Write-Host "An error occurred:"
  Write-Host $_.ScriptStackTrace
}

結果は次のようになります。

An Error occurred:
at <ScriptBlock>, <No file>: line 2

finally を使用したリソースの解放

スクリプトで使用されるリソースを解放するには、try ブロックと catch ブロックの後に finally ブロックを追加します。 finally ブロック ステートメントは、try ブロックで終了エラーが発生したかどうかに関係なく実行されます。 PowerShell は、スクリプトが終了する前、または現在のブロックがスコープ外になる前に、 finally ブロックを実行します。

finally ブロックは、スクリプトを停止するために CTRL+C を使用した場合でも実行されます。 finally ブロックは、Exit キーワードがスクリプトを catch ブロック内から停止した場合にも実行されます。

関連項目