about_Try_Catch_Finally

簡単な説明

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

長い説明

スクリプト内の終了エラーに応答したり処理したりするために、ブロックをcatchfinally使用tryします。 この 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および C# プログラミング言語で使用されるキーワードcatchfinallyに似ていますtryfinally

構文

tryステートメントには、tryブロック、0 個以上catchのブロック、0 個または 1 個finallyのブロックが含まれます。 ステートメントには try 、少なくとも 1 つのブロックまたは 1 つの catch ブロックが 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後には、ステートメントがエラーなしで実行された場合や、ステートメントでcatchエラーがキャッチされた場合tryでも、スクリプトが実行されるたびに実行されるステートメント リストが続きます。

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

エラーのキャッチ

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

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

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

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 型から継承されます。 次の例では、Command Not Found エラーもキャッチします。

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

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

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

注意

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

Try Catch でのトラップの使用

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

Trap a が 、現在のスコープ内tryに一致するブロックがない場合、親スコープTrapに一致catchcatchするブロックがある場合でも、制御が取られます。

例外情報へのアクセス

ブロック内では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 を使用してリソースを解放する

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

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

こちらもご覧ください