capturando el código de retorno de un comando con & # 8220; invoke-command & # 8221; - Powershell 2

StackOverflow https://stackoverflow.com/questions/1210942

  •  06-07-2019
  •  | 
  •  

Pregunta

Estoy usando " invoke-command " ejecutar un script en una máquina remota.

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

Mi script devuelve " -1 " cuando hay algún error Por lo tanto, quería asegurarme de que el script se haya ejecutado correctamente comprobando el código de retorno.

Intenté lo siguiente.

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

Pero no devuelve nada.

¿No Invoke-command captura el código de retorno del bloque de script?

¿Hay otra forma de resolver esto?

¿Fue útil?

Solución

Creo que si ejecuta un comando de esa manera en otro servidor, no hay forma de que pueda obtener el código de retorno de su script allí. Esto se debe a que Invoke-Command simplemente ejecuta un comando en la máquina remota, probablemente dentro de una sola sesión temporal y no puede conectarse a esa sesión nuevamente.

Lo que puede hacer, sin embargo, es crear una sesión en la computadora remota e invocar su secuencia de comandos dentro de esa sesión. Luego, puede verificar nuevamente el valor de retorno en esa sesión. Entonces algo en la línea de:

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

podría funcionar. De esta forma, obtiene acceso al mismo estado y variables que el primer Invoke-Command en la máquina remota.

También es muy poco probable que Invoke-Command pase por el valor de retorno del comando remoto. ¿Cómo descubrirías entonces que el Invoke-Command falló?

ETA: Ok, te he leído mal con respecto al " código de retorno " ;. Supuse que querías decir $? . De todos modos, de acuerdo con la documentación, puede ejecutar un script en una computadora remota de la siguiente manera:

  

Para ejecutar un script local en computadoras remotas, use el   Parámetro FilePath de Invoke-Command .

     

Por ejemplo, el siguiente comando ejecuta el script Sample.ps1   en las computadoras S1 y S2 :

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

Los resultados del script se devuelven a la computadora local. usted   no es necesario copiar ningún archivo.

Otros consejos

Aquí hay un ejemplo ...

Script remoto:

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

Script local:

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 y $ mycreds no son necesarios si está completamente dentro de un grupo de confianza. Esto parece funcionar para mí ... ¡buena suerte!

Si un bloque de script remoto devuelve un código de salida, la sesión se cerrará. Solo estoy comprobando el estado de la psession. Si está cerrado, supongo un error. Un poco hacky, pero funciona para mis propósitos.

$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

Estaba buscando atrapar el código de error devuelto por un script por lotes llamado a través de invoke-command. No es una tarea fácil, pero encontré una manera agradable y fácil de hacerlo.

Tu script de PowerShell es $ res = invoke-command -Computername% computer% {C: \ TEST \ BATCH.CMD} write-host $ res Descubrirá que $ res es la salida del lote, sabiendo esto usando @echo off, > nul y echo " lo que desea devolver " es posible!

Usted secuencia de comandos por lotes

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

¡Ahora $ res será = 2! Luego puede aplicar cualquier lógica en su lote.

Incluso puedes usar invoke-command -AsJob ¡Utilice el trabajo de recepción para obtener la salida! En este caso, no necesita usar $ res.

Saludos, Julien

El último comando de invocación de Powershell a continuación devuelve boolean True si el código de error es cero del script ejecutado y boolean False si el código de retorno no es cero. Funciona muy bien para detectar códigos de error devueltos de ejecuciones remotas.

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"
    }
}

Si necesita la salida del bloque de script y el código de salida, puede arrojar el código de salida del bloque y convertirlo de nuevo en un número entero en el lado de la llamada ...

$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 

Si necesita la salida del bloque de script y el código de salida, puede arrojar el código de salida del bloque y convertirlo de nuevo en un número entero en el lado de la llamada ...

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

Esto devuelve la salida estándar y el último código de salida. Sin embargo, esto requiere que dentro de su bloque de script, cualquier excepción sea capturada y relanzada como código de salida. Salida del ejemplo ...

<*>.tostring() [int]$exceptionExit = [convert]::ToInt32($exceptionExit) Write-Host "`$exceptionExit = $exceptionExit" }

Esto devuelve la salida estándar y el último código de salida. Sin embargo, esto requiere que dentro de su bloque de script, cualquier excepción sea capturada y relanzada como código de salida. Salida del ejemplo ...

<*>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top