2009-07-31 7 views
15

Ich verwende "invoke-Befehl", um ein Skript auf einem Remote-Computer auszuführen.Capture Return-Code eines Befehls mit "Invoke-Befehl" - Powershell 2

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

Mein Skript gibt "-1" zurück, wenn Fehler auftreten. Also wollte ich sicherstellen, dass das Skript erfolgreich ausgeführt wurde, indem Sie den Rückgabecode überprüfen.

Ich habe versucht, wie folgt.

Aber es gibt nichts zurück.

Nicht Invoke-command fangen Rücklaufcode des Skriptblocks?

Gibt es eine andere Möglichkeit, dies zu beheben?

Antwort

10

Ich denke, wenn Sie einen Befehl so auf einem anderen Server ausführen, gibt es keine Möglichkeit, den Rückgabecode Ihres Skripts dort zu bekommen. Dies liegt daran, dass Invoke-Command einfach einen Befehl auf dem Remotecomputer ausführt, wahrscheinlich innerhalb einer einzelnen temporären Sitzung, und Sie können keine Verbindung zu dieser Sitzung erneut herstellen.

Was Sie können tun, ist jedoch eine Sitzung auf dem Remote-Computer erstellen und rufen Sie Ihr Skript innerhalb dieser Sitzung. Danach können Sie einfach in dieser Sitzung erneut nach dem Rückgabewert suchen. Also etwas in der Art von:

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

könnte funktionieren. Auf diese Weise erhalten Sie Zugriff auf den gleichen Status und die gleichen Variablen wie die erste Invoke-Command auf dem Remote-Computer.

Auch Invoke-Command ist sehr unwahrscheinlich, den Rückgabewert des Remote-Befehls zu übergeben. Wie würden Sie dann herausfinden, dass Invoke-Command selbst fehlgeschlagen ist?

ETA: Ok, ich habe Sie in Bezug auf "Rückkehrcode" falsch gelesen. Ich nahm an, du meintest $?. Wie auch immer, nach der Dokumentation können Sie ein Skript auf einem entfernten Computer laufen wie folgt:

Um eine lokale Skript auf Remote-Computer ausführen, verwenden Sie die FilePath Parameter von Invoke-Command.

Zum Beispiel der folgende Befehl führt die Sample.ps1 Skript auf den S1 und S2 Computer:

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

Die Ergebnisse des Skripts werden auf den lokalen Computer zurückgegeben. Sie müssen keine Dateien kopieren.

+0

Seltsame in Invoke-Befehl, wenn im Jenkins Kontext ausgeführt wird, der Return-Code wie dieser $ Rückkehrcode = Invoke-Befehl -datei somescript.ps1 würde jeder von somescript.ps1 zurückzukehren. Wenn in einem Befehlsfenster ausgeführt wird, wird der Rückgabewert ordnungsgemäß zurückgegeben. Hat jemand eine Idee? – koo9

+0

@ koo9: '$ returnCode' empfängt _pipeline output_ der Skriptdatei. Kein Exit-Code. – Joey

+0

angeblich, aber wenn das Skript innerhalb des Jenkins-Jobs ausgeführt wird, fangen irgendwie $ returncode alle Ausgabe vom ps1-Skript ab – koo9

3

Hier ist ein Beispiel ...

Remote-Skript:

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

Lokale Skript:

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 und $ mycreds sind nicht erforderlich, wenn Sie voll und ganz in einer Vertrauensgruppe sind. Das scheint für mich zu funktionieren ... viel Glück!

2

Wenn ein Remote-Skriptblock einen Exit-Code zurückgibt, wird Psession geschlossen. Ich überprüfe nur den Zustand der Sitzung. Wenn es geschlossen ist, nehme ich einen Fehler an. Art von Hacky, aber es funktioniert für meine Zwecke.

0

Ich suchte, um die Fehlercode-Rückgabe von einem Batch-Skript abgerufen durch Aufruf-Befehl abzufangen. Keine leichte Aufgabe, aber ich habe einen netten und einfachen Weg gefunden.

Sie Powershell-Skript ist $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res Hier finden Sie die $ res herausfinden, ist die Batch-Ausgabe, dies zu wissen, durch @echo mit handels,> nul und Echo „was Sie wollen zurückkehren“ möglich ist!

Sie Batch-Skript

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

Jetzt wird $ res sein = 2! Dann können Sie jede Logik in Ihrem Stapel anwenden.

Sie können sogar invoke-Befehl -AsJob Verwenden Sie Receive-Job, um die Ausgabe zu erhalten! In diesem Fall müssen Sie $ res nicht verwenden.

Cheers, Julien

0

Wenn Sie die Ausgabe aus dem Skriptblock und den Exit-Code benötigen, können Sie den Exit-Code aus dem Block werfen und konvertieren in eine ganzen Zahl auf der rufenden Seite, wenn zurück.

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

Dies gibt den Standardausgang und den letzten Exitcode zurück. Dies erfordert jedoch, dass in Ihrem Skriptblock alle Ausnahmen abgefangen und als Beendigungscodes erneut geworfen werden. Die Ausgabe von Beispiel ...

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