перехват кода возврата команды с помощью «invoke-command» — Powershell 2

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

  •  06-07-2019
  •  | 
  •  

Вопрос

Я использую команду «invoke» для выполнения сценария на удаленном компьютере.

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

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

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

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

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

Не Invoke-command поймать код возврата блока скрипта?

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

Это было полезно?

Решение

Я думаю, что если вы запустите команду таким образом на другом сервере, вы не сможете найти код возврата вашего сценария. Это потому, что 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
     

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

Другие советы

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

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

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"

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

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

$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

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

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

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

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

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

Вы даже можете использовать invoke-command -sjob использовать приемную работу, чтобы получить выход!В этом случае вам не нужно использовать $res.

Ура, Жюльен

Последняя приведенная ниже команда Powershell Invoke-Command возвращает логическое значение True, если код ошибки равен нулю из выполненного скрипта, и логическое значение False, если код возврата не равен нулю. Отлично работает для обнаружения кодов ошибок, возвращаемых из удаленного выполнения.

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

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

$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 

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

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

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

<*>.tostring() [int]$exceptionExit = [convert]::ToInt32($exceptionExit) Write-Host "`$exceptionExit = $exceptionExit" }

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

<*>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top