2009-07-31 29 views
15

Estoy usando "invoke-command" para ejecutar un script en una máquina remota.capturando el código de retorno de un comando con "invoke-command" - Powershell 2

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

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

Intenté como sigue.

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

Pero no devuelve nada.

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

¿Hay alguna otra manera de resolver esto?

Respuesta

10

Creo que si ejecuta un comando de esa manera en otro servidor no hay manera 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. Así que algo similar a:

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

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

También es poco probable que Invoke-Command pase por el valor de retorno del comando remoto. ¿Cómo se daría cuenta entonces que el propio Invoke-Command falló?

ETA: Bien, te he leído mal con respecto al "código de retorno". Asumía que querías decir $?. De todos modos, según la documentación puede ejecutar una secuencia de comandos en un equipo remoto de la siguiente manera:

para ejecutar un script local en equipos remotos, utilice el parámetro de Invoke-Command FilePath.

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

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

Los resultados del script se devuelven al equipo local. Usted no necesita copiar ningún archivo.

+0

cosa rara en Invoke-comando cuando se ejecuta en el contexto Jenkins, el código de retorno como esto $ returnCode = Invoke-Command -file somescript.ps1 volvería cada de somescript.ps1. si se ejecutó dentro de una ventana de comandos, el valor devuelto se devuelve correctamente. Alguien tiene alguna idea? – koo9

+0

@ koo9: '$ returnCode' recibirá _pipeline output_ del archivo de script. No es un código de salida. – Joey

+0

supuestamente, pero al ejecutar el script en el trabajo de Jenkins, de alguna manera $ returncode captura todos los resultados del script ps1 – koo9

3

Aquí hay un ejemplo ...

escritura a distancia:

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" 

$ es así, -UseSSL y $ mycreds no son necesarios si está totalmente dentro de un grupo de confianza. Esto parece funcionar para mí ... ¡buena suerte!

2

Si un scriptblock remoto devuelve un código de salida, la psession se cerrará. Estoy comprobando el estado de la psession. Si está cerrado, asumo un error. Tipo de 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 
0

Estaba buscando capturar 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.

guión

Usted PowerShell es $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res Usted se dará cuenta los $ res es la salida de lotes, sabiendo esto utilizando @ echo off,> nul y el eco "de lo que desea devolver" es posible!

Usted escritura de la hornada

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

Ahora alta $ habrá = 2! Entonces puedes aplicar cualquier lógica en tu lote.

Incluso puede usar invoke-command -AsJob ¡Use Receive-job para obtener la salida! En este caso, no necesita usar $ res.

Saludos, Julien

0

Si necesita la salida del bloque de script y el código de salida, se puede tirar el código de salida del bloque si y convertir de nuevo en un entero en el lado llamado.

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

Esto devuelve el estándar y el último código de salida. Sin embargo, esto requiere que dentro de su secuencia de comandos, cualquier excepción sea capturada y relanzada como códigos de salida. La salida de ejemplo ...

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