try/catch控件的整个想法是告诉脚本如果遇到终止错误该怎么做,而不是抛出错误并停止脚本的默认操作。如果您的 catch 块仅使用Write-Host向终端显示一条消息,那么这就是所有的错误处理,并且脚本将从那里继续。如果您考虑一下,如果在捕获到错误时自动停止脚本,它将部分破坏try/catch的目的。
在catch块中,$_将设置为 ErrorRecord 对象,表示来自try块的终止错误(与存储在$error[0]中的相同)。所以结束脚本最简单的方法是重新抛出如果你没有使用try/catch会抛出的错误:
try {
Get-Content "c:\GarbageFileName.txt" -ErrorAction stop
} catch {
# Custom action to perform before terminating
throw $_
}
或者,如果您想显示自定义消息而不是默认的 ErrorRecord:
try {
Get-Content "c:\GarbageFileName.txt" -ErrorAction stop
} catch {
throw 'Custom error message'
}
或者,如果您想在完成自定义错误处理后退出而不向错误流抛出错误,则可以按照 Joost 的回答中的建议使用break 。
或者您可以变得更复杂并创建自己的 ErrorRecord 对象。你可以做很多事情,这个话题太大了,无法在这里全面介绍,但你可以通过谷歌搜索System.Management.Automation.ErrorRecord获得有关语法的更多信息。这是我的一个脚本中的一个示例,可帮助您入门(来自一个针对 SQL Server 数据库执行$query变量中定义的 SQL 查询的函数):
} catch {
$ErrorRecord = New-Object System.Management.Automation.ErrorRecord(
(New-Object Exception("Exception executing the query: $($_.Exception.InnerException.Message)")),
$query,
[System.Management.Automation.ErrorCategory]::InvalidArgument,
$null
)
$ErrorRecord.CategoryInfo.Reason = $_.CategoryInfo.Reason;
$ErrorRecord.CategoryInfo.Activity = $_.InvocationInfo.InvocationName;
$PSCmdlet.ThrowTerminatingError($ErrorRecord);
}
几点注意事项:
- 您会看到,在创建我的自定义 ErrorRecord 时,我使用了 $_ ,我刚才说过它包含与try块中捕获的终止错误关联的 ErrorRecord 对象。这个想法是自定义一些错误输出,同时通过将默认 ErrorRecord 的部分分配给自定义 ErrorRecord 的相应属性来使用它们。
- $PSCmdlet仅在您
[CmdletBinding()]
在函数或脚本的开头声明时可用。否则,您可以使用throw $ErrorRecord
抛出您的自定义错误。但是,如果您使用$PSCmdlet.ThrowTerminatingError,结果将更像 Cmdlet 样式。(throw将从产生错误的函数中吐出该行,而$PSCmdlet.ThrowTerminatingError将为您提供使用该函数的调用上下文中的行。很难以一种有意义的方式来描述而不会过于详细,但如果你尝试一下,你就会明白我的意思。)
顺便说一句,设置$ErrorActionPreference = "Stop"
,然后使用是多余的-ErrorAction Stop
。首选项变量设置所有 cmdlet 的默认操作,并且-ErrorAction开关覆盖特定 cmdlet 的默认操作,因此无需先指定默认值,然后使用-ErrorAction指定您刚刚设置为默认值的相同操作. 您可能想要做的只是省略$ErrorActionPreference = "Stop"
。