web-dev-qa-db-ja.com

「invoke-command」を使用してコマンドのリターンコードをキャッチする-Powershell2

「invoke-command」を使用して、リモートマシンでスクリプトを実行しています。

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

エラーがあると、スクリプトは「-1」を返します。そのため、戻りコードをチェックして、スクリプトが正常に実行されたことを確認したかったのです。

私は次のように試しました。

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

しかし、それは何も返しません。

しないInvoke-commandスクリプトブロックのリターンコードをキャッチしますか?

これを解決する他の方法はありますか?

17
Buddhika

別のサーバーでそのようにコマンドを実行した場合、そこでスクリプトのリターンコードを取得する方法はないと思います。これは、Invoke-Commandがリモートマシンで1つのコマンドを実行するだけで、おそらく1つの一時セッション内で実行され、そのセッションに再度接続できないためです。

ただし、できることは、リモートコンピューターでセッションを作成し、そのセッション内でスクリプトを呼び出すことです。その後、そのセッションで戻り値を再度確認できます。したがって、次のようなものがあります。

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

うまくいくかもしれません。このようにして、リモートマシンの最初のInvoke-Commandと同じ状態と変数にアクセスできます。

また、Invoke-Commandがリモートコマンドの戻り値を通過する可能性はほとんどありません。では、Invoke-Command自体が失敗したことをどのように理解しますか?

ETA:わかりました、「リターンコード」に関して誤解しました。私はあなたが$?を意味していると思っていました。とにかく、ドキュメントによると、次のようにリモートコンピュータでスクリプトを実行できます。

リモートコンピューターでローカルスクリプトを実行するには、Invoke-CommandFilePathパラメーターを使用します。

たとえば、次のコマンドは、Sample.ps1およびS1コンピューターでS2スクリプトを実行します。

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

スクリプトの結果はローカルコンピューターに返されます。ファイルをコピーする必要はありません。

10
Joey

ここに例があります...

リモートスクリプト:

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は必要ありません。これは私にとってはうまくいくようです...頑張ってください!

3
Iain Ballard

リモートスクリプトブロックが終了コードを返す場合、psessionは閉じられます。私はただ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
3
Cirem

私は、invoke-commandを介して呼び出されたバッチスクリプトによって返されるエラーコードをキャッチしようとしていました。簡単な作業ではありませんが、私はそれを行うための素晴らしくて簡単な方法を見つけました。

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 -AsJob Use Receive-jobを使用して出力を取得することもできます!この場合、$ resを使用する必要はありません。

乾杯、ジュリアン

0
Julien

以下の最後のPowershellInvoke-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"
    }
}
0
Jared