captura del código de retorno de un comando con "invocar-comando"-Powershell 2
return-value (6)
Estoy usando "invocar-comando" para 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 al verificar el código de retorno.
Intenté lo siguiente.
$code = invoke-command -computername ....
Pero no devuelve nada.
¿El Invoke-command
catch no devuelve el código del bloque de script?
¿Hay otra manera de resolver esto?
Aquí hay un ejemplo ...
Script Remoto:
try {
... go do stuff ...
} catch {
return 1
exit
}
return 2
exit
Guión 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"
$ por lo tanto, -UseSSL y $ mycreds no son necesarios si está dentro de un grupo de confianza. Esto parece funcionar para mí ... ¡buena suerte!
Creo que si ejecuta un comando de esa manera en otro servidor, no hay forma de 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 volver a conectarse a esa sesión.
Sin embargo, lo que puede hacer es crear una sesión en la computadora remota e invocar su script dentro de esa sesión. Después, puede volver a comprobar el valor de retorno en esa sesión. Así que algo a lo largo de las líneas de:
$s = New-PSSession -ComputerName <server_name>
Invoke-Command -Session $s -ScriptBlock { ... }
Invoke-Command -Session $s -ScriptBlock { $? }
Podría funcionar. De esta manera, obtendrá 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 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". Estaba asumiendo 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
deInvoke-Command
.Por ejemplo, el siguiente comando ejecuta el script
Sample.ps1
en las computadorasS1
yS2
:
invoke-command -computername S1, S2 -filepath C:/Test/Sample.ps1
Los resultados del script se devuelven al equipo local. No es necesario copiar ningún archivo.
El último Powershell Invoke-Command a continuación devuelve Boolean True si el código de error es cero desde el script ejecutado y boolean False si el código de retorno no es cero. Funciona muy bien para detectar códigos de error devueltos desde 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"
}
}
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.
El script de PowerShell es $res=invoke-command -Computername %computer% {C:/TEST/BATCH.CMD} write-host $res
Descubrirá que $ res es el resultado del proceso por lotes, sabiendo esto utilizando @echo off ,> nul y echo "lo que quieres devolver" es posible!
Usted script por lotes
@echo off
echo "Start Script, do not return" > nul
echo 2
Ahora $ res será = 2! Entonces puedes aplicar cualquier lógica en tu lote.
¡Incluso puede usar invoke-command -AsJob Use Receive-job para obtener el resultado! En este caso no necesitas usar $ res.
Saludos, Julien
Si necesita la salida del bloque de script y el código de salida, puede lanzar el código de salida del bloque y convertirlo de nuevo en un 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 $_.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 se capture y se vuelva a lanzar como códigos de salida. Salida del ejemplo ...
This is output that should not be lost
$exceptionExit = 99
Si un bloque de secuencia de comandos remoto devuelve un código de salida, se cerrará la sesión. Solo 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