“ invoke-command”でコマンドのリターンコードをキャッチする-Powershell 2
-
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"
}
これは、標準出力と最後の終了コードを返します。ただし、これにはスクリプトブロック内で例外をキャッチし、終了コードとして再スローする必要があります。例からの出力...
<*>