PowerShell tr​​y/catch/finally

Posted

技术标签:

【中文标题】PowerShell tr​​y/catch/finally【英文标题】:PowerShell try/catch/finally 【发布时间】:2011-10-10 09:17:36 【问题描述】:

我最近编写了一个运行良好的 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"

错误在第二个 catch 块中被捕获 - 您可以看到来自 $error[0] 的输出。显然我想在第一个街区抓住它。我错过了什么?

【问题讨论】:

【参考方案1】:

这很奇怪。

我检查了ItemNotFoundException 的基类并测试了以下多个catches 以查看捕获什么:

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'

【讨论】:

【参考方案2】:

-ErrorAction Stop 正在为你改变一切。尝试添加这个,看看你会得到什么:

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

【讨论】:

这很有趣,考虑到$_.ExceptionItemNotFoundException 而不是ActionPreferencesStopException。我打赌后者从RuntimeException开车。 我认为你是对的。我喜欢你的开关版本。更符合史蒂夫试图做的事情。 对,这里的麻烦是它是一个非终止错误。因此,即使它是 ItemNotFoundException,除非包裹在 ActionPreferencesStopException 中,否则它实际上不会被抛出。作为开发人员,这让我很恼火。 :) @JasonMArcher 似乎是旧版本中的一个错误。这在 Powershell 5.0 中按预期对我有用 那就是它捕获了ItemNotFoundException @JasonS 是的,看起来您不再需要担心异常被包装了。

以上是关于PowerShell tr​​y/catch/finally的主要内容,如果未能解决你的问题,请参考以下文章

PowerShell tr​​y/catch/finally

如何转义 schtasks /tr 参数

vagrant powershell tr anslation missing:en.vagrant_winrm.errors.winrm_not_ready

如何使用XML文件中的PowerShell更新数据源连接字符串

在 Azure Devops 中使用从一个 PowerShell 任务到另一个任务的变量值

powershell和powershell ise到底分别干啥用,powershell命令那么长怎么记