attraper le code de retour d'une commande avec “invoke-command” - Powershell 2

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

  •  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?

Était-ce utile?

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 de Invoke-Command .

     

Par exemple, la commande suivante exécute le script Sample.ps1 .   sur les ordinateurs S1 et S2 :

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 ...

<*>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top