実世界の例を交えたPsexecの詳細ガイド

もし、robocopyと同じくらい有用なコマンドラインユーティリティがあったとしたら、それはPsExecです。SysinternalsのPsExecユーティリティは、IT管理者のアーセナルに欠かせない存在です。このツールは、管理者がローカルコンピュータ上にいるかのようにリモートでコマンドを実行することができます。

PsExecツールを詳しく説明するために、この貴重なツールをATA究極ガイドで取り上げることがふさわしかったです。このガイドでは、psexecとは何か、どのような機能を持っているか、そしてこの便利なツールの使用例を多数紹介します。

PsExec.exeとは何ですか?

ITに初めて触れる方や、リモートコンピュータ上でコマンドやツールを実行する必要がなかった方は、psexecが何かを知らないかもしれません。

PsExecまたはpsexec.exeは、Windows向けのコマンドラインユーティリティです。管理者はこれを使用して、ローカルコンピュータや一般的にはリモートコンピュータ上でプログラムを実行することができます。これは、以前Mark Russinovichによって作成されたSysinternals pstoolsスイートの一部である無料のユーティリティです。

このツールは、ポートを開放しセキュリティの脆弱性を引き起こすtelnetのようなツールを置き換えるために作成されました。現在では、PowerShellリモーティングやInvoke-Command PowerShellコマンドレットなど他のオプションがありますが、PsExecにはまだその場所があります。

PsExecは、ソフトウェアをインストールすることなくコンソールアプリケーションの完全な対話機能を提供します。この究極のガイドを通じてご覧の通り、PsExecは対話型のコマンドプロンプトを起動し、リモートコンピュータ上でローカルシステムとして実行し、複数のコンピュータでコマンドを一度に実行することができます。

Windows XP以降のすべてのバージョンをサポートしています。つまり、Windows 10上でもPsExecが利用できるということです。ほとんどの環境で動作するシンプルなツールですが、そのシンプルさと機能を混同しないでください!

前提条件

PsExecをローカルコンピュータで実行するには、最新のWindowsオペレーティングシステムを実行している必要があります。ただし、リモートコンピュータに対してpsexecを実行するには、いくつかの条件を満たす必要があります。

これらの条件がすでに整っていない場合や、自信がない場合は心配しないでください。次のセクションでは、リモートコンピュータをテストするためのPowerShellの書き方について説明します。

  • A modern Windows computer (local)
  • ファイルおよびプリンタ共有(リモートコンピュータ、TCPポート445)がオープンしている
  • admin$ 管理共有が利用可能(リモートコンピュータ)
  • ローカルアカウントの資格情報を知っている(リモートコンピュータ)

この記事の執筆時点では、PsExecはv2.2であり、この記事で学ぶバージョンです。

PSexecのインストール(リモートコンピュータのセットアップを伴う)

技術的には、PsExecをインストールする必要はありません。単なるコマンドラインユーティリティですが、ほぼ同じです。インストールは不要で、単にPsToolsのZIPファイルからダウンロードして展開する必要があります。PsExecは単体のユーティリティとして提供されておらず、PsToolsスイートの一部です。

PSExecのダウンロード

ZIPファイルを手動で展開するか、便利なPowerShellスニペットを使用して、PsExecをpstoolsのZIPファイルからダウンロードして展開することができます。なお、これにより他のPsToolsツールがすべて削除されます。多くのツールが便利ですが、この記事ではそれらについては説明しません。

PS> Invoke-WebRequest -Uri 'https://download.sysinternals.com/files/PSTools.zip' -OutFile 'pstools.zip'
PS> Expand-Archive -Path 'pstools.zip' -DestinationPath "$env:TEMP\pstools"
PS> Move-Item -Path "$env:TEMP\pstools\psexec.exe" .
PS> Remove-Item -Path "$env:TEMP\pstools" -Recurse

リモートコンピュータの設定

PsExecをダウンロードしたら、実行するリモートコンピュータがオープンであることを確認する必要があります。PsExecには単純な要件があります。有効になっている「ファイルとプリンタの共有」と「admin$」の管理共有が利用可能であることです。

リモートコンピュータすべてにアクセスし、Windowsファイアウォールのアプレットを開き、以下のようにすべてのコンピュータで「ファイルとプリンタの共有」を有効にすることができます。

なお、「ファイルとプリンタの共有」は既知のセキュリティリスクですので、プライベートファイアウォールプロファイルのみを有効にしてください。

Allowing File and Print Sharing in the Windows Firewall

また、各コンピュータを訪れ、netshユーティリティを使用して次のように開くこともできます:

> netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes

または、PowerShellのSet-NetFirewallRuleコマンドレットを使用することもできます。

PS51> Set-NetFirewallRule -DisplayGroup "File And Printer Sharing" -Enabled True -Profile Private

各コンピュータを訪問することを避けたい場合、PowerShellリモーティングを使用して、Active Directoryドメインにいる場合は、Invoke-Commandコマンドレットを使用して一度に複数のコンピュータのファイアウォールを開くこともできます。

PS51> Invoke-Command -ComputerName PC1, PC2, PC3 -ScriptBlock { Set-NetFirewallRule -DisplayGroup "File And Printer Sharing" -Enabled True -Profile Private }

PsExecを使用する

実行する前に歩行する必要があります。PsExecを使用したことがない場合は、まずこのセクションを読んで基本を学び、この記事の後半で深いところに飛び込む前に基礎を固めてください。

新しいシステムで初めてPsExecを実行すると、PsExecのライセンス契約が表示されます。使用を開始するには、同意ボタンをクリックする必要があります。

PSExec license agreement (EULA)

ライセンス契約の表示を防止するには、以下に示すように/accepteulaスイッチを使用して黙って受け入れることができます。

> psexec /accepteula

このEULAポップアップをローカルおよびリモートコンピュータで無音化するいくつかのトリックを後の記事で学びます。

ヘルプの検索

PsExecを探索する際には、どのスイッチも使用しないでください。スイッチなしでpsexecを単純に実行すると、すべてのオプションとそれぞれの簡単な説明が返されます。すべてのオプションは以下の表に便利な形で示されています。

Switch Explanation
-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. Some have reported best results always using the -s switch with -i due to windows being unintelligible.
-h If the target system is Vista or higher, has the proc
-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 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
-x Display the UI on the Winlogon secure desktop (local system only).
-arm Specifies the remote computer is of ARM architecture.
-priority Specifies -low, -belownormal, -abovenormal, -high or
-realtime run the process at a different priority. Use
-background run at low memory and I/O priority on Vista.
computer Direct PsExec to run the application on the 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
@file PsExec will execute the command on each of the computers listed in the file.
-accepteula This flag suppresses the display of the license dialog.
-nobanner Do not display the startup banner and copyright message.

単純なリモートコマンドの実行

PsExecは、最も基本的には2つのパラメータが必要です:コンピュータ名と実行するコマンドです。もしリモートコンピュータ上で引数を必要としないコマンド(hostnameなど)を実行したい場合は、単純にコンピュータ名の後に追加するだけです。

なお、完全なファイルパスを指定しない場合、実行するコマンドはユーザーまたはシステムのパスにある必要があります。また、名前にスペースが含まれるプログラムがある場合は、常にスペースでプログラムを囲むことができます(「my application.exe」のように)。

> psexec \\REMOTECOMPUTER hostname

以下の例では、hostnameコマンドをCONTOSODC1コンピュータで実行するために、UNCパスとコマンドを定義しています。PsExecはリモートコンピュータに安全に接続し、コマンドを実行して結果を返します。この場合、hostnameコマンドはコンピュータのホスト名であるCONTOSODC1を返しました。

もしコマンドがcmdや他のコンソールでない場合、PsExecはすばやくリモートセッションを終了し、リモートプロセスが返した終了コードを返します。

注意:Psexecから返されるエラーまたは終了コードは、Psexec自体からではなく、リモートコンピュータ上で実行されたコマンドから返されます。

Successful psexec remote command execution

Psexecのリモートコンピュータへの動作

Psexecは、リモートコンピュータ上でプログラムを実行するためにいくつかの手順を踏みます。

  1. PSEXESVC.exeファイルをC:\Windowsに作成します。
  2. リモートコンピュータ上でPsExecという名前のWindowsサービスを作成し、開始します。
  3. プログラムをpsexesvc.exeの親プロセスとして実行します。
  4. 完了すると、PsExec Windowsサービスは停止され、削除されます。

プロセスが100%正常に機能しない場合は、scコマンドを使用してサービスを手動で削除する必要がある場合があります。

シンプルなローカルコマンドの実行

PsExecはリモートコンピュータ上でのコマンド実行で最もよく知られていますが、ローカルでもコマンドを実行することもできます。

以下のようにコンピュータ名を指定しないだけで、ローカルでコマンドを実行できます。

> psexec <local command or EXE file>

なぜこれを行うのかというと、ローカルのSYSTEMアカウントとしてコマンドを実行するためです。後で詳しく説明するように、-sスイッチを使用してローカルまたはリモートで任意のコマンドをSYSTEMとして実行できます。

以下の短いビデオをご覧ください。psexecを使用して新しいコマンドセッションをNT AUTHORITY\SYSTEMとして起動するには、単に-sスイッチとコマンドインタープリタの実行可能ファイルを指定するだけです。

Running Psexec as SYSTEM

PsExecコマンド(より高度な操作)

基本を押さえたら、psexecでより高度なテクニックを学び始めることができます。PsExecは、単一のコンピュータ上で単一のコマンドを実行するだけでなく、さまざまな操作を行うことができます。

複数のコンピュータでコマンドを実行する

PsExecは、一度に複数のリモートコンピュータ上でコマンドを実行するだけでなく、プログラムのコピーとコマンドの実行もサポートしています。

複数のコンピュータでPsExecを同時に実行する方法はいくつかあります。

コンマで区切られたコンピュータ名

通常、単一のリモートコンピュータでコマンドを実行する場合、\\REMOTECOMPUTERのように単一のコンピュータ名を指定します。カンマで区切って複数のコンピュータを指定することもできます。

> psexec \\REMOTECOMPUTER1,REMOTECOMPUTER2,REMOTECOMPUTER3

Active Directoryドメイン内のすべてのコンピュータ

Active Directoryドメインに参加しているコンピュータでPsExecを実行し、そのドメインのすべてのコンピュータでコマンドを実行したい場合は、ワイルドカードを使用します。

PsExecは、Active Directoryドメイン全体を検索し、すべてのコンピュータでコマンドを実行しようとします。以下は、PsExecがドメイン内のすべてのコンピュータに接続し、hostnameコマンドを実行しようとする例の構文です。

> psexec \\* hostname

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

Enumerating domain...

ローカルコンピュータがワークグループに属している場合、ドメイン内のすべてのコンピュータを検索するためにアスタリスクを使用すると、A system error has occurred: 6118というエラーが発生します。

ワイルドカードを使用すると、PsExecは基本的にコマンドnet view /allを実行して最初にドメイン内のすべてのコンピュータを検索します。これは、NetBIOSに依存しているため、コンピュータ情報を検索するための古い方法です。

ファイルから読み込む

一度に複数のコンピュータでコマンドを実行する別の方法として、テキストファイルを使用することがあります。構文@<filename.txt>を使用すると、PsExecはテキストファイルの各行をコンピュータ名として読み取ります。それぞれのコンピュータを個別に処理します。

以下には、PowerShellを使用して行区切りのコンピュータ名のテキストファイルを作成し、それをpsexecの入力として使用する例が示されています。

PS51> (Get-AdComputer -Filter *).Name | Out-File computers.txt
PS51> psexec @computers.txt hostname

ローカルプログラムをリモートコンピュータにコピーする

-cスイッチを使用すると、psexecは実行前にローカルのプログラムをリモートコンピュータにコピーします。

おそらく、ローカルコンピュータのC:\ToolsフォルダにEXEファイルがあり、それをリモートコンピュータで実行したい場合、次の構文を使用します:

> psexec \\REMOTECOMPUTER -c C:\Tools\program.exe

-cスイッチを使用して実行ファイルを指定しない場合でも、PsExecはファイルをコピーしようとしますが、「指定されたファイルが見つかりません。」というエラーが表示されます。これは、PsExecがコピーしたファイルを常に実行しようとするためです。

PsExecを使用する前にリモートコンピュータにファイルをコピーする必要がある場合は、Copy-Item PowerShellコマンドレットを代わりに使用します。

別の資格情報でリモートプロセスを実行する

PsExecのもう一つの人気のある使用方法は、代替アカウントでコマンドを実行することです。デフォルトでは、PsExecは現在ログインしているアカウントでリモートコンピュータに接続しようとします。具体的には、PsExecはリモートコンピュータであなたのアカウントを模倣します。

-uスイッチとオプションの-pスイッチを使用すると、代替ユーザーアカウントでリモートコンピュータに接続することができます。PsExecはユーザー名とパスワードを暗号化し、リモートコンピュータに送信して認証します。

たとえば、ワークグループにいる場合は、常にリモートコンピュータへの認証にユーザー名を指定する必要があります。

> psexec \\REMOTECOMPUTER hostname -u localadmin -p secret-p@$$word

両方のコンピュータがActive Directoryのメンバーである場合は、ドメイン名をユーザーアカウントの前に付ける必要があります。

> psexec \\REMOTECOMPUTER hostname -u contoso.local\domainadmin -p secret-p@$$word

-uスイッチを使用しない場合、psexecはリモートコンピュータ上でログインしているアカウントになります。ネットワークリソースにはアクセスできません。

ローカルシステムアカウントとしてプロセスを実行する

PsExecを別のアカウントで実行する最も便利な機能の1つは、-sスイッチを使用することです。このスイッチを使用すると、PsExec(およびリモートで実行されるアプリケーション)がリモート(またはローカル)コンピュータのローカルシステムアカウントで実行されます。

以下の例では、リモートコンピュータ名を含めていません。PsExecはローカルコンピュータでも実行できます。この場合、-sオプションを使用して、PsExecにローカルシステムアカウントとしてローカルのコマンドプロンプトを起動するように指示しています。

Running psexec as LOCAL SYSTEM

リモートコンピュータでローカルシステムとしてコマンドプロンプトを実行するには、以下のようにコンピュータ名を参照に追加します。

> psexec -s \\REMOTECOMPUTER cmd

リモートでGUIアプリケーションを起動する

もう1つの便利なPsExecのスイッチは-iです。デフォルトでは、PsExecはリモートで実行されるコマンドによってリモートコンピュータ上にウィンドウを表示しません。これは、リモートでコマンドを実行する場合、画面を見ることはないため便利です。

しかし、ユーザーのためにプログラムを起動する必要があるかもしれません。あなた自身はアプリケーションを使用しないでしょうが、エンドユーザーが使用します。その場合は、-iスイッチを使用します。

リモートコンピュータでメモ帳ウィンドウを開きたい場合も問題ありません。 -iスイッチと一緒にnotepad.exeを実行すると、PsExecがメモ帳を開きます。

> psexec -i \\REMOTECOMPUTER notepad
Running psexec in interactive mode

しかし、対話ウィンドウが表示された場合には、-dスイッチも使用して切断するようにしてください。デフォルトでは、PsExecは実行したプロセスの完了を待ちます。この場合、リモートプロセス(この場合はメモ帳)が実行され続けると、PsExecは制御を返さなくなります。

-dスイッチを-iとともに使用すると、PsExecにリモートプロセスの完了を待たないように指示します。代わりに、リモートプロセスが実行されるとすぐに切断し、制御を返します。

出力のリダイレクト

PsExecは、リモートプロセスから送信された出力をローカルセッションに依存します。通常、この出力は直接ローカルコンソールに表示されます。しかし、リダイレクトしたい場合は、通常のリダイレクト演算子を使用して行うことができます。たとえば、コマンドを実行してすべての出力を無効にしたい場合、出力とエラーを^> nul ^2^&1にリダイレクトすることができます。

特殊文字はハットでエスケープされていることに注意してください(^)。

PsExecの使用例

Psexecの使用方法を学んだ後、さまざまな具体的な使用例に遭遇することがあります。このセクションでは、Psexecを使用した実際の使用例と例をいくつか紹介します。

リモートコマンドプロンプトの起動(psexec cmd

最も一般的な使用例の1つは、PsExecをインタラクティブなコマンドプロンプトとして起動することです。PsExecは単にリモートでコマンドを実行するだけでなく、コマンドの出力をコンソールに送信することもできます。そのため、(まだ使用している人がいるなら)素晴らしいtelnetの代替、またはおそらくPowerShellのEnter-PSSessionの代替となります。

リモートコマンドを起動するには、リモートコンピュータ名を指定し、cmdアプリケーションを実行します。CmdはWindowsのコマンドインタプリタです。PsExecは対話的な使用をサポートしているため、点滅するカーソルとプロンプトが返されます。

> psexec \\REMOTEPC cmd
Opening a command prompt on a remote computer

この時点で、世界はあなたのものです。この「入れ子」のコマンドプロンプトを介してローカルコンピュータ上でコマンドを実行し、リモートコンピュータ上で実行されます。

コマンドプロンプトから終了するには、exitと入力します。PsExecはリモートコンピュータ上のcmdプロセスを停止し、フォーカスをローカルコンピュータに戻します。

対話的なcmdセッションを終了するためにCtrl-Cを使用しないでください。常にexitを使用してください。Ctrl-Cを使用すると、psexecセッションはリモートコンピュータで実行されたままになります。

リモートでのソフトウェアのインストール

PsExecを貧弱なソフトウェアデプロイメントツールとして使用することができます。おそらく1つ以上のリモートコンピュータで実行する必要があるMSIインストーラーがあり、setup.msiと呼ばれています。このインストーラーをリモートコンピュータにコピーし、msiexec.exeユーティリティをいくつかのスイッチとともに実行する必要があります。

以下は、PsExecを使用してソフトウェアをリモートで展開する方法の例です。この例では、setup.msiをリモートコンピュータにコピーし、SYSTEMアカウントでMSIインストーラを対話型で起動します。

> psexec.exe \\REMOTECOMPUTER –i –s "msiexec.exe /i setup.msi" -c setup.msi

「/accepteula」スイッチなしでEULAを受け入れる

先述のように、PsExecを初めて実行すると、EULAを受け入れる必要があります。 「/accepteula」スイッチを使用することもできますが、レジストリに「ステージング」することもできます。

初回起動時、PsExecはHKCU\Software\Sysinternals\PsExecというレジストリキーを作成します。その代わりに、DWORD値が1のレジストリ値EulaAcceptedを作成します。

リモートコンピュータ上でレジストリを変更するためのお気に入りの方法を使用して、このキー/値を作成するだけでPsExecを実行する必要はありません。/accepteulaを実行する必要はありません!

PowerShellとPsExecの結合

PowerShell以前は、PsExecしかありませんでした。今ではオプションがあります。PowerShellは多くの状況でPsExecを置き換えることができますが、他の状況では補完することができます。

PowerShellでコンピュータ名を構築する

ドメイン内のすべてのコンピュータを見つけるために\\*を使用する代わりに、PowerShellを使用することができます。PowerShellを使用すると、特定のコンピュータを選択するだけでなく、ファイアウォールに影響を与える可能性のあるnet view /allの振る舞いを使用する必要はありません。

PowerShellを使用して、カンマで区切られたすべてのコンピュータ名を含む文字列を作成できます。その文字列をPsExecに渡すことができ、それによってまるで手動で入力したかのようにそれぞれを処理することができます。

Get-AdComputerコマンドレットの使用例を以下に示します。これはActiveDirectory PowerShellモジュールの一部です。

PS51> psexec "\\$((Get-AdComputer -Filter *).Name -join ',')" hostname

リモートでPowerShellリモートを有効にする

PsExecではなく、PowerShellリモートを使用したいリモートコンピュータがある場合、それらを有効にするためにPsExecを使用できます。

Enable-PSRemotingまたはwinrm.cmdバッチファイルをリモートコンピュータで実行することで、一度に多くのコンピュータで簡単にPowerShellリモートをオンにすることができます。

以下に、SYSTEMアカウントとして実行されているリモートコンピュータでwinrm.cmdバッチファイルを呼び出す例を示します。そのコマンドの出力は必要ないため、2>&1> $nullで無効化されています。

$computerName = 'REMOTECOMPUTER'
psexec "\\$Computername" -s c:\windows\system32\winrm.cmd quickconfig -quiet 2&>&1> $null 

PsExecエラーメッセージ

ここで再度言及しておく価値があるのは、PsExecから返されるエラーコードのほとんどはリモートプロセスからのものであり、PsExecからのものではないということです。しかし、これらのエラーコードとそれらの意味を理解しておくと役立ちます。

すべてのWindowsエラーコードについての参照は、この詳細なWindowsエラーコードのリストを参照することをお勧めします。

以下は、PsExecから返される可能性のある一般的なエラーコードのリストです。

Error Code Explanation
-2146232576 Typically returned by Windows Update when an error occurs.
0 Command executed successfully
1 Incorrect function. A problem happened. That’s about it.
1603 Fatal error during installation. This typically is returned by msiexec.
2 The system cannot find the file specified
4 The system cannot open the file.
5 Access is denied.
6 The handle is invalid.
6118 The list of servers for this workgroup is not currently available

ご意見をお聞かせください

ATA Ultimate Guidesは大変なものです。これらにはたくさんの情報があり、私はここかしこでミスをするかもしれません。もし何か間違いや追加すべきことがあれば、コメントで教えてください。投稿の中であなたをクレジットさせていただきます。

クレジット

  • Mathias(コメント)による数多くのフィードバックに感謝します。

Source:
https://adamtheautomator.com/psexec/