サーバ大量構築時のキモ ~PSexecによるWindows OSのリモート操作~

今までnvspbindの記事などで触れてきていたPSexecについて、今更ながら書いてみることにした。

さて、このPSexecとは一体どういったものなのか。

PSexecは、Windows用の管理ツールスイート『PStools』に含まれるプログラムの一つだ。
対象となるWindowsに対し、CUIでコマンドを実行させるというプログラムになる。

1.『PStools』スイートのダウンロード

『PStools』は、以下からダウンロードが出来る。

PsTools - TechNet - Microsoft

2.コマンドの構文

このPSexec、以下のような構文で使用する。

psexec.exe \\コンピュータ名 -u ユーザ名 -p パスワード <オプション> 実行させるプログラム

さて、使用出来るオプションを把握するため、実際に実行してみた。

C:\PSTools>PsExec.exe

PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

PsExec executes a program on a remote system, where remotely executed console
applications execute interactively.

Usage: psexec [\\computer[,computer2[,...] | @file]][-u user [-p psswd][-n s][-r
 servicename][-h][-l][-s|-e][-x][-i [session]][-c [-f|-v]][-w directory][-d][-<p
riority>][-a n,n,...] cmd [arguments]
     -a         Separate processors on which the application can run with
                commas where 1 is the lowest numbered CPU. For example,
                to run the application on CPU 2 and CPU 4, enter:
                "-a 2,4"
     -c         Copy the specified program to the remote system for
                execution. If you omit this option the application
                must be in the system path on the remote system.
     -d         Don't wait for process to terminate (non-interactive).
     -e         Does not load the specified account's profile.
     -f         Copy the specified program even if the file already
                exists on the remote system.
     -i         Run the program so that it interacts with the desktop of the
                specified session on the remote system. If no session is
                specified the process runs in the console session.
     -h         If the target system is Vista or higher, has the process
                run with the account's elevated token, if available.
     -l         Run process as limited user (strips the Administrators group
                and allows only privileges assigned to the Users group).
                On Windows Vista the process runs with Low Integrity.
     -n         Specifies timeout in seconds connecting to remote computers.
     -p         Specifies optional password for user name. If you omit this
                you will be prompted to enter a hidden password.
     -r         Specifies the name of the remote service to create or interact.
                with.
     -s         Run the remote process in the System account.
     -u         Specifies optional user name for login to remote
                computer.
     -v         Copy the specified file only if it has a higher version number
                or is newer on than the one on the remote system.
     -w         Set the working directory of the process (relative to
                remote computer).
     -x         Display the UI on the Winlogon secure desktop (local system
                only).
     -priority  Specifies -low, -belownormal, -abovenormal, -high or
                -realtime to run the process at a different priority. Use
                -background to run at low memory and I/O priority on Vista.
     computer   Direct PsExec to run the application on the remote
                computer or computers specified. If you omit the computer
                name PsExec runs the application on the local system,
                and if you specify a wildcard (\\*), PsExec runs the
                command on all computers in the current domain.
     @file      PsExec will execute the command on each of the computers listed
                in the file.
     cmd            Name of application to execute.
     arguments  Arguments to pass (note that file paths must be
                absolute paths on the target system).
     -accepteula This flag supresses the display of the license dialog.

You can enclose applications that have spaces in their name with
quotation marks e.g. psexec \\marklap "c:\long name app.exe".
Input is only passed to the remote system when you press the enter
key, and typing Ctrl-C terminates the remote process.

If you omit a user name the process will run in the context of your
account on the remote system, but will not have access to network
resources (because it is impersonating). Specify a valid user name
in the Domain\User syntax if the remote process requires access
to network resources or to run in a different account. Note that
the password and command is encrypted in transit to the remote system.

Error codes returned by PsExec are specific to the applications you
execute, not PsExec.

C:\PSTools>

さて、使用できるオプションについてはダウンロードしたページに日本語の情報がある。
以下にその内容を抜粋する。

使用法: psexec [\\<コンピューター>[,<コンピューター2>[,...] | @<ファイル>][-u <ユーザー> [-p <パスワード>]][-n s][-l][-s|-e][-x][-i [<セッション>]][-c [-f|-v]][-w <ディレクトリ>][-d][-<優先度>][-a n,n,... ] cmd [<引数>]
<コンピューター>   指定した 1 台以上のコンピューターでアプリケーションを実行するように指示します。コンピューター名を省略すると、PsExec ではローカル システムでアプリケーションを実行します。コンピューター名を「\\*」と指定した場合は、現在のドメイン内のすべてのコンピューターでアプリケーションを実行します。
@<ファイル> 指定したテキスト ファイルに記載されている各コンピューターでコマンドを実行するように指示します。
-a  アプリケーションの実行に使用できるプロセッサをコンマ区切りで記載します (一番小さな CPU 番号は 1 です)。たとえば、CPU 2 と CPU 4 でアプリケーションを実行する場合は「-a 2,4」と入力します。
-c  指定したプログラムを実行するために、リモート システムにコピーします。このオプションを省略する場合、アプリケーションはリモート システムのシステム パスに存在している必要があります。
-d  アプリケーションが終了するのを待ちません。このオプションは、非対話型のアプリケーションにのみ使用します。
-e  指定したアカウントのプロファイルを読み込みません。
-f  リモート システムにファイルが存在する場合も、指定したプログラムをコピーします。
-i  プログラムを実行して、リモート システムの指定したセッションのデスクトップと対話するようにします。セッションを指定しないと、プロセスはコンソール セッションで実行されます。
-l  (Administrators グループを削除して、Users グループに割り当てられている特権のみを許可する) 制限付きのユーザーとしてプロセスを実行します。Windows Vista では、プロセスは低い整合性で実行されます。
-n  リモート コンピューターへの接続のタイムアウトを秒単位で指定します。
-p  ユーザー名のパスワードを指定します (これはオプションです)。省略すると、隠しパスワードの入力を要求するメッセージが表示されます。
-s  System アカウントで、リモート プロセスを実行します。
-u  ログイン用のユーザー名をリモート コンピューターに指定します (これはオプションです)。
-v  指定したファイルのバージョン番号がリモート システムにあるファイルのバージョン番号よりも大きいか、新しい場合のみ、指定したファイルをコピーします。
-w  (リモート コンピューターから見た相対パスで) プロセスの作業ディレクトリを設定します。
-x  Winlogon デスクトップの UI を表示します (ローカル システムのみ)。
-<優先度>  -low、-belownormal、-abovenormal、-high、または -realtime を指定して、さまざまな優先度でプロセスを実行します。Windows Vista では、-background を使用してメモリと I/O の優先度が低い状態で実行します。
<プログラム> 実行するプログラム名です。
<引数>    渡す引数です (ファイル パスは、対象システムの絶対パスで指定する必要があります)。
ファイル パスに空白文字が含まれているアプリケーションは、"psexec \\marklap "c:\long name\app.exe" のように二重引用符で囲んで指定します。入力は、Enter キーを押したときに、リモート システムに渡されます。また、Ctrl キーを押しながら C キーを押すと、リモート プロセスが終了します。
ユーザー名を省略すると、リモート プロセスは、PsExec の実行に使用したのと同じアカウントで実行されます。ただし、リモート プロセスはアカウントを偽装しているので、リモート システムではネットワーク リソースへのアクセス権はありません。ユーザー名を指定すると、リモート プロセスは指定のアカウントで実行され、そのアカウントがアクセスできるネットワーク リソースにアクセスできます。パスワードは、クリア テキストでリモート システムに送信されることに注意してください。

例

私が書いた次の記事では、PsExec のしくみを解説し、使用法についてのヒントを提供しています。
http://windowsitpro.com/article/articleid/42919/psexec.html (英語)外部サイトへ
次のコマンドでは、\\marklap で対話型のコマンド プロンプトを起動します。
psexec \\marklap cmd
次のコマンドでは、/all スイッチを指定した状態で ipconfig をリモート システムで実行して、結果の出力をローカルで表示します。
psexec \\marklap ipconfig /all
次のコマンドでは、test.exe というプログラムをリモート システムにコピーし、対話的に実行します。
psexec \\marklap -c test.exe
次のコマンドでは、リモート システムに既にインストールされているプログラムがシステムのパスにない場合に、そのプログラムの完全なパスを指定します。
psexec \\marklap c:\bin\test.exe
次のコマンドでは、regedit を System アカウントで対話的に実行し、SAM キーと SECURITY キーの内容を表示します。
psexec -i -d -s c:\windows\regedit.exe
次のコマンドでは、Internet Explorer を、制限された特権を持つユーザーとして実行します。
psexec -l -d "c:\program files\internet explorer\iexplore.exe"

3.リモート側で使用するマシンの設定

さて、リモート側で使用するWindowsマシンは、デフォルトのままで使用出来るのか。
個人的な経験上、「Windows Server」系のOSであれば特に設定せずリモート操作が可能だった。
※Windows ファイアウォールでブロックする場合は、135/tcp、445/tcp、1025~65535/tcpの開放が必要。

問題はクライアント機、しかも64bitの場合だ。
64bitのクライアント系OSの場合、デフォルトのままではPSexecを使用すると、以下のようなエラーが出てリモート操作出来ない。

アクセスが拒否されました。

このエラーを解消するには、以下のコマンドを管理者権限で実行する。

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v "LocalAccountTokenFilterPolicy" /t REG_DWORD /d 1

これで対象のマシンをPSexecでリモート操作出来るようになった。

4.特に便利なオプション

個人的に、特に便利だと考えるオプションを以下に列挙する。

-c

ローカルにあるプログラムを、リモート先のコンピュータで実行させるオプション。
つまり、操作をする対象マシンにプログラムやバッチが無くても問題が無い。
一つのバッチを複数台のマシンで実行させて、実行結果をローカルにログとして出力、一括管理させることも出来る。

-d

プログラムの回答を待たない。
一括で複数台のマシンにプログラムを流す際に有用だ。

-i

対話型プログラムを、リモート操作を行っている対象マシン上で表示させる事ができる。