如何在同一执行脚本中检查管道的成功/失败?
Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false
我不需要任何比 更等同的东西$?
。
答案1
同意 try...catch 方法,但是如果 ($?) {}也可以很好地工作,但不会捕获通常会完全抛出脚本的异常。
无论如何,PowerShell 的优势之一也是它的弱点之一。我说的是管道。是的,可以通过管道传递对象很棒,但是当您的脚本在生产中运行时,您需要优雅地失败,创建有意义的日志,返回有意义的返回代码,可能向待命人员发送短信,甚至运行恢复作业,那么当管道刚刚遇到第 50 个对象时,如果还有 70 个对象要处理,管道就没什么用了。
在生产脚本中,我强烈建议暂存“管道工作”。也就是说,使用管道功能收集工作队列 (Get-VM | Where-Object,等等),并将其推送到对象数组中。
然后使用 Foreach-Object 遍历工作队列中的对象。在 Foreach-Object 中,当涉及到 Remove-Snapshot 之类的操作时,使用 try...catch,并查询返回的异常对象以提供返回代码/日志文件/警报/恢复序列等。
答案2
嗯,Powershell 有 $?,所以我假设问题是它只在退出时填充?
在处理运行代码中的错误时,最佳做法是使用Try/Catch 块。如果出现问题,“Try”块内的代码将自动切换到“Catch”,甚至更好的是,您可以针对不同的异常使用不同的 catch 块,这样您就可以动态处理不同的问题。非常酷。
答案3
正如已经指出的,安全的方法是使用 Try/Catch 块:
try
{
Get-VM -Name Machine | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-1)} | Remove-Snapshot -Confirm:$false
}
catch
{
# Rainbows, unicorns and error handling here
}
如果您将输出分配给变量并想要自己测试输出,则可以将 try/catch 块放在子表达式中,并在失败时将其默认为$null
或$false
,如下所示:
$results = $( try{Get-Something "MaybeNonexisting"} catch{$false} )
if(-not($results))
{
# more unicorns
Write-Host ("Something awful happened: {0}" -f $Error[0])
}