about_Try_Catch_Finally
簡単な説明
try
、catch
、およびfinally
ブロックを使用して終了エラーを処理する方法について説明します。
詳細な説明
try
、catch
、および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
ブロックを使用すると、スクリプトで不要になったリソースを解放できます。
try
、 catch
、および finally
は、C# プログラミング言語で使用される try
、 catch
、および 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
ステートメントが制御を受け取ります。
Trap
がtry
より高いブロックに存在し、現在のスコープ内に一致する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.
ScriptStackTrace、Exception、ErrorDetails など、アクセスできる追加のプロパティがあります。 たとえば、スクリプトを次のように変更するとします。
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
ブロック内から停止した場合にも実行されます。
関連項目
PowerShell