“ invoke-command”でコマンドのリターンコードをキャッチする-Powershell 2

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

  •  06-07-2019
  •  | 
  •  

質問

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

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

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

次のように試しました。

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

しかし、何も返しません。

Invoke-command は、スクリプトブロックのリターンコードをキャッチしませんか?

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

役に立ちましたか?

解決

別のサーバーでコマンドをそのように実行すると、そこでスクリプトのリターンコードを取得する方法はないと思います。これは、 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-Command FilePath パラメーター。

     

たとえば、次のコマンドは 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は、完全に信頼グループ内にいる場合は必要ありません。 これは私にはうまくいくようです...幸運を祈ります!

リモートスクリプトブロックが終了コードを返す場合、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

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

PowerShellスクリプトは $ res = invoke-command-コンピューター名%computer%{C:\ TEST \ BATCH.CMD} 書き込みホスト$ res $ resがバッチ出力であることがわかります。これは、@ echo off、&gt; nul、echo&quot; what you want to return&quot;を使用して知ることができます。可能です!

バッチスクリプト

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

これで$ resは= 2になります!その後、バッチ内の任意のロジックを適用できます。

invoke-command -AsJobを使用することもできます Receive-jobを使用して出力を取得します!この場合、$ 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