一つ前のメモで、PsExec.exe を使用したリモートWindows PCのコマンドを実行する方法について書きました。このコマンドは、ドメインに参加しているPC同士で行う場合には便利ですが、PsExec は標準コマンドではありません。いろいろな背景から、できることなら Powershell で行ってしまいたい。
Powershell で同様のことを行うにはどう書けばいいか?
検索してみたら、Invoke-Command というのが見つかりました。
PsExecとコマンドと動く環境が違うだけで、基本的には相手ホストとアカウントを指定して、リモートコマンドを書くだけ。
Invoke-Command -ComputerName win10_01 -Credential $c {dir C:\users}
こんな感じでPowershell から{}にくるんでコマンドを発行すれば、実行出来るようです。(Workgroupの場合。)
ところが、、、、PsExec や Invoke-Command は、情報を盗んだり、リモート操作にも使えるため、がちがちにプロテクトされていました。Workgroup環境では動かすだけですごく大変でした。リモート管理を行う前提で運営されているドメインの方が、簡単かも。
私が使うと次のようにエラーが出てきて、実際にコマンドが通るようになるまでがすごく大変。
[win10_01] リモート サーバー win10_01 への接続に失敗し、次のエラー メッセージが返されました: WinRM クライアントは要求を処理できません。認証スキームが Kerberos と異なる場合、またはクライアント コンピューターがドメインに参加していない場合は、 HTTPS トランスポートを使用するか、または宛先 コンピューターが TrustedHosts 構成設定に追加されている必要があります。 TrustedHosts を構成する には winrm.cmd を使用します。TrustedHosts 一覧に含まれるコンピューターは認証されていない可能性が あります。 winrm help config コマンドを実行すると、詳細が表示されます。詳細については、 about_Remote_Troubleshooting のヘルプ トピックを参照してください。 + CategoryInfo : OpenError: (win10_01:String) [], PSRemotingTransportException + FullyQualifiedErrorId : ServerNotTrusted,PSSessionStateBroken
まず、コマンドを受けるPCでは、
- デフォルトではリモート管理が起動していません
- そして、ファイヤーウォールがリモート管理ポートを塞いでいます
- さらに、TrustedHosts 構成設定 がなされていません
ので、これらを双方のPCで許可するように設定しないといけません。
「powershell invoke-command windows10」でWeb検索してみると、いろいろ出て来ました。一番助かったのが、
https://www.vwnet.jp/Windows/PowerShell/InvokeCommand.htm
のサイト。Enter-PSSession と同じ設定が必要なんだそうです。(Enter-PSSessionって何よ?って思いながら)
https://www.vwnet.jp/Windows/PowerShell/EnterPSSession.htm
に書かれているコマンドを、管理者として起動したPowershell ISE環境でコマンドを実行したところ、「おっ、コマンドが通った!」と拍手が出ました。(半日悩んでましたからね。)
リモートコマンドを受け付けるPC:
Set-ExecutionPolicy RemoteSigned -Force Set-WSManQuickConfig -Force
リモートコマンドを発行するPC:
Set-ExecutionPolicy RemoteSigned -Force winrm quickconfig -force Set-Item WSMan:\localhost\Client\TrustedHosts * -Force
これが必要でした。手作業で、サービスを動かしたり、ファイヤーウォールに穴を空けたりするという手もありますが、コマンドに任せる方が楽で正確。
ディレクトリ: C:\users Mode LastWriteTime Length Name PSComputerName ---- ------------- ------ ---- -------------- d----- 2019/09/12 2:38 defaultuser0 win10_01 d-r--- 2019/08/23 22:17 Public win10_01 略
Users以下はフォルダーだけなので、同様のコマンドをc:\Windowsに対して行ってみたところ、以下のような結果に。
invoke-command -ComputerName win10_01 -Credential $c -ScriptBlock {dir c:/windows}
略 -a---- 2019/03/19 13:43 73216 bfsvc.exe win10_01 -a---- 2018/10/11 2:54 1198368 boinc.scr win10_01 -a--s- 2019/12/30 16:38 67584 bootstat.dat win10_01 -a---- 2019/08/23 22:44 32897 comsetup.log win10_01 -a---- 2018/05/09 16:56 3176 DDACLSys.log win10_01 -a---- 2019/08/23 22:45 15243 diagerr.xml win10_01 -a---- 2019/08/23 22:45 15243 diagwrn.xml win10_01 -a---- 2019/03/19 13:55 776 DtcInstall.log win10_01 -a---- 2019/11/13 6:19 4615616 explorer.exe win10_01 略
ちなみに、Powershellコマンド中の $c は get-credential の実行結果です。