2009-07-31 9 views
15

Używam "invoke-command" do wykonania skryptu na zdalnej maszynie.przechwytywanie kodu powrotu polecenia za pomocą "invoke-command" - Powershell 2

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

Mój skrypt zwraca "-1", gdy są jakieś błędy. Tak więc chciałem upewnić się, że skrypt został pomyślnie wykonany, sprawdzając kod powrotu.

Próbowałem w następujący sposób.

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

Ale nic nie zwraca.

Czy kod powrotu bloku skryptu nie jest Invoke-command?

Czy istnieje inny sposób rozwiązania tego problemu?

Odpowiedz

10

Myślę, że jeśli uruchomisz polecenie w ten sposób na innym serwerze, nie ma możliwości uzyskania kodu powrotu skryptu. Jest tak, ponieważ Invoke-Command po prostu uruchamia jedno polecenie na zdalnym komputerze, prawdopodobnie w ramach jednej sesji tymczasowej i nie można połączyć się z tą sesją ponownie.

To, co możesz może zrobić, to jednak utworzyć sesję na komputerze zdalnym i wywołać skrypt w tej sesji. Następnie możesz po prostu sprawdzić ponownie wartość zwrotu w tej sesji. Tak więc coś w rodzaju:

może działać. W ten sposób uzyskasz dostęp do tego samego stanu i zmiennych, co pierwszy Invoke-Command na zdalnym komputerze.

Jest również mało prawdopodobne, aby przechodził przez wartość zwracaną przez polecenie zdalnego. Jak byś się domyślił, że to się nie udało?

ETA: Ok, źle odczytałem w odniesieniu do "kodu powrotnego". Zakładałem, że masz na myśli $?. W każdym razie, zgodnie z dokumentacją można uruchomić skrypt na komputerze zdalnym, co następuje:

Aby uruchomić lokalną skryptu na zdalnych komputerach, użyj parametru Invoke-Command FilePath.

Na przykład, następujące polecenie uruchamia Sample.ps1 skrypt na komputerach S1 i S2:

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

Wyniki scenariusza są zwracane do komputera lokalnego. Ty nie musisz kopiować żadnych plików.

+0

Najdziwniejsze w Invoke-Command, gdy uruchomiony w kontekście Jenkins, kod powrotu jak to $ returnCode = Invoke-Command -file somescript.ps1 wróci każdy z somescript.ps1. jeśli został uruchomiony w oknach poleceń, zwracana wartość jest zwracana poprawnie. ktoś ma jakiś pomysł? – koo9

+0

@ koo9: '$ returnCode' otrzyma _podsumowanie wyjścia_ pliku skryptu. Nie kod wyjścia. – Joey

+0

podobno, ale podczas uruchamiania skryptu w ramach pracy Jenkins, jakikolwiek kod $ returncode wychwytuje wszystkie wyniki ze skryptu ps1 – koo9

3

Oto przykład ...

zdalnego skryptu:

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

skrypt lokalny:

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" 

$ tak, -UseSSL i $ mycreds nie są potrzebne, jeśli jesteś całkowicie wewnątrz grupy zaufania. To wydaje się działać dla mnie ... Powodzenia!

2

Jeśli zdalny skrypt skryptowy zwróci kod zakończenia, sesja zostanie zamknięta. Właśnie sprawdzam stan psesji. Jeśli jest zamknięty, zakładam błąd. Coś w stylu hacky, ale działa to dla moich celów.

$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

Szukałem, aby złapać zwrot kodu błędu za pomocą skryptu wsadowego wywoływanego za pomocą polecenia invoke. Nie jest to łatwe zadanie, ale znalazłem dobry i łatwy sposób na zrobienie tego.

skrypt

Ty PowerShell jest $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res Dowiesz dolarów res jest wyjście partii, wiedząc o tym za pomocą @echo off,> nul a echo „co chcesz powrotu” jest możliwe!

skrypt Ty partia

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

Teraz $ res = 2 będzie! Następnie możesz zastosować dowolną logikę w swojej partii.

Można nawet użyć polecenia invoke -AsJob Użyj zadania odbioru, aby uzyskać dane wyjściowe! W takim przypadku nie musisz używać $ res.

Cheers, Julien

0

Jeśli potrzebujesz wyjście z bloku skryptu i kodu wyjścia, można wyrzucić kod wyjścia z bloku i przekształcić, jeśli z powrotem do liczby całkowitej po stronie wywołującego.

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

Powoduje to wyprowadzenie standardowego wyjścia i ostatniego kodu wyjścia. Wymaga to jednak, aby w obrębie bloku skryptu wszelkie wyjątki były przechwytywane i ponownie zgłaszane jako kody wyjścia. Wyjście z przykładu ...

This is output that should not be lost 
$exceptionExit = 99 
Powiązane problemy