web-dev-qa-db-ja.com

PowerShellのtry / catch / finally

最近、うまく機能するPowerShellスクリプトを作成しましたが、スクリプトをアップグレードしてエラーチェック/処理を追加したいのですが、最初のハードルに悩まされています。次のコードが機能しないのはなぜですか?

try {
  Remove-Item "C:\somenonexistentfolder\file.txt" -ErrorAction Stop
}

catch [System.Management.Automation.ItemNotFoundException] {
  "item not found"
}

catch {
  "any other undefined errors"
  $error[0]
}

finally {
  "Finished"
}

エラーは2番目のcatchブロックでキャッチされます-$error[0]からの出力を確認できます。明らかに、最初のブロックでキャッチしたいと思います。私は何が欠けていますか?

44
steve

-ErrorAction Stopはあなたのために物事を変えています。これを追加してみて、得られるものを確認してください。

Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception" 
$error[0]
}
36
Bruce

それは非常に奇妙です。

私はItemNotFoundExceptionの基本クラスを調べ、次の複数のcatchesをテストして、何をキャッチするかを確認しましたwould

try {
  remove-item C:\nonexistent\file.txt -erroraction stop
}
catch [System.Management.Automation.ItemNotFoundException] {
  write-Host 'ItemNotFound'
}
catch [System.Management.Automation.SessionStateException] {
  write-Host 'SessionState'
}
catch [System.Management.Automation.RuntimeException] {
  write-Host 'RuntimeException'
}
catch [System.SystemException] {
  write-Host 'SystemException'
}
catch [System.Exception] {
  write-Host 'Exception'
}
catch {
  write-Host 'well, darn'
}

結局のところ、出力は'RuntimeException'。また、別の例外CommandNotFoundExceptionを試してみました:

try {
  do-nonexistent-command
}
catch [System.Management.Automation.CommandNotFoundException] {
  write-Host 'CommandNotFoundException'
}
catch {
  write-Host 'well, darn'
}

その出力'CommandNotFoundException'正しく。

私はこれに関する問題を他の場所で読んだことを漠然と覚えています(再び見つけることができませんでした)。例外フィルタリングが正しく機能しなかった場合、可能な限り最も近いTypeをキャッチし、switchを使用します。以下は、Exceptionの代わりにRuntimeExceptionをキャッチしますが、switchのすべての基本型をチェックする最初の例のItemNotFoundExceptionと同等です。

try {
  Remove-Item C:\nonexistent\file.txt -ErrorAction Stop
}
catch [System.Exception] {
  switch($_.Exception.GetType().FullName) {
    'System.Management.Automation.ItemNotFoundException' {
      write-Host 'ItemNotFound'
    }
    'System.Management.Automation.SessionStateException' {
      write-Host 'SessionState'
    }
    'System.Management.Automation.RuntimeException' {
      write-Host 'RuntimeException'
    }
    'System.SystemException' {
      write-Host 'SystemException'
    }
    'System.Exception' {
      write-Host 'Exception'
    }
    default {'well, darn'}
  }
}

これにより、'ItemNotFound'、あるべきです。

28
Joel B Fant