【问题标题】:Powershell Ignore errorPowershell忽略错误
【发布时间】:2018-05-04 08:52:41
【问题描述】:

如何让 powershell 忽略旧命令的失败?

所有 powershell 模块都支持-ErrorAction,但是这不适用于NET STOP 等旧版命令

NET STOP WUAUSERV
echo $?
true

我想尝试停止服务,如果服务已经停止,请继续。重现此问题的一种简单方法是尝试停止服务两次。

我尝试过的事情

$ErrorActionPreference = "SilentlyContinue"
NET STOP WUAUSERV
NET STOP WUAUSERV
echo $LASTEXITCODE

尝试使用 AND 和 OR 运算符

NET STOP WUAUSERV || $true
NET STOP WUAUSERV || $true
echo $LASTEXITCODE

NET STOP WUAUSERV && $true
NET STOP WUAUSERV && $true
echo $LASTEXITCODE

我也尝试过重定向错误

NET STOP WUAUSERV 2>nul
NET STOP WUAUSERV 2>nul
echo $LASTEXITCODE

按照similar question 中的建议,我也尝试过

cmd.exe /C "NET STOP WUAUSERV"

如何使这个旧命令具有幂等性?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    My other answer 讨论了处理来自外部可执行文件的标准错误输出/退出代码。

    关于停止服务的幂等方式(保证服务处于停止状态):

    • Matthew Wetmore's helpful answer 建议使用 PowerShell 的 Stop-Service cmdlet应该是幂等的:如果服务正在运行,它要么停止服务,要么如果它已经处于停止状态,则为空操作.

      • 停止是同步的,除非你使用-NoWait 开关(PSv5+),如我的this answer 所示。
    • 1234563服务已停止,同时仍在检测错误情况:
    $svc = 'wuauserv'
    if ((Get-Service $svc).Status -ne 'Stopped') {
      net stop $svc
      if ($LASTEXITCODE) { Throw "Failed to stop service $svc."}
    } else {
      Write-Verbose -Verbose "(Service $svc is already stopped.)"
    }
    

    【讨论】:

      【解决方案2】:

      对于许多常见任务,正确的答案是使用已经存在的本机 PowerShell 命令。

      对于这个特定示例,正确的路径是使用Stop-Service cmdlet,它将优雅地处理您的条件。

      如果您必须使用旧版工具,请参阅 StackOverflow 答案:Powershell: Capture program stdout and stderr to separate variables

      .exe 不会在 PowerShell 输出管道上放置一个传统值供您评估,因此尝试比较 $true 没有任何用处。另见:Windows PowerShell Rethinking the Pipeline

      此外,$ErrorActionPreference 对旧版 .EXE 没有影响。 (而-ErrorAction 特定于 PowerShell 命令。)

      【讨论】:

      • 推荐 PowerShell cmdlet 的好主意。关于“不要将传统值放在 PowerShell 输出管道上供您评估”:控制台应用程序通过管道发送其 stdout 输出。 || 目前在 PowerShell 中根本不支持(生成语法错误); should it get implemented,它肯定作用于控制台应用程序的退出代码(以及 PowerShell-native 命令的成功状态)。 -ErrorAction 甚至不能应用于可执行文件的调用。
      • Stop-Service 的工作方式略有不同,这给我带来了我在另一个问题stackoverflow.com/questions/47405100/… 中解释过的问题
      • @mklement0,是的。我在争论是否进入输出中的标准输出结果的主题,以及问题的语法挑战,但没有解决。我后来添加的几件事可能令人困惑,因此我根据您的观点稍微调整了答案。
      • @spuder 我想知道为什么您在尝试更新时要停止更新服务wuauserv...我在另一篇文章中评论说您可能希望确保该服务是完全停止,即使在使用 Stop-Service 时,如果您确实需要停止它...再次提醒您认真考虑停止该服务是否真的是您想要做的。
      • @MatthewWetmore 此脚本用于自动化中使用打包程序构建黄金映像。如果 Windows 更新服务正在运行,它可能会在打包程序完成之前提前重启机器。 blog.powerbiz.net.au/fixes/…
      【解决方案3】:
      • 在 PowerShell 中静默错误/stderr 输出,请使用 2> $null,而不是 2> NUL

        • $ErrorActionPreference 的值不应对调用外部实用程序(控制台应用程序)有任何影响,例如 net.exe,但 - due to a bug 从 Windows PowerShell v5 开始。 1 / PowerShell Core v6.0.0-beta.9 - 如果值为'Stop'2> $null(实际上,any2 的重定向,错误流)当前触发 PowerShell 错误.
      • 很遗憾,从 Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.9 开始,PowerShell 不支持 控制运算符 &&||;但是,即使它们是,您也不会在这里需要它们(并且您不会将它们与 $true$false 一起使用)。


      不管stderr输出是否静音:

      • $LASTEXITCODE 包含最近执行的外部实用程序的退出代码。

      • 在执行外部实用程序后,如果$LASTEXITCODE0,则$?$True,否则为$False

      关于 PowerShell 错误处理的全面讨论 - 关于 PowerShell 原生命令和外部实用程序 - see here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-26
        • 2012-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 2015-12-29
        • 2014-07-30
        相关资源
        最近更新 更多