【问题标题】:How to capture the Return Value of a ScriptBlock invoked with Powershell's Invoke-Command如何捕获使用 Powershell 的 Invoke-Command 调用的 ScriptBlock 的返回值
【发布时间】:2012-01-22 20:47:26
【问题描述】:

我的问题与this one 非常相似,除了我试图使用 Invoke-Command 捕获 ScriptBlock 的返回码(因此我不能使用 -FilePath 选项)。这是我的代码:

Invoke-Command -computername $server {\\fileserver\script.cmd $args} -ArgumentList $args
exit $LASTEXITCODE

问题是 Invoke-Command 没有捕获 script.cmd 的返回码,所以我无法知道它是否失败。我需要知道 script.cmd 是否失败。

我也尝试使用 New-PSSession(它可以让我在远程服务器上看到 script.cmd 的返回代码),但我找不到任何方法将其传递回我的调用 Powershell 脚本以实际执行任何关于失败。

【问题讨论】:

    标签: powershell return-value exit-code windows-scripting invoke-command


    【解决方案1】:
    $remotesession = new-pssession -computername localhost
    invoke-command -ScriptBlock { cmd /c exit 2} -Session $remotesession
    $remotelastexitcode = invoke-command -ScriptBlock { $lastexitcode} -Session $remotesession
    $remotelastexitcode # will return 2 in this example
    
    1. 使用 new-pssession 创建新会话
    2. 在此会话中调用您的脚本块
    3. 从此会话中获取 lastexitcode

    【讨论】:

    • 这行得通。我不知道您可以像这样将会话中的远程变量传递回本地脚本。谢谢!
    • $remotelastexitcode = invoke-command -ScriptBlock { cmd /c exit 2; $lastexitcode} -Session $remotesession 不行吗?由于您使用会话来提供多个命令,因此您可能可以防止这种情况发生。
    • @manojlds 是的,在第一个脚本块中捕获 lastexitcode 也可以。
    • 是否可以从使用 -filepath 参数的远程会话中检索最后一个退出代码,例如 Invoke-Command -Session $Session -FilePath "FullStopBizTalkApp.ps1" -argumentlist $BizTalkMgmtDBConString, $ ApplicationNameInBizTalk
    • 非常感谢 - 这对我也很有帮助!
    【解决方案2】:
    $script = {
        # Call exe and combine all output streams so nothing is missed
        $output = ping badhostname *>&1
    
        # Save lastexitcode right after call to exe completes
        $exitCode = $LASTEXITCODE
    
        # Return the output and the exitcode using a hashtable
        New-Object -TypeName PSCustomObject -Property @{Host=$env:computername; Output=$output; ExitCode=$exitCode}
    }
    
    # Capture the results from the remote computers
    $results = Invoke-Command -ComputerName host1, host2 -ScriptBlock $script
    
    $results | select Host, Output, ExitCode | Format-List
    

    主机:HOST1
    输出:Ping 请求找不到主机 badhostname。请检查名称,然后重试
    退出代码:1

    主机:HOST2
    输出:Ping 请求找不到主机 badhostname。请检查名称,然后重试。
    退出代码:1

    【讨论】:

      【解决方案3】:

      我最近一直在使用另一种方法来解决这个问题。来自远程计算机上运行的脚本的各种输出是一个数组。

      $result = Invoke-Command -ComputerName SERVER01 -ScriptBlock {
         ping BADHOSTNAME
         $lastexitcode
      }
      
      exit $result | Select-Object -Last 1
      

      $result 变量将包含一个由 ping 输出消息和 $lastexitcode 组成的数组。如果远程脚本的退出代码是最后输出的,那么它可以从完整的结果中提取而无需解析。

      要在退出代码之前获得其余的输出,只需:
      $result | Select-Object -First $(result.Count-1)

      【讨论】:

        【解决方案4】:

        @jon Z 的回答不错,不过这样更简单:

        $remotelastexitcode = invoke-command -computername localhost -ScriptBlock {
            cmd /c exit 2; $lastexitcode}
        

        当然,如果您的命令产生输出,您将不得不抑制它或解析它以获取退出代码,在这种情况下@jon Z 的答案可能会更好。

        【讨论】:

          【解决方案5】:

          最好使用return 而不是exit

          例如:

          $result = Invoke-Command -ComputerName SERVER01 -ScriptBlock {
             return "SERVER01"
          }
          
          $result
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多