attraper le code de retour d'une commande avec “invoke-command” - Powershell 2
-
06-07-2019 - |
Question
J'utilise " invoke-command " exécuter un script sur une machine distante.
invoke-command -computername <server_name> -scriptblock {command to execute the script}
Mon script renvoie "-1". quand il y a des erreurs. Je voulais donc m'assurer que le script a été exécuté avec succès en vérifiant le code de retour.
J'ai essayé comme suit.
$code = invoke-command -computername ....
Mais cela ne retourne rien.
La commande Invoke
n'attrape-t-elle pas le code de retour du bloc de script?
Existe-t-il un autre moyen de résoudre ce problème?
La solution
Je pense que si vous exécutez une commande de cette manière sur un autre serveur, vous ne pouvez pas obtenir le code de retour de votre script. En effet, Invoke-Command
exécute simplement une commande sur la machine distante, probablement au sein d'une seule session temporaire, et vous ne pouvez plus vous connecter à cette session.
Ce que vous pouvez faire, cependant, est de créer une session sur l'ordinateur distant et d'appeler votre script au cours de cette session. Ensuite, vous pouvez simplement vérifier la valeur de retour dans cette session à nouveau. Donc, quelque chose dans les lignes de:
$s = New-PSSession -ComputerName <server_name>
Invoke-Command -Session $s -ScriptBlock { ... }
Invoke-Command -Session $s -ScriptBlock { $? }
pourrait fonctionner. De cette manière, vous avez accès au même état et aux mêmes variables que le premier Invoke-Command
sur la machine distante.
De même, il est très peu probable que Invoke-Command
passe par la valeur de retour de la commande distante. Comment pourriez-vous comprendre alors que la Invoke-Command
elle-même a échoué?
ETA: OK, je vous ai mal compris en ce qui concerne le "code de retour". Je supposais que vous vouliez dire $?
. Quoi qu'il en soit, selon la documentation, vous pouvez exécuter un script sur un ordinateur distant comme suit:
Pour exécuter un script local sur des ordinateurs distants, utilisez la commande Paramètre
FilePath
deInvoke-Command
.Par exemple, la commande suivante exécute le script
Sample.ps1
. sur les ordinateursS1
etS2
:invoke-command -computername S1, S2 -filepath C:\Test\Sample.ps1
Les résultats du script sont renvoyés à l'ordinateur local. Vous ne devez copier aucun fichier.
Autres conseils
Voici un exemple ...
Script à distance:
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 et $ mycreds ne sont pas nécessaires si vous faites entièrement partie d'un groupe de confiance. Cela semble fonctionner pour moi ... bonne chance!
Si un scriptblock distant renvoie un code de sortie, la psession sera fermée. Je vérifie simplement l'état de la psession. Si c'est fermé je suppose une erreur. Un peu comme un hacky, mais ça marche pour moi.
$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
Je cherchais à intercepter le code d'erreur renvoyé par un script de traitement par lots appelé via invoke-command. Ce n’est pas une tâche facile, mais j’ai trouvé un moyen simple et agréable de le faire.
Votre script PowerShell est
$ res = invoke-command -Commutername% computer% {C: \ TEST \ BATCH.CMD}
write-host $ res
Vous découvrirez que $ res correspond à la sortie par lots, en le connaissant à l'aide de @echo off, > nul et echo & "ce que vous voulez renvoyer". est possible!
Votre script batch
@echo off
echo "Start Script, do not return" > nul
echo 2
Maintenant, $ res sera = 2! Vous pouvez ensuite appliquer n’importe quelle logique dans votre lot.
Vous pouvez même utiliser invoke-command -AsJob Utilisez Receive-job pour obtenir le résultat! Dans ce cas, vous n'avez pas besoin d'utiliser $ res.
Salut, Julien
La dernière commande Powershell Invoke ci-dessous renvoie le booléen Vrai si le code d'erreur du script exécuté est zéro et le booléen Faux si le code de retour est différent de zéro. Idéal pour détecter les codes d’erreur renvoyés par les exécutions à distance.
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 vous avez besoin de la sortie du bloc de script et du code de sortie, vous pouvez jeter le code de sortie du bloc et le reconvertir en un entier du côté appelant ...
$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 vous avez besoin de la sortie du bloc de script et du code de sortie, vous pouvez jeter le code de sortie du bloc et le reconvertir en un entier du côté appelant ...
This is output that should not be lost
$exceptionExit = 99
Ceci renvoie la sortie standard et le dernier code de sortie. Cela nécessite toutefois que, dans votre bloc de script, toutes les exceptions soient interceptées et renvoyées comme codes de sortie. Sortie de l'exemple ...
<*>.tostring()
[int]$exceptionExit = [convert]::ToInt32($exceptionExit)
Write-Host "`$exceptionExit = $exceptionExit"
}
Ceci renvoie la sortie standard et le dernier code de sortie. Cela nécessite toutefois que, dans votre bloc de script, toutes les exceptions soient interceptées et renvoyées comme codes de sortie. Sortie de l'exemple ...
<*>