【问题标题】:PowerShell script always Pass, doesn't throw Error - "ErrorAction Stop" doesn't catch exception [duplicate]PowerShell脚本始终通过,不抛出错误-“ErrorAction Stop”不捕获异常[重复]
【发布时间】:2021-10-10 08:19:33
【问题描述】:

我有我的静默安装 PowerShell 脚本,但我有一个问题,即使某些参数不正确,我的 powershell 脚本执行也不会失败。

$expression="C:\app\tool.exe  /COMPUTER=server1  /INSTALL  /SILENT"
try {
Invoke-Expression $expression -ErrorAction Stop
}
catch {
Write-Host "Entered Exception"
}

不幸的是它总是“绿色”,就像执行成功并且没有抛出任何错误一样。

在日志中,我可以看到它是“意外取消”设置。

******************************************************** Error:
Connect to computer registry failed
Computer 'SERVER1' does not exist
The network path was not found.

Unattended setup >>> 'Cancel'
********************************************************
Exit code = 0x4C7

我的脚本没有输入catch 子句。 是否有可能我可以以某种方式强制它失败,所以我可以捕捉到那个错误。 我有一个大问题,我的 powershell 没有失败,虽然它应该是因为它有错误的安装参数。

谢谢!!!

【问题讨论】:

  • @AdityaNair 如果我在没有 Invoke-Expression 的情况下执行脚本,是否相关?如果我在没有 Invoke-Expression 的情况下执行,我会得到完全相同的行为 - 我没有收到任何错误 "C:\app\tool.exe /COMPUTER=server1 /INSTALL /SILENT" 你能告诉我为什么如果我直接运行 .exe 文件它不会抛出错误吗?
  • 在exe执行结束时检查$LASTEXITCODE的输出。如果状态不为 0,则抛出错误。我已将其发布在答案中以供参考。
  • 从 PowerShell 7.2 开始,对外部程序的调用不会导致 PowerShell 错误(即使通过 Invoke-Expression),这意味着 PowerShell 的错误处理功能(例如 try { ... } catch { ... } ) 不适用(除了意外,由于重定向到 v7.1 的错误)。相反,检查$LASTEXITCODE 是否为非零以确定外部程序是否失败。 未来 PowerShell 版本可能会提供一种opt-in 机制,用于将外部程序调用集成到 PowerShell 的错误处理中。详情请见the linked duplicate

标签: powershell


【解决方案1】:

Invoke-Expression 仅检查运行命令的可能性,并在可以调用命令时给出成功。 使用$LASTEXITCODE 来检查输出:

$expression="C:\app\tool.exe  /COMPUTER=server1  /INSTALL"
try {
    $result = Invoke-Expression $expression
    if ($LASTEXITCODE -ne 0) {
        throw $result
    }
}
catch {
    Write-Host "Entered Exception"
    $_
}

【讨论】:

  • 不幸的是,这无济于事。我仍然没有得到任何输出。如果我添加了一些 Write-Host,它会被打印出来,但不会捕获 catch 子句。 PS C:\> try {Write-Host "aaaa" >> $result = Invoke-Expression $expression >> Write-Host "bbb" >> if ($result -like "*not found*" -or $result -like "*Error*") { >> throw $result >> } >> } >> catch { >> Write-Host "Entered Exception" >> $_ >> } aaaa bbb
  • $LASTEXITCODE 也适用于使用 Invoke-Expression 运行的本机应用程序。要捕获 $result 变量中的错误,您需要将错误流重定向到成功流 $result = Invoke-Expression ($expression + " 2>&1")
  • 谢谢。使用 $LASTEXITCODE 部分的第二个解决方案有效!!! ($reuslt 之类的表达式没有,但是当我使用 LASTXITICODE 时,我得到了我需要的东西)非常感谢
  • 我没有投反对票,但我认为您的答案可以改进:一般建议不要使用Invoke-Expression,而should especially be avoided for calling external programs。成功或失败通常不应源自外部程序的输出,而是源自其退出代码(这使您的$LASTEXITCODE 解决方案成为正确的解决方案)。此外,在手头的情况下,由于/SILENT,可能根本没有 no (stdout/stderr) 输出(只有日志文件输出)。
  • 我已经根据工作解决方案@AndreyDonald修改了答案
猜你喜欢
  • 2012-10-01
  • 2018-03-23
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多