web-dev-qa-db-ja.com

PowershellのInvoke-Commandで呼び出されたScriptBlockの戻り値をキャプチャする方法

私の質問は this one と非常に似ていますが、Invoke-Commandを使用してScriptBlockのリターンコードをキャプチャしようとしていることを除いて(-FilePathオプションを使用できません)。ここに私のコードがあります:

Invoke-Command -computername $server {\\fileserver\script.cmd $args} -ArgumentList $args
exit $LASTEXITCODE

問題は、Invoke-Commandがscript.cmdの戻りコードをキャプチャしないため、失敗したかどうかを知る方法がないことです。 script.cmdが失敗したかどうかを知る必要があります。

New-PSSessionも使用してみました(リモートサーバーでscript.cmdのリターンコードを確認できます)が、呼び出し元のPowershellスクリプトにそれを返して失敗について実際に何もする方法が見つかりません。

29
Jay Spang
$remotesession = new-pssession -computername localhost
invoke-command -ScriptBlock { cmd /c exit 2} -Session $remotesession
$remotelastexitcode = invoke-command -ScriptBlock { $lastexitcode} -Session $remotesession
$remotelastexitcode # will return 2 in this example
  1. New-pssessionを使用して新しいセッションを作成します
  2. このセッションでscripblockを呼び出します
  3. このセッションからlastexitcodeを取得します
39
jon Z
$script = {
    # Call exe and combine all output streams so nothing is missed
    $output = ping badhostname *>&1

    # Save lastexitcode right after call to exe completes
    $exitCode = $LASTEXITCODE

    # Return the output and the exitcode using a hashtable
    New-Object -TypeName PSCustomObject -Property @{Host=$env:computername; Output=$output; ExitCode=$exitCode}
}

# Capture the results from the remote computers
$results = Invoke-Command -ComputerName Host1, Host2 -ScriptBlock $script

$results | select Host, Output, ExitCode | Format-List

ホスト:Host1
出力:Ping要求はホストbadhostnameを見つけることができませんでした。名前を確認してもう一度お試しください
ExitCode:1

ホスト:Host2
出力:Ping要求はホストbadhostnameを見つけることができませんでした。名前を確認して、もう一度試してください。
ExitCode:1

6

私は最近、この問題を解決するために別の方法を使用しています。リモートコンピューターで実行されているスクリプトからのさまざまな出力は配列です。

_$result = Invoke-Command -ComputerName SERVER01 -ScriptBlock {
   ping BADHOSTNAME
   $lastexitcode
}

exit $result | Select-Object -Last 1
_

_$result_変数には、ping出力メッセージと_$lastexitcode_の配列が含まれます。リモートスクリプトからの終了コードが最後に出力される場合、解析せずに完全な結果から取得できます。

終了コードの前に残りの出力を取得するには、次のようにします。
$result | Select-Object -First $(result.Count-1)

2

@jon Zの答えは良いですが、これはもっと簡単です:

$remotelastexitcode = invoke-command -computername localhost -ScriptBlock {
    cmd /c exit 2; $lastexitcode}

もちろん、コマンドが出力を生成する場合は、終了コードを取得するためにコマンドを抑制するか解析する必要があります。その場合、@ jon Zの回答の方が良い場合があります。

1
jimhark