1. ホーム
  2. スクリプト・コラム
  3. パワーシェル

PowerShellリモートタスクの実行手順

2022-01-04 23:49:23

LinuxではSSHを使用して様々なリモート操作を行うことができますが、Windowsプラットフォームでも同様にPowerShellを使用して同様の機能を得ることができます。この記事では、PowerShellを使用してリモート操作を実行するための基本的な情報をカバーします。SSHによるリモート操作について学びたい方は、以下のサイトを参照してください。 SSHリモート実行タスク

ベース

MSはWS-Managementと呼ばれるプロトコルを定義しており、コンピュータ機器からの管理データの遠隔交換のための公共規格を提供しています。Windowsプラットフォームでは、MSはWindowsリモート管理サービス(WinRM)を通じてWS-Managementプロトコルを実装しています。PowerShellはWinRMサービスを通じてこれを行うため、PowerShellでリモート操作を行うための基礎となるものである。

WinRMサービスの確認

以下のコマンドで、WinRMサービスの状態を確認することができます。

Get-Service WinRM

WinRMサービスは、Server EditionのWindowsシステムではデフォルトで起動されますが、Regular Editionのシステムではデフォルトでは起動されません。次に、このサービスを正しい位置で開始する方法について説明します。

リモートコマンドを受け付けるようにシステムを設定する

SSHクライアント/サーバー・アーキテクチャと同様に、リモート・コマンドを受け入れるホスト上でWinRMサービスを設定するだけです。これは、SSHデーモンと同じように、WinRMサービスをポートでリッスンさせるだけのことです。

PowerShellを管理者権限で起動し、以下のコマンドを実行します。

Enable-PSRemoting -Force

次に、WinRMサービスが稼働していることを確認します。

あるいは

ファイアウォールのルールも変更されました。

Enable-PSRemotingコマンドは、WinRMサービスを開始するだけでなく、ファイアウォールのルールも設定します。

お使いのコンピュータがすでにドメインに参加している場合は、上記の設定で十分です。ドメインに参加していないコンピュータの場合は、信頼設定を行い、WinRMサービスを再起動する必要があります。

Set-Item wsman:\localhost\client\trustedhosts *
Restart-Service WinRM

リモート接続のテスト

PowerShellには、リモートホストでリモート操作サービスが有効になっているかどうかをテストするコマンドも用意されています。

Test-WsMan xxx.xxx.xxx.xxx

上図のコマンドは正常に返され、リモートアクセスを許可するサービスがリモートホスト上に設定されたことを示します。エラーメッセージが返された場合は、リモートホストにリモートアクセスのためのサービスがオンになっていないことを示します。

リモート接続セッションの作成

この方法は、SSHリモート接続と似ています。SSHクライアントを使ってサーバーとの接続(セッション)を確立し、様々な操作を行うのです。これはSSHの最も基本的な使い方で、PowerShellでも同様のことができるようなサポートが提供されています。

Enter-PSSession -ComputerName my-svr -Credential nickli

パスワードを入力すると、接続が確立されます。

次に、リモートホストでタスクを実行することができます!

リモートで1つのコマンドを実行する

リモートホストと確立したセッションでタスクを実行できることは、素晴らしいスタートです。しかし、単に1つのコマンドを実行したり、スクリプトでそのようなコマンドを実行したりする必要がある場合はどうでしょうか。
Invoke-Commandコマンドの-ScriptBlockパラメータを指定することで、これを実現できます。

コピーコード コードは以下の通りです。

/{br Invoke-Command -ComputerName cd-lsr-svr -ScriptBlock { Get-Service WinRM } -credential nickli

上記のコマンドを実行し、ユーザーのパスワードを入力してください。

このコマンドは実行されますが、欠点は明らかで、ユーザーがパスワードを入力する必要があるため、自動化のためのスクリプトに書き込むことができません。

を使用して、パスワードをコマンドに書き込む(自動化できるようにする)。

$Username = 'xxxx'
$Password = 'yyyy'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Invoke-Command -ComputerName cd-lsr-svr -ScriptBlock { Get-Service WinRM } -credential $Cred

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

例えば、後のコマンドで前のコマンドの結果を使用するなど、関連する複数のコマンドを連続して実行する必要がある場合があります。このような場合、上記の方法は使えません。コマンド間の接続を処理するために、セッションを使用する必要があります。

Invoke-Command -ComputerName myserver -ScriptBlock {$p = Get-Process PowerShell}
Invoke-Command -ComputerName myserver -ScriptBlock {$p.VirtualMemorySize}

$s = New-PSSession -ComputerName myserver
Invoke-Command -Session $s -ScriptBlock {$p = Get-Process PowerShell}
Invoke-Command -Session $s -ScriptBlock {$p.VirtualMemorySize}


最初の2つのコマンドを直接実行すると、2番目のコマンドの$pには値がないので、結果を得ることはできません。最後の2行のコマンドは同じセッションを通して実行されるので、変数を共有することができ、最終的に結果を得ることができます。

リモートでスクリプトを実行する

リモート実行コマンドの操作方法を紹介した後は、リモート実行スクリプトを紹介する方がずっと簡単です。実は、これが自動化の仕組みの核となる部分です。

Invoke-Command -ComputerName cm-12r2 -FilePath . \task.ps1

task.ps1内にtest.txtを作成し、このファイルにPowerShellのバージョン情報を追加しました。上記のコマンドを実行します。

次に、リモートマシンで、作成されたファイルがあるかどうかを確認します。

すべてが素晴らしく見えますが、実際のスクリプトはもっと複雑です。

複数のマシンで同じ操作を行う

複数のホストで同時に同じ操作を行うと、効率が飛躍的に向上しますが、これは以下のようにすることでリモートで行うことができます。

上の図のコマンドは、2つのリモートホストで同時に実行され、実際にはComputerName属性に複数のターゲットを指定しているだけなのです!

繰り返し:本当の力は、スクリプトファイルの実行です。

今回は、2つのリモートホストでスクリプトファイルtask.ps1を同時に実行しました。

対象ホストが多数ある場合は、ファイルに書いて、で参照することも可能です。

Invoke-Command -ComputerName (Get-Content Machines.txt)

リモートコピーファイル

ついにPowerShellがバージョン5.xでリモートファイルコピーに対応しました! まずはデモをご覧ください。

$mySession = new-PSSession -ComputerName xxxxxx
Copy-Item -Path . \task.ps1 -Destination C:\task.ps1 -ToSession $mySession

上記のコマンドは、task.ps1ファイルをローカルのカレントディレクトリからリモートホストxxxxxxのCドライブのルートディレクトリにコピーします。Copy-Item コマンドは、ToSession という名前の Session オブジェクトを引数として使用し、ファイル転送の方向がこの引数によって決定されることに注意してください:ToSession を使用するとローカルファイルをリモートホストに転送し、FromSession を使用するとファイルをリモートホストからローカルマシンに転送します。.

ディレクトリを丸ごとコピーする方法をもう一度見てみましょう。

$mySession = new-PSSession -ComputerName xxxxxx
Copy-Item -Path . \PowerShell -Destination C:\PowerShell -ToSession $mySession -Recurse

ディレクトリコピー操作にRecurseパラメータが追加されていることに注意してください。

上記の2つの操作は、ファイルとディレクトリをリモートホストにコピーするもので、リモートホストからローカルマシンにファイルまたはフォルダをコピーしたいと思います。

$mySession = new-PSSession -ComputerName xxxxxx
Copy-Item -Path C:\task.ps1 -Destination F:\temp\task.ps1 -FromSession $mySession
Copy-Item -Path C:\PowerShell -Destination F:\temp -FromSession $mySession -Recurse

ここで使われているパラメーターはFromSessionなので、コマンドのDestinationにはローカルパスが指定されていることに注意してください。上記のコマンドを実行して、ローカルの F:\temp ディレクトリにコンテンツがコピーされているかどうかを確認してください。

概要

この記事では、PowerShellによるリモート操作の基礎と、一般的な使い方を簡単に紹介しました。一般的な操作としては、基本的にSSHと同様です。なお、リモートコピーコマンドは最新版のPowerShellでしか対応していないので、使用する際は自分の環境のPowerShellのバージョンを確認するようにしましょう。

今回の内容は以上ですが、学習の一助となり、スクリプトハウスをより支持していただけると幸いです。