PowerShell でリモート接続を行うには、リモート接続される側で接続を受け付けるようにしなければなりません。 リモートデスクトップでの設定と似たようなものです。具体的には PowerShell コンソールを管理者権限で起動して Enable-PSRemoting コマンドを実行して、リモートからの接続を許可します。
スポンサーリンク
Enable-PSRemoting コマンドでエラー
PS C:\Windows\system32> Enable-PSRemoting WinRM クイック構成 WinRM サービスによるこのコンピューターのリモート管理を有効にするコマンド "Set-WSManQuickConfig" を実行します。 これには、次の処理が含まれます: 1. WinRM サービスを開始または (既に開始されている場合は) 再起動します。 2. WinRM サービスのスタートアップの種類を自動に設定します。 3. どの IP アドレスでも要求を受け付けるリスナーを作成します。 4. WS-Management トラフィック用のファイアウォール例外を有効にします (HTTP のみ)。 続行しますか? [Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "Y"): Y WinRM は要求を受信するように更新されました。 WinRM サービスの種類を正しく変更できました。 WinRM サービスが開始されました。 ローカル ユーザーにリモートで管理権限を付与するよう LocalAccountTokenFilterPolicy を構成しました。 Set-WSManQuickConfig : アクセスが拒否されました。 発生場所 行:50 文字:33 + Set-WSManQuickConfig <<<< -force + CategoryInfo : InvalidOperation: (:) [Set-WSManQuickConfig]、InvalidOperationException + FullyQualifiedErrorId : WsManError,Microsoft.WSMan.Management.SetWSManQuickConfigCommand
いきなりエラー発生しました。原因は、ログインユーザーは administrator権限を持つユーザーであったが、パスワードに何も設定していないためでした。 そこで、ログインユーザーにパスワードを設定して、再度 Enable-PSRemoting コマンドを実行したところ、正常にコマンドが完了しました。
ローカルホストにリモート接続する
リモート接続のための事前準備が完了したので、とりあえず自分自身にリモート接続を行ってみます。 (自分自身に telnet するようなものです)
ここでは、Enter-PSSession コマンドを利用してリモートホストに接続することにします。他の接続方法としては、New-PSSession コマンドで リモートホストとのセッションを確立し、そのセッションに対してコマンドを打ち込む方法があります。
PS C:\Windows\system32> Enter-PSSession -ComputerName localhost [localhost]: PS C:\Users\masao\Documents>
上記のとおり、無事接続完了しました。これで、リモートホスト上でコマンドを実行することができるようになりました。
本当のリモートホストにリモート接続する
次に、ローカルホストではなく、本当のリモートホストに接続してみます。ここで、ローカルホストと同様に接続しても おそらくはエラーとなりあます。どうやら、リモートホストに接続するためには、接続する側のホストでもう少し設定が必要となるみたいです。
なお、ここで説明する接続方法は一例であり、環境によっては他の設定が必要となる場合もあるとおもいますので注意が必要です。 以下は、どちらもドメインへは入っていない端末間でのリモート接続の検証を行った結果です。
リモートホストを信頼する
まず、追加の設定としてリモート接続する側がリモート接続するホストを信頼ホストとして登録しておく必要があります。Set-Item コマンドで登録しますが、-Value オプションで * を指定しているのは、すべてのホストを信頼するという意味です。
PS C:\Windows\system32> Set-Item WSMan:\localhost\Client\TrustedHosts -Value * WinRM セキュリティの構成。 このコマンドは WinRM クライアントの TrustedHosts の一覧を変更します。TrustedHosts の一覧内にあるコンピューターは認証されない可能性があります。クライアントはこれらのコンピューターに資格情報を送信する可 能性があります。この一覧を変更しますか? [Y] はい(Y) [N] いいえ(N) [S] 中断(S) [?] ヘルプ (既定値は "Y"): Y
これで、準備が整いましたので接続してみます。リモート接続するには、Enter-PSSession コマンドで Credential オプションを指定して接続します。 なお、この方法では、パスワード入力用のダイアログが表示され、パスワードを入力する必要があります。
ComputerName オプションで、リモートホスト名を設定し、Credential オプションには [ ホスト名 ] \ [ administrator 権限を持つユーザー ] の形式で入力します。未検証ですが、ドメイン環境では ホスト名の部分にドメイン名を入力すればよいのではないかと思います。
PS C:\Users\masao> Enter-PSSession -ComputerName masao-pc -Credential masao-pc\masao [masao-pc]: PS C:\Users\masao\Documents>
パスワード入力ダイアログがでるもののこれでリモートマシンに接続できました。
接続時にパスワードを入力しないで接続する
Credential オプションを設定せずに、ComputerName オプションのみで接続することもできますが、以下の条件が必要です。
- リモート接続する側と、リモート接続される側に administrator 権限を持つ同一ユーザー(とパスワード)が作成されている必要がある
- リモート接続する側は、そのユーザーでログインしている必要がある
New-PSSession コマンドでリモート接続&コマンド実行
これまでの例では Enter-PSSession コマンドによる接続方法を確認しましたが、ここでは New-PSSession コマンドで セッションの生成、リモートホスト上でのコマンドの実行を行う方法を試してみます。また、接続時のパスワード入力を行わず スクリプト内で記述する方法についても併せて試しています。
PS C:\> $hostname = "masao-pc" # 接続先ホスト(環境に合わせて変更する) PS C:\> $username = "masao-pc\masao" # 接続ユーザー(環境に合わせて変更する) PS C:\> $passwd = "masao" # パスワード (環境に合わせて変更する) PS C:\> PS C:\> # セキュアストリングの作成(パスワードの暗号化) PS C:\> $sec_str = ConvertTo-SecureString $passwd -AsPlainText -Force PS C:\> PS C:\> # Credential オプションに指定するオブジェクトのインスタンス生成 PS C:\> $psc = New-Object System.Management.Automation.PsCredential($username, $sec_str) PS C:\> PS C:\> # New-PSSession コマンドによるセッションの生成 PS C:\> $sess = New-PSSession -ComputerName $hostname -Credential $psc PS C:\> Get-PSSession # セッションの確認 Id Name ComputerName State ConfigurationName Availability -- ---- ------------ ----- ----------------- ------------ 1 Session1 masao-pc Opened Microsoft.PowerShell Available PS C:\> # コマンドをリモートホスト上で実行する PS C:\> Invoke-Command -Session $sess -ScriptBlock {Get-ExecutionPolicy;} PSComputerName RunspaceId PSShowComputerName Value -------------- ---------- ------------------ ----- masao-pc 7e14da16-066c-4289-811d-af... True Restricted PS C:\> Remove-PSSession -Session $sess # セッションを削除 PS C:\> Get-PSSession # セッションの確認 PS C:\>
セッションの削除を行わないとセッションが残ったままになるので必ず削除する必要があるので注意が必要です。 以下には、リモート接続中にネットワークアダプタを無効にした場合の結果を参考までに記載しておきます。State が Broken になりました。
PS C:\> Get-PSSession # セッションの確認 Id Name ComputerName State ConfigurationName Availability -- ---- ------------ ----- ----------------- ------------ 2 Session2 masao-pc Broken Microsoft.PowerShell None
一度セッションが切断されると、ネットワークアダプタを有効にしてもセッションのステータスが元に戻るわけではないので 一度セッションを破棄し、セッションの再作成からやり直す必要があります。
参考
- MSDN – about_Remote_Troubleshooting
- MSDN – Enter-PSSession
- MSDN – New-PSSession