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

catching return code of a command with “invoke-command” - Powershell 2

我正在使用"调用命令"在远程计算机上执行脚本。

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

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

我尝试如下。

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

但是它什么也没返回。

Invoke-command是否不捕获脚本块的返回码?

还有其他解决方法吗?


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

但是,您可以做的是在远程计算机上创建一个会话,然后在该会话中调用脚本。之后,您可以再次检查该会话中的返回值。因此,遵循以下原则:

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

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

同样,Invoke-Command不太可能通过远程命令的返回值。那么您如何确定Invoke-Command本身失败了?

预计到达时间:我误解了您关于"返回码"的信息。我假设您的意思是$?。无论如何,根据文档,您可以在远程计算机上运行脚本,如下所示:

To run a local script on remote computers, use the
FilePath parameter of Invoke-Command.

For example, the following command runs the Sample.ps1 script
on the S1 and S2 computers:

1
invoke-command -computername S1, S2 -filepath C:\\Test\\Sample.ps1

The results of the script are returned to the local computer. You
do not need to copy any files.


如果远程脚本块返回退出代码,则psession将关闭。我只是在检查状态。如果关闭,我会假设一个错误。有点骇人听闻,但可以满足我的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$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


这是一个例子

远程脚本:

1
2
3
4
5
6
7
8
try {
    ... go do stuff ...
} catch {
    return 1
    exit
}
return 2
exit

本地脚本:

1
2
3
4
5
6
7
8
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。
这似乎对我有用...祝您好运!


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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"
    }
}

如果您需要脚本块的输出和退出代码,则可以抛出该块的退出代码,并在调用方将其转换为整数...

1
2
3
4
5
6
7
8
$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"
}

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

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


我一直在寻找由通过invoke-command调用的批处理脚本返回的错误代码。这不是一件容易的事,但我找到了一种不错的简便方法。

您的PowerShell脚本是
$res=invoke-command -Computername %computer% {C:\\TEST\\BATCH.CMD}
write-host $res

您会发现$ res是批处理输出,可以通过使用@echo off,> nul并回显"您要返回的内容"来了解这一点!

您批处理脚本

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

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

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

干杯,
朱利安