使用“invoke-command”捕获命令的返回码 - Powershell 2

时间:2009-07-31 06:23:56

标签: powershell return-value

我正在使用“invoke-command”在远程计算机上执行脚本。

invoke-command -computername <server_name> -scriptblock {command to execute the script}

当出现任何错误时,我的脚本会返回“-1”。 因此,我想通过检查返回代码来确保脚本已成功执行。

我尝试如下。

$code = invoke-command -computername ....

但它什么也没有回报。

Invoke-command不会捕获脚本块的返回码吗?

还有其他方法可以解决这个问题吗?

6 个答案:

答案 0 :(得分:10)

我认为如果你在另一台服务器上以这种方式运行命令,你就无法获得脚本的返回代码。这是因为Invoke-Command只是在远程计算机上运行一个命令,可能在一个临时会话中,并且您无法再次连接到该会话。

可以做的是在远程计算机上创建会话并在该会话中调用您的脚本。之后,您可以再次检查该会话中的返回值。所以有些东西:

$s = New-PSSession -ComputerName <server_name>
Invoke-Command -Session $s -ScriptBlock { ... }
Invoke-Command -Session $s -ScriptBlock { $? }

可能会奏效。这样,您就可以访问与远程计算机上的第一个Invoke-Command相同的状态和变量。

同样Invoke-Command不太可能通过远程命令的返回值。你怎么知道Invoke-Command本身失败了?

ETA:好的,我误解了你的“返回代码”。我假设你的意思是$?。无论如何,根据文档,您可以在远程计算机上运行脚本,如下所示:

  

要在远程计算机上运行本地脚本,请使用   FilePath的{​​{1}}参数。

     

例如,以下命令运行Invoke-Command脚本   在Sample.ps1S1台计算机上:

S2
     

脚本的结果将返回到本地计算机。您   不需要复制任何文件。

答案 1 :(得分:3)

这是一个例子......

远程脚本:

try {
    ... go do stuff ...
} catch {
    return 1
    exit
}
return 2
exit

本地脚本:

function RunRemote {
    param ([string]$remoteIp, [string]$localScriptName)
    $res = Invoke-Command -computername $remoteIp -UseSSL -Credential $mycreds -SessionOption $so -FilePath $localScriptName
    return $res
}

$status = RunRemote $ip_name ".\Scripts\myRemoteScript.ps1"
echo "Return status was $status"

$ so,如果您完全位于信任组内,则不需要-UseSSL和$ mycreds。 这似乎对我有用......祝你好运!

答案 2 :(得分:3)

如果远程脚本块返回退出代码,则psession将关闭。我只是在检查psession的状态。如果它关闭我会假设一个错误。有点hacky,但它适用于我的目的。

$session = new-pssession $env:COMPUTERNAME
Invoke-Command -ScriptBlock {try { ErrorHere } Catch [system.exception] {exit 1}} -Session $session

if ($session.State -eq "Closed")
{
    "Remote Script Errored out"
}

Remove-PSSession $session

$session = new-pssession $env:COMPUTERNAME
Invoke-Command -ScriptBlock {"no exitcodes here"} -Session $session

if ($session.State -ne "Closed")
{
    "Remote Script ran succesfully"
}

Remove-PSSession $session

答案 3 :(得分:0)

我希望通过invoke-command调用的批处理脚本来捕获错误代码。这不是一件容易的事,但我找到了一个简单易行的方法。

您的PowerShell脚本是 $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res 您会发现$ res是批量输出,通过使用@echo off,&gt; nul和echo“您想要返回的内容”知道这一点!

批量脚本

@echo off
echo "Start Script, do not return" > nul
echo 2

现在$ res将= 2!然后,您可以在批处理中应用任何逻辑。

您甚至可以使用invoke-command -AsJob 使用Receive-job获取输出!在这种情况下,您不需要使用$ res。

干杯, 于连

答案 4 :(得分:0)

下面的最后一个Powershell Invoke-Command如果错误代码从执行的脚本为零则返回布尔值True,如果返回码非零,则返回布尔值False。适用于检测远程执行返回的错误代码。

function executeScriptBlock($scriptString) {

    Write-Host "executeScriptBlock($scriptString) - ENTRY"

    $scriptBlock = [scriptblock]::Create($scriptString + " `n " + "return `$LASTEXITCODE")

    Invoke-Command -Session $session -ScriptBlock $scriptBlock

    $rtnCode = Invoke-Command -Session $session -ScriptBlock { $? }

    if (!$rtnCode) {
        Write-Host "executeScriptBlock - FAILED"
    }
    Else {
        Write-Host "executeScriptBlock - SUCCESSFUL"
    }
}

答案 5 :(得分:-1)

如果您需要脚本块输出的输出,您可以从块中抛出退出代码并转换回调用端的整数...

$session = new-pssession $env:COMPUTERNAME
try {
    Invoke-Command -ScriptBlock {Write-Host "This is output that should not be lost"; $exitCode = 99; throw $exitCode} -Session $session
} catch {
    $exceptionExit = echo $_.tostring()
    [int]$exceptionExit = [convert]::ToInt32($exceptionExit)
    Write-Host "`$exceptionExit = $exceptionExit"
}

这将返回标准输出和最后一个退出代码。但是,这确实需要在脚本块中捕获任何异常并将其作为退出代码重新抛出。示例输出......

This is output that should not be lost
$exceptionExit = 99