2009-07-31 3 views
15

Я использую команду «invoke-command» для выполнения сценария на удаленной машине.catching return code of command with invoke-command - Powershell 2

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

Мой скрипт возвращает «-1» при возникновении ошибок. Итак, я хотел убедиться, что сценарий успешно выполнен, проверив код возврата.

Я пробовал следующим образом.

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

Но он ничего не возвращает.

Не Invoke-command уловить код кода сценария?

Есть ли другой способ решить эту проблему?

ответ

10

Я думаю, что если вы запустите команду на другом сервере, вы не сможете получить код возврата своего сценария там. Это связано с тем, что Invoke-Command просто запускает одну команду на удаленном компьютере, возможно, в течение одного временного сеанса, и вы не можете снова подключиться к этому сеансу.

Что вы делаете может, однако, создает сеанс на удаленном компьютере и вызывает ваш скрипт в этом сеансе. После этого вы можете снова проверить возвращаемое значение в этом сеансе. Так что что-то вроде:

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

может работать. Таким образом, вы получаете доступ к тому же состоянию и переменным, что и первый Invoke-Command на удаленном компьютере.

Также Invoke-Command вряд ли пройдет через возвращаемое значение удаленной команды. Как бы вы тогда выяснили, что сам Invoke-Command не удалось?

ETA: Хорошо, я неправильно вас понял относительно «кода возврата». Я предполагал, что вы имели в виду $?. Во всяком случае, в соответствии с документацией вы можете запустить скрипт на удаленном компьютере следующим образом:

Чтобы запустить локальный скрипт на удаленных компьютерах, используйте FilePath параметр Invoke-Command.

Например, следующая команда запускает скрипт Sample.ps1 на S1 и S2 компьютеров:

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

Результаты сценария возвращаются на локальный компьютер. Вам не нужно копировать файлы.

+0

странность в Invoke-команды при работе в контексте Дженкинс, код возврата, как этот $ = код возврата Invoke-команда -file somescript.ps1 вернется каждый из somescript.ps1. если он запускается внутри окон команд, возвращаемое значение возвращается правильно. у кого есть идея? – koo9

+0

@ koo9: '$ returnCode' получит _pipeline output_ файла сценария. Не код выхода. – Joey

+0

предположительно, но при запуске скрипта в задании Jenkins, как-то $ returncode улавливает весь вывод из сценария ps1 – koo9

3

Вот пример ...

Удаленный скрипт:

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

Локальный сценарий:

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" 

$ так, -UseSSL и $ mycreds не нужны, если вы полностью внутри группы доверия. Это, похоже, работает для меня ... удачи!

2

Если удаленный скриптовый блок возвращает код выхода, функция psession будет закрыта. Я просто проверяю состояние психики. Если он закрыт, я допускаю ошибку. Вид хаки, но он работает для моих целей.

$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

Я искал код возврата ошибки с помощью командного сценария, вызываемого с помощью команды invoke-command. Не легкая задача, но я нашел хороший и простой способ сделать это.

Вы PowerShell скрипт $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res Узнаешь в $ Рез является дозирующий выход, зная это, используя @ECHO прочь,> NUL и эхо «что вы хотите, чтобы вернуться» это возможно!

Вы пакетный сценарий

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

Теперь $ Рез будет = 2! Затем вы можете применить любую логику в своей партии.

Вы также можете использовать команду invoke -AsJob Использовать приемную работу для получения результата! В этом случае вам не нужно использовать $ res.

Приветствие, Julien

0

Если вам нужен выход из блока сценария и кода завершения, вы можете выбросить код выхода из блока и преобразование, если обратно в целое на вызывающей стороне.

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

Это возвращает стандартный код выхода и последний код выхода. Однако это требует, чтобы в вашем блоке скрипта все исключения были пойманы и повторно выбраны в качестве кодов выхода. Выход из примера ...

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