トップ回答者
Invoke-Commandを使用した、戻り値の取得方法について

質問
-
nishigunと申します。
未熟で申し訳ないですが、powershellのご質問をさせてください。■環境
端末:2台(端末A.端末Bとします)
OS:Windows2008 Server(R2 spなし 2台とも)
IP:端末A=192.168.1.2
IP:端末B=192.168.1.1
powershell: version:2.0
ミドル:端末Aにジョブ管理ソフトManagerあり。端末Bにはミドルウェアなし■ご質問
端末Aに導入されているジョブ管理ソフトからpowershell.exeを呼出し、
Invoke-Comanndで端末Bを経由して命令を実行するスクリプトを作成しようと思ってます。
まず、端末Aから端末Bにリモートログインして、サービス名の数を取得して、
問題なし⇒exit 0。問題あり⇒exit 255。
見たいな事を実施しようと考えております。問題点として、
スクリプトは作成できたのですが、端末B側のエラーコードを端末Aが取得できず困っております。
過去ログを参照して真似てみたのですがうまくいきません。スクリプトは下記の通りです。
ご存知であれば、どなたかご指導いただきたくおねがいいたします。■端末Aのスクリプト
[C:\PCA\PCA.ps1]
---------------------
invoke-command -ComputerName 192.168.1.1 -ScriptBlock{invoke-command -filepath $args[0] -computername 192.168.1.1 ;$lastexitcode} -argumentlist C:\PCB\PCB.ps1
---------------------■端末Bのスクリプト
[C:\PCB\PCB.ps1]
---------------------
#netstartでサービスを確認
$CMD = net start | Select-String "AAA" | measure-object|%{$_.count}#サービス数をチェック
if ($cmd -eq 3)
{
exit 0
}
else
{
exit 255
}
---------------------
回答
-
最終的にジョブ管理ソフトがpowershell.exeからの終了コードを受け取る必要があるということでしょうか。
それであれば以下のようにするとどうでしょうか?
■端末Aのスクリプト
[C:\PCA\PCA.ps1]
---------------------
$exitcode = invoke-command -ComputerName 192.168.1.1 -ScriptBlock{invoke-command -filepath $args[0] } -argumentlist C:\PCB\PCB.ps1exit $exitcode
---------------------
■端末Bのスクリプト
[C:\PCB\PCB.ps1]
---------------------
先ほどのと同じつまりは、まずPCA.ps1がリモートのPCB.ps1をキックし、その結果を$exitcodeに格納しています。
そして$exitcodeをPCA.ps1の終了コードとしています。
これでジョブ管理ソフトが直接呼び出すPCA.ps1が、終了コードを返すようになるかと思います。
- 回答としてマーク nisigun 2013年2月7日 0:53
すべての返信
-
シェル変数$lastexitcodeは直前に実行したWin32ネイティブアプリの終了コードを格納する変数です。
一方、Invoke-Command -FilePath PCB.ps1 -ComputerName 192.168.1.1 の意味するところは、192.168.1.1 に新しくPSセッション(この場合、同一コンピュータでの実行なのでループバックセッションとなる)を作成し、そこでPCB.ps1ファイルの中身を実行するということになります。
したがって、PCB.ps1内で終了コードを返しても、それを実行したループバックセッションはスクリプトの終了と同時に消滅するので、$lastexitcodeの値も消滅しています。
$lastexitcodeの値をどうしても呼び出し元から参照したいというのであれば別ですが、この場合、終了コードにこだわらずもっと簡単にしても良いのではないかと思います。
スクリプトの構成自体は手を入れないで呼び出し方だけを変えるなら、
■端末Aのスクリプト
[C:\PCA\PCA.ps1]
---------------------
invoke-command -ComputerName 192.168.1.1 -ScriptBlock{invoke-command -filepath $args[0] } -argumentlist C:\PCB\PCB.ps1
---------------------■端末Bのスクリプト
[C:\PCB\PCB.ps1]
---------------------
#netstartでサービスを確認
$CMD = net start | Select-String "AAA" | measure-object|%{$_.count}#サービス数をチェック
if ($cmd -eq 3)
{
0
}
else
{
255
}
---------------------たとえばこのようなものでも十分なのではないでしょうか。
-
-
最終的にジョブ管理ソフトがpowershell.exeからの終了コードを受け取る必要があるということでしょうか。
それであれば以下のようにするとどうでしょうか?
■端末Aのスクリプト
[C:\PCA\PCA.ps1]
---------------------
$exitcode = invoke-command -ComputerName 192.168.1.1 -ScriptBlock{invoke-command -filepath $args[0] } -argumentlist C:\PCB\PCB.ps1exit $exitcode
---------------------
■端末Bのスクリプト
[C:\PCB\PCB.ps1]
---------------------
先ほどのと同じつまりは、まずPCA.ps1がリモートのPCB.ps1をキックし、その結果を$exitcodeに格納しています。
そして$exitcodeをPCA.ps1の終了コードとしています。
これでジョブ管理ソフトが直接呼び出すPCA.ps1が、終了コードを返すようになるかと思います。
- 回答としてマーク nisigun 2013年2月7日 0:53