Windows Server
 Computer >> コンピューター >  >> システム >> Windows Server

PowerShellのInvoke-Commandを使ってリモートコンピューターでスクリプトを実行する方法

この記事では、Invoke-Commandコマンドレットを使用して、PowerShellのコマンドやスクリプトをリモートで実行する方法を解説します。PowerShellを使えば、ネットワーク上の1台または複数のコンピューターに対してコマンドをリモート実行できます。Invoke-Commandコマンドレットは、PowerShell Remotingのリモート管理機能を利用しています。PowerShell Remotingでは、WinRM(Windows Remote Management)サービスとWS-Management(WS-MAN)プロトコルを介して、リモートコンピューター上のPowerShellセッションに接続できます。これにより、リモートPowerShellセッションを確立し、任意のコードを実行することが可能になります。

PowerShell RemotingのためのWinRM設定

PowerShell Remotingは、コンピューター間の通信にHTTP(TCP/5985ポート)またはHTTPS(TCP/5986ポート)を使用します。デフォルトではHTTPが使われますが、通信自体は暗号化されています(ただし、中間者攻撃の脅威は完全には排除されません)。認証にはKerberosまたはNTLMが使用されます。

接続先のリモートコンピューターでは、WinRMサービスが稼働している必要があります。まず、WinRMサービスの状態を確認しましょう。

Get-Service -Name "*WinRM*" | fl

サービスが停止している場合は、以下のコマンドで有効化します。

Enable-PSRemoting

WinRM has been updated to receive requests.
WinRM service started.
WinRM is already set up for remote management on this computer.

このコマンドは、WinRMサービスの起動(自動起動への設定を含む)、既定のWinRM設定の適用、Windowsファイアウォールへの例外ルールの追加を行います。Enable-PSRemoting -Forceとすると、ユーザーへの確認なしでWinRMを有効化できます。

これで、PowerShell Remotingを使ってリモートコンピューターへ接続できるようになります。

なお、ネットワークの種類がパブリック(Public)に設定されている場合、PowerShell Remotingはデフォルトでは動作しません。その場合、次のようなエラーが返されます。

Set-WSManQuickConfig : ... WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.

ネットワークの場所を「プライベート」に変更するか、次のコマンドを使用してください。

Enable-PSRemoting -SkipNetworkProfileCheck

さらに、パブリックネットワークでWinRMへのアクセスを許可するWindows Defenderファイアウォールの規則も有効にします。ファイアウォール規則はGPOまたはPowerShellで有効化できます。

Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any

PowerShell Remoting経由でリモートコンピューターへの接続をテストするには、次のコマンドを実行します。

Test-WsMan compname1

Active Directoryドメインがない環境や、IPアドレスでPowerShell Remoting経由でアクセスする場合は、NTLMプロトコルによる認証が使用されます。NTLM使用時にInvoke-Commandを実行すると、次のようなエラーが表示されることがあります。

[192.168.1.201] Connecting to remote server 192.168.1.102 failed with the following error message: The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions: the transport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided...

接続元のコンピューターでNTLM認証を正しく機能させるには、WinRM用のSSL証明書を発行するか、信頼されたホスト(TrustedHosts)リストにホスト名/IPアドレスを追加します。

Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201

すべてのコンピューターへの接続を許可することもできますが、NTLMは相互認証をサポートしないという弱点があるため、推奨されません。

Set-Item wsman:\localhost\Client\TrustedHosts -value *

同じ設定をリモートホスト側にも適用する必要がある点に注意してください。

信頼されたホストのリストを表示するには、次のコマンドを実行します。

Get-Item WSMan:\localhost\Client\TrustedHosts

変更を適用するために、WinRMサービスを再起動します。

Restart-Service WinRM

なお、WinRMはグループポリシー(GPO)を使って一括で有効化・構成することもできます。

Invoke-CommandでPowerShellコマンドをリモート実行する方法

Invoke-Commandコマンドレットを使うと、1台または複数のリモートコンピューター上でコマンドを実行できます。

例えば、リモートコンピューターで単一のコマンドを実行するには、以下のようにします。

Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}

このコマンドは、-ComputerNameパラメーターで指定したリモートコンピューターにインストールされているPowerShellのバージョンを表示します。リモートで実行したいコマンドは、-ScriptBlock {[コマンドレット]}ブロック内に記述します。

デフォルトでは、Invoke-Commandで送信されたコマンドは、リモートコンピューター上で現在のユーザーとして実行されます。別のユーザーとして実行したい場合は、資格情報を取得して変数に保存します。

$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}

このPowerShellコマンドは、リモートコンピューターのネットワークインターフェースの一覧を表示します。

ScriptBlockには、セミコロンで区切ることで複数のコマンドを記述できます。例えば、次のコマンドは現在のタイムゾーンを表示した後、別のタイムゾーンに変更します。

Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time"}

Invoke-Commandでは、個々のコマンドだけでなくPowerShellスクリプト(.ps1ファイル)も実行できます。その場合は、-ScriptBlockの代わりに-FilePath引数を使用します。指定するのは手元のコンピューター上にあるローカルスクリプトのパスなので、スクリプトファイルをターゲットのリモートコンピューターにコピーしておく必要はありません。

Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1

Invoke-Commandで複数のコンピューターに同時にコマンドを実行する方法

Invoke-Commandを使うと、複数のリモートコンピューターに対して並列(同時)にコマンドを実行できます。

最もシンプルなケースでは、コマンドを実行するコンピューター名をカンマで区切って指定します。

Invoke-Command server1, server2, server3 -ScriptBlock {get-date}

コンピューターのリストを変数(配列)に入れることもできます。

$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers

テキストファイルからコンピューター名を読み込むことも可能です。

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.txt)

さらに、AD PowerShellモジュールのGet-ADComputerコマンドレットを使えば、Active Directoryからコンピューターのリストを動的に取得できます。ドメイン内のすべてのWindows Serverホストでコマンドを実行するには、次のPowerShellコードを使用します。

$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue

一部のコンピューターが電源オフや到達不能な状態でも、SilentlyContinueパラメーターによりスクリプトは停止せず、他のコンピューターでの処理を続行します。

実行結果がどのコンピューターからのものかを確認するには、PSComputerName変数を使用します。

$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime

Invoke-Commandで複数のコンピューターに対してコマンドを実行する場合、それらは同時に実行されます。ただし、Invoke-Commandには同時に管理できるコンピューターの最大数(同時PSSession数)に制限があり、この制限はThrottleLimitパラメーターで制御されます(デフォルト値は32)。32台以上(例えば128台)のコンピューターでコマンドを実行したい場合は、-ThrottleLimit 128のように指定します。ただし、多数のPSSessionを確立するため、実行元コンピューターへの負荷が高くなる点に注意してください。

また、Invoke-Commandでリモートコンピューター上のコマンドをバックグラウンドジョブとして実行するには、特別なパラメーター-AsJobを使用します。この場合、コマンドの結果は即座にコンソールへ返されません。結果を取得するには、Receive-Jobコマンドレットを使用します。

  1. PowerShellを使ってWindows 10パソコンをリモートで再起動する6つの方法

    システム管理者をはじめ、サーバーやPCの再起動が必要になる場面は少なくありません。通常はGUI(グラフィカルユーザーインターフェース)からリモートシャットダウンや再起動を行うことができますが、PowerShellを使えば、より柔軟かつ効率的にリモートコンピューターを再起動できます。本記事では、PowerShellを活用してWindows 10マシンをリモート再起動する6つの方法を詳しく解説します。 PowerShellでWindows 10をリモート再起動する手順 これらの方法を実行するための前提条件として、リモートシステムに接続でき、必要な認証が行えることを確認してください。また、対象のリモ

  2. ユーザーのログオン・ログオフ、PCの起動・シャットダウン時にPowerShellスクリプトを優先的に実行する方法

    ユーザーのログオン・ログオフ時や、コンピューターの起動・シャットダウン時にWindows PowerShellスクリプトを最初に実行したい場合は、以下の手順に従って設定を行いましょう。「ローカルグループポリシーエディター」または「レジストリエディター」を使用することで、PowerShell以外のスクリプトよりも先にPowerShellスクリプトが実行されるよう優先順位を変更できます。 ユーザーがログオンしたりコンピューターを起動したりすると、登録されているすべてのスクリプトは同時に実行されます。そのため、システムの起動や特定のプログラムの実行に遅延が発生することがあります。こうした問題を避ける