PowerShellには、リモートマシンに対してコマンドを実行するための仕組みが標準で備わっています。これを PowerShell Remoting(PSリモーティング)と呼び、内部的には WinRM(Windows Remote Management) プロトコルを使用しています。サーバー管理の自動化、複数マシンへの一括操作、リモート診断など、さまざまな場面で活用できます。
事前準備:WinRMの有効化
PowerShell Remotingを使用するには、接続先のマシンで WinRM を有効にしておく必要があります。管理者権限のPowerShellで以下を実行してください。
# 接続先マシン上で実行(管理者権限が必要)
Enable-PSRemoting -Force
# ファイアウォールのルールを有効化
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" -Enabled True
Enable-PSRemoting -Force を実行すると、WinRMサービスの開始・自動起動設定、リスナーの作成、ファイアウォールの例外追加が自動で行われます。ドメイン環境では、グループポリシーで一括展開することも可能です。
1. Invoke-Command(最も基本的な方法)
Invoke-Command は、リモートマシンに対してスクリプトブロック(コマンドのまとまり)を送り込んで実行するコマンドレットです。最も頻繁に使われる方法で、単発の操作からバッチ処理まで幅広く対応できます。
# 単一のリモートマシンでコマンドを実行
Invoke-Command -ComputerName "ServerName" -ScriptBlock { Get-Process }
# 認証情報を明示的に指定する場合
$cred = Get-Credential
Invoke-Command -ComputerName "ServerName" -Credential $cred -ScriptBlock { Get-Service }
# 複数のマシンに同時実行(並列処理)
Invoke-Command -ComputerName "Server1", "Server2", "Server3" -ScriptBlock { hostname }
複数マシンを指定した場合、PowerShellは並列でコマンドを送信します。結果には PSComputerName プロパティが付加されるため、どのマシンからの出力かを識別できます。
2. Enter-PSSession(対話型リモートセッション)
Enter-PSSession を使うと、リモートマシンの PowerShell プロンプトに「入り込む」ような感覚で対話的に操作できます。SSHでサーバーにログインするイメージに近く、1つのマシンを手動で調査・操作したいときに便利です。
# リモートセッションに入る(プロンプトが [ServerName]: PS C:\> に変わる)
Enter-PSSession -ComputerName "ServerName"
# リモート側でコマンドを実行
Get-EventLog -LogName System -Newest 5
# 終了してローカルに戻る
Exit-PSSession
セッション中はプロンプトが [ServerName]: PS C:\> のように変化し、リモートで操作していることが一目でわかります。スクリプトの自動化には向きませんが、トラブルシューティング時に重宝します。
3. New-PSSession(セッションの再利用)
同じリモートマシンに対して複数回コマンドを実行する場合、そのたびに接続を確立するのは非効率です。New-PSSession でセッションオブジェクトをあらかじめ作成しておくと、接続の再利用が可能になり、処理が高速化されます。
# セッションを作成して変数に保持
$session = New-PSSession -ComputerName "ServerName" -Credential $cred
# 同じセッションを使って複数のコマンドを実行
Invoke-Command -Session $session -ScriptBlock { Get-Process }
Invoke-Command -Session $session -ScriptBlock { Get-Service | Where-Object { $_.Status -eq "Running" } }
# 作業が終わったらセッションを明示的に閉じる
Remove-PSSession $session
セッションを閉じ忘れると、リモートマシン側にセッションが残り続けてリソースを消費します。Remove-PSSession での後片付けを習慣にしましょう。Get-PSSession で現在開いているセッション一覧を確認できます。
4. ローカル変数をリモートに渡す
スクリプトブロック内はリモートマシンのスコープで実行されるため、ローカルで定義した変数をそのまま使うことはできません。変数をリモートに渡す方法は2つあります。
$localVar = "C:\Logs"
# 方法①:-ArgumentList でパラメータとして渡す
Invoke-Command -ComputerName "ServerName" -ScriptBlock {
param($path)
Get-ChildItem $path
} -ArgumentList $localVar
# 方法②:$using: スコープを使う(より直感的)
Invoke-Command -ComputerName "ServerName" -ScriptBlock {
Get-ChildItem $using:localVar
}
$using: スコープ修飾子(PowerShell 3.0以降)を使う方法がよりシンプルで読みやすいため、現在はこちらが推奨されています。複数の変数を渡す場合も、それぞれに $using: を付けるだけで済みます。
5. SSH経由のリモート実行(クロスプラットフォーム)
PowerShell 6(PowerShell Core)以降では、WinRMだけでなく SSH経由 でのリモート接続もサポートされています。これにより、LinuxやmacOSなど、WinRM非対応の環境に対してもPowerShellからリモート操作が可能になりました。
# Linux/macOS サーバーへの接続(PowerShell 6以降)
Invoke-Command -HostName "user@linux-server" -ScriptBlock { uname -a }
# SSHセッションとして接続
Enter-PSSession -HostName "user@linux-server"
SSH経由を使うには、接続先に OpenSSH サーバー と PowerShell の両方がインストールされている必要があります。Windows Server 2019以降はOpenSSHがオプション機能として標準搭載されているため、混在環境でも導入しやすくなっています。
方法の使い分けまとめ
| 用途 | コマンド | 特徴 |
|---|---|---|
| スクリプトの一括実行 | Invoke-Command | 複数マシン・並列実行に最適 |
| 手動・対話的な操作 | Enter-PSSession | SSH感覚でリモートを操作 |
| 繰り返し接続の効率化 | New-PSSession | 接続コストを節約できる |
| Linux/macOS への接続 | SSH経由の Invoke-Command | クロスプラットフォーム対応 |
PowerShell Remotingを活用することで、数十台・数百台のサーバーに対して同じ操作を一度に実行できるようになります。インフラ管理の自動化において、非常に強力な武器になります。