マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

リモートコンピューターでPowerShellのコマンドを実行する方法についてまとめる。

  • invoke-command マシン名やSessionを指定 -scriptblock { ・・・コード・・・ }
  • invoke-command マシン名やSessionを指定 -filepath ファイルパス

# Sessionを指定すれば処理中のジョブ等に再接続することも可能。

Workgroup編

Invoke-Command を使って、リモートでコマンド実行ができます。

  • ただし、事前に構成を変更しておく必要があります。
  • また、実行する要件によっては追加の構成が必要です。

リモート先でリモートコマンドを呼ばれる準備 (PowerShellを 管理者として実行)

1. PowerShellリモート処理を有効にする

Enable-PSRemoting

 Enable-PSRemoting は、PowerShellを使ってリモートからコマンド実行できるように、以下の様な構成変更をまとめて行います。

  • WinRM サービスを起動します。
  • WinRM サービスのスタートアップの種類を [自動] に設定します。
  • 任意の IP アドレスで要求を受け入れるためのリスナーを作成します。
  • WS-Management 通信のファイアウォール例外を有効にします。
  • "Microsoft.PowerShell" セッション構成がまだ登録されていない場合は登録します。
  • "Microsoft.PowerShell32" セッション構成が 64 ビット コンピューターでまだ登録されていない場合は登録します。
  • 登録済みのすべてのセッション構成のセキュリティ記述子から "Deny Everyone" 設定を削除します。
  • WinRM サービスを再起動して、変更を有効にします。

解放しすぎる場合は(任意のIPアドレスで..など)、範囲を調整する必要があるか、検討ください。
リモートから実行の可否を制御するには、ユーザーと権限(後述)、または、
ファイルウォール例外("Windows リモート管理 (HTTP 受信)")のスコープ設定で行います。

2. PowerShellリモート処理可能なユーザーと権限の設定

Set-PSSessionConfiguration Microsoft.Powershell -ShowSecurityDescriptorUI

 実行すると権限を設定する画面が表示されるので、リモートから指定するユーザーと権限を追加。
 (Administratorsメンバー以外のユーザーを使用する場合に必要)

リモートを呼び出す側の準備 (PowerShellを 管理者として実行)

1. WinRM サービスを開始

Start-Service WinRM

 WinRMサービスを開始していなければ実行します。

2. UACのリモート設定

Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 
    -Name LocalAccountTokenFilterPolicy -Value 1 -Type DWord
    (上は、行を折り返しています、1行のコマンドです。)

 管理者特権を維持するように設定変更します。
 これをしないと、下の wsman:localhost\client\trustedhosts の設定が出来ません。

3. 対象のコンピュータを 信頼されたホストの一覧に追加

set-item wsman:localhost\client\trustedhosts -value リモートコンピュータ名

 リモートコンピュータ名 が複数ある場合は、"リモートコンピュータ名,リモートコンピュータ名" の様に 文字列にして , で繋ぎます。
 依存の設定値に追加する場合は、get-item で値を確認し、 , で連結して設定します。

LocalAccountTokenFilterPolicy? と wsman:localhost\client\trustedhosts の関係について。

wsman:localhost\client\trustedhosts を設定するためには、以下の条件があります。

  • 管理者実行のコマンドプロンプト(PowerShell) で行う場合は、LocalAccountTokenFilterPolicy? を 1 にする
  • ビルトイン Administrator で行う場合は、 LocalAccountTokenFilterPolicy? の変更は不要
  • wsman:localhost\client\trustedhosts を設定した後は、LocalAccountTokenFilterPolicy? を 0 に戻しても構いません。
    (LocalAccountTokenFilterPolicy? を 0 に戻してもすぐには設定不可能に戻りません。その場合はWinRMサービスを再起動します。)

リモートでコマンドを実行

1. Invoke-Command を実行

Invoke-Command -ComputerName リモートコンピュータ名 -Credential (get-credential)
-ScriptBlock { リモートコマンド リモートコマンド引数... }
(上は、行を折り返しています、1行のコマンドです。)

 (get-credential) によって、ユーザー名を入力する画面が開きます。
 -Credential (get-credential) を指定しないと、Invoke-Command を実行しているユーザーで、リモートコンピュータへ接続し、コマンド実行されます。
 ユーザー名を入力したくない場合は、 get-credential を先に行って、変数に入れておくか、-Credential を指定しないようにします。

注意事項ほか

  • PowerShellでリモート実行するコマンドから、ファイル共有などのネットワーリソースへアクセスする際は、匿名ユーザーが使われます。
    リモートのコマンド実行の中からネットワークリソースへユーザー指定でアクセスする場合は、後述の ダブルホップ編 を参照するか、
    sysinternals の psexecツール を検討ください。( psexec は サービス・タスク系のいろいろ も参照ください。)
  • Invoke-Command は リモートとの通信用に http や https も使用できます。それらの構成方法、オプションなどは、各コマンドを get-help で確認ください。
    • また、リモートとの通信に proxy を使用することもできます。
    • 必要であれば netsh コマンドなどで winhttp の proxy を設定する、
      通信できない場合に winhttp proxy が原因になっていないか確認ください。
  • Credential を指定しない場合は、PowerShellを実行しているアカウントが使われます。
    • Get-Credential はパスワード入力のためにポップアップ画面を表示します。
      バックグラウンド処理など、画面表示をしたくない場合には、パスワードを事前に暗号化してファイルに保存しておくこともできます。
    • パスワードをファイルに保存する方法、ファイルから取り出して Credentialオブジェクトを作成する方法は、下のページを参考ください。
  • Invoke-Command -ComputerName? Server1,Server2,... の様に複数のサーバーを記述すると、それらのサーバーに対して同時実行します。
    実行結果は、PowerShellのオブジェクトとして、1つの配列に混合されて返ります。~(cmd.exeなどPowerShell でないコマンドを実行した場合は String(文字列) の配列になる。)
    オブジェクトにはPSComputerName?プロパティが付加されるので、サーバー別にソートしたり区別したいときはPSComputerName?で判断できます。
    同時ではなく、順に実行したい場合は、-ComputerName?に1つつず指定します。

Workgroup + ダブルホップ

上の Workgroup編では、リモートコマンドの中から、他サーバーのリソースにアクセスすると、匿名ユーザーが使用されますが、
下の手順の様に、ダブルホップを使用することで、

-credential で指定するものと同じアカウントで 他サーバーのリソースにアクセスすることができます。~

準備 (上の Workgroup編と共通)

  • リモート先でリモートコマンドを呼ばれる準備 (PowerShellを 管理者として実行)
     1. Enable-PSRemoting
    
     2. Set-PSSessionConfiguration Microsoft.Powershell -ShowSecurityDescriptorUI

  • リモートを呼び出す側の準備 (PowerShellを 管理者として実行)
     1. Start-Service WinRM
    
     2. Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 
        -Name LocalAccountTokenFilterPolicy -Value 1 -Type DWord
        (上は、行を折り返しています、1行のコマンドです。)
    
     3. set-item wsman:localhost\client\trustedhosts -value リモートコンピュータ名

ダブルホップのための 追加の準備

  • リモート先で資格情報を受け取る準備 (PowerShellを 管理者として実行)
     1. Enable-WSManCredSSP -Role Server

  • リモートを呼び出す側で、資格情報を送信する準備 (PowerShellを 管理者として実行)
     2. Enable-WSManCredSSP -Role Client -DelegateComputer リモートコンピュータ名

  • リモートを呼び出す側で、資格情報を NTLM 認証で行う様にグループポリシーを設定
     3. gpedit.msc コマンド
       コンピューターの構成 >> 管理用テンプレート >> システム >> 資格情報の委任
          NTLMのみのサーバー認証で新しい資格情報の委任を許可する
            (x) 有効
            サーバーを一覧に追加: [表示]
              wsman/リモートコンピュータ名

ダブルホップを使用した、リモートコマンドの実行

  • リモートでコマンドを実行
    4. Invoke-Command に -Authentication CredSSP を付けてを実行
    
    Invoke-Command -ComputerName リモートコンピュータ名 -Credential (get-credential) 
    -ScriptBlock { cmd.exe /c "dir \\リソースサーバー\ファイル共有" } -Authentication CredSSP
    (上は、行を折り返しています、1行のコマンドです。 -ScriptBlock { ... } の中は例です。)

注意事項ほか

  • -credential で指定する ユーザー について

    -credential で指定する ユーザーおよびパスワード は、リモートコンピュータ名 と リソースサーバー の両方に共通なものを作成しておきます。
    上の例で \\リソースサーバー\ファイル共有 の共有フォルダは、指定する ユーザー で参照権限を設定しておきます。
    リモートコンピュータ上のユーザーは、Administrators でなくてもかまいません。リモートコマンドの内容に応じて 権限を付加してください。


Tags: :シェル, :インフラストラクチャ, :Windows


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-02-13 (火) 13:29:42 (185d)