PowerShell で Windows Remote Management を使ってみたのでメモ書きを。
表題にある Windows Remote Management(WinRM) というのは、Windows を遠隔で操作する仕組みのことです。
遠隔で操作するなら以前からリモートデスクトップがあるんですが、WinRM はコマンドで操作ができます。Linux で言うところの ssh な感じになります。これができると、多数のサーバで同じ操作を繰り返すような作業をバッチ処理として自動化することができます。
WinRM を使う準備
WinRM は Windows Server 2012 以降ならデフォルトで有効(デフォルトではポート 5985 で待ち受けています)になっているのでサーバ側での設定は不要です。ただ、ファイアウォールを有効にしてやる必要はあるかもしれないので、確認方法を。この辺は無理に PowerShell でやる必要は無いです。普通に「強化されたWindowsファイアウォール」で見たほうが良いです。
WINRM-HTTP-In-TCP-Public というルールもありましたが localsubnet のみ許可されているようなので見なかったことにします。コマンドで見ると気づけない。
PS > # ファイアウォールのルールの確認
PS > Get-NetFirewallRule -Name WINRM-HTTP-In-TCP
Name : WINRM-HTTP-In-TCP
DisplayName : Windows Remote Management (HTTP-In)
Description : Inbound rule for Windows Remote Management via WS-Management. [TCP 5985]
DisplayGroup : Windows Remote Management
Group : @FirewallAPI.dll,-30267
Enabled : True
Profile : Domain, Private
Platform : {}
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
PS > # 必要に応じて Profile を Any に変更
PS > Get-NetFirewallRule -Name WINRM-HTTP-In-TCP | Set-NetFirewallRule -Profile Any -PassThru
Name : WINRM-HTTP-In-TCP
DisplayName : Windows Remote Management (HTTP-In)
Description : Inbound rule for Windows Remote Management via WS-Management. [TCP 5985]
DisplayGroup : Windows Remote Management
Group : @FirewallAPI.dll,-30267
Enabled : True
Profile : Any
Platform : {}
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
一方、非ドメイン環境の場合、クライアント側では以下の設定が必要です。もし WinRM が無効になっていたら失敗しますので、管理者権限で PowerShell を起動し Enable-PSRemoting
で有効にしておきます。
PS > # 信頼済みホストの一覧を取得する
PS > Get-Item WSMan:\localhost\client\trustedhosts
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String TrustedHosts
PS > # 全てのホストを信頼済みにする(少々乱暴)。
PS > # もし個別に設定したければカンマで区切ったホスト名(文字列)を指定します。
PS > Set-Item WSMan:\localhost\client\trustedhosts -Value '*' -PassThru
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String TrustedHosts *
補足です。WSMan とは Web Service for Management という標準化された仕様です。名前の通り HTTP をシステム管理に使おうというものです。WinRM は WSMan の Microsoft 実装とのこと。
WinRM で接続する
とりあえず以下のような感じで接続できます。
PS > $cred = Get-Credential -UserName Administrator -Message "Test1のパスワード"
PS > $host = "Test1.hogehoge.com"
PS > Enter-PSSession -ComputerName $host -Credential $cred
[Test1.hogehoge.com]: PS C:\Users\Administrator\Documents> $Env:ComputerName
Test1
ただ、普通にログインしてしまっては意味が無いので、以下のようにバックグラウンドジョブとしてコマンドを実行してやります。
PS > $session = New-PSSession -ComputerName $host -Credential $cred
PS > Invoke-Command -Session $session -ScriptBlock { $Env:ComputerName } -AsJob
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
5 Job5 RemoteJob Running True Test1.hogehoge.com $Env:Computername
PS > Get-Job -State Complete | Receive-Job
Test1
複数ホストで並列処理するとき
認証情報とホスト名を CSV とかに列挙しておくなら以下のような感じに。
PS > Import-CSV .\host_username_passwd.csv | % {
# Get-Credential では必ずプロンプトが表示されてしまうので New-Object で認証情報を生成しています。
$SecurePassword = $_.Password | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $_.UserName, $SecurePassword
# 後は好きなだけジョブを実行
$session = New-PSSession -ComputerName $_.Host -Credential $cred
Invoke-Command -Session $session -ScriptBlock { ... } -AsJob
} | wait-job # State Completed した順番に表示される
PS > # Get-Job | % { $_ | Receive-Job -Keep | Out-File -FilePath $_.location } などで結果を受とる
PS > # Get-PSSession | Remove-PSSession でセッションをまとめて閉じる
これ認証に失敗したらどうなるんですかね?