読者です 読者をやめる 読者になる 読者になる

treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

システム権限でコマンドプロンプト起動

トラブルシューティング ネットワーク

今日はローカルシステムアカウントを使用しなければならないシステム管理者向けに、コマンドプロンプトをシステム権限で起動する方法についてご報告します。
WindowsXPまではできていたのですが、最近のOSではWindowsXPまでで利用していた方法が使えなくなっていました。

WindowsXPまでの方法は?

WindowsXPまでは、atコマンドに/interactiveオプションを付与してcmd.exeを起動することによってシステムアカウントでコマンドプロンプトが起動できました。
 at %起動時間% /interactive "cmd.exe"
起動時間のところに1・2分後の時刻をセットしておくようにします。例えば現在時刻が1:05であれば数分後の1:07をセットして、
 at 1:07 /interactive "cmd.exe"
という具合にコマンドを実行します。XPまではこれが使えたのですが、Windows7以降のOSではこのatコマンドを利用してcmd.exeを起動することができなくなっていました。
----------------------------------------------
>at 1:07 /interactive "cmd.exe"
この AT コマンドは廃止されました。代わりに schtasks.exe を使用してください。

この要求はサポートされていません。
----------------------------------------------
schtasks.exeは確かにatコマンドのようなスケジューラとしては動作するのですが、システムアカウントでコマンドプロンプトを起動するという動作はできませんでした。

そこで利用するPsexec

以前にPSToolsのPSEXECを利用する方法をご報告しました。

blog.treedown.net

この記事ではあくまでリモート接続についての内容となっていますが、psexecはこれだけではありません。ローカルシステムアカウントでローカルシステムに接続する、ということも可能になっています。
使い方は簡単です。Windowsキー+Xのメニューで言うところの「コマンドプロンプト(管理者)」で起動し、以下のコマンドを実行します。
「PsExec.exe -i -s cmd」
※psexecに対するパスが通っていない場合にはpsexec.exeをフルパスで入力します。
起動したところのウィンドウが以下です。
図:起動したの図

f:id:treedown:20160427102538p:plain

whoamiコマンドの実行結果が「nt authority\system」となっているのが確認できます。
この画面でコマンド実行するとローカルシステムアカウントによる実行となるのでかなり強力な権限で実行ができるようになります。※そのため取り扱いには十分にご注意ください。

これを使うシチュエーション

これを使うシチュエーションはそうそう何度も出てくることはないのですが、実際にローカルシステムアカウントが必要だった体験事例も併せてご報告しておきます。
私がローカルシステムアカウントを必要としたのは、プロキシが利用されている社内ネットワークにおいて、BITSを利用しないアプリの更新(例えばAIRアプリ)で、システムアカウントのプロファイルが利用されることがあり、設定をしました。

もっと具体的に言うと、ユーザのPCにバッググラウンドでサイレントインストールするにはローカルシステムアカウントを使ってインストーラをキックしないとUACが動作してしまうのです。ローカルシステムアカウントを使えばUACが動作しないので、ユーザPCに対してバックグラウンドでサイレントオプションを付与したインストーラを起動させることができる、ということです。このサイレントインストールを実行するために使われるローカルシステムアカウントのプロファイル設定としてプロキシ設定が必要だった、ということです。

通常、プロキシ環境ではBITSが利用されていれば、「netsh winhttp show proxy」コマンドでプロキシが指定されているはずです。このような環境であれば、プロキシ経由でのアップデート導入は可能です。例えば
----------------------------------------------
>netsh winhttp show proxy

現在の WinHTTP プロキシ設定:

    直接アクセス (プロキシ サーバーなし)。
----------------------------------------------
このように表記されると、プロキシ設定がされていません。プロキシ経由でしかインターネット上のホストにアクセスできないLAN環境では、ここにプロキシサーバのIPやホスト名が出力されないと、Windows Updateが遅い、エラーになる、といった症状がでます。

この(アップデートの)インストールプロセスでシステムアカウントを使用してアップデートを実行している場合、サイト接続を要するようなアップデートの作りになっていれば
「ローカルシステムアカウントであってもプロキシ設定が必要になる」
というところでハマりました。
つまり、ローカルシステムアカウントで実行しているアップデータがサイト接続要求(おそらくルート証明書の確認などをしている)をしてくるので、インターネットアクセスができないと(タイムアウト待ちをして)動作が遅い、最悪(タイムアウトで)エラーになる、という症状が起こります。
で、通常は「netsh winhttp set proxy」コマンドでプロキシ設定をしてやれば動作OKになります。

ようやく本題に戻りますが、「netsh winhttp set proxy」でプロキシ設定してもタイムアウト待ちの動作が変わらないことがあります。これはローカルシステムアカウントでインターネットサイト接続を要するアップデータやインストーラを動作させていることが要因になります。
これを対処するにはローカルシステムアカウントのプロファイルでプロキシ設定をしてやることが一つの解決策になります。
ローカルシステムアカウントのプロファイル上のプロキシ設定が必要になる場合には、システムアカウントで起動したコマンドプロンプトで「inetcpl.cpl」を起動します。
----------------------------------------------
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>whoami
nt authority\system

C:\WINDOWS\system32>inetcpl.cpl
----------------------------------------------
そうすると、インターネットのプロパティ(IEの設定画面)が表示されますが、この画面は現在ログインしているユーザのものではなく、「nt authority\system」ユーザの設定画面です。ここでプロキシ設定を入れ込んで検証してみるわけですね。

恒常的にこの設定をいれてしまうかどうか、というのは賛否が分かれると思いますが、ローカルシステムアカウントでインストールを実行する場合にタイムアウト(ないし待ち時間が長い)場合にはこのサイトアクセスができるようになる設定を検証マシンなどで動作確認し、問題の切り分けをするにはシステムアカウントでコマンドプロンプト起動は役に立つはずです。

まとめ

システムアカウントでのコマンドプロンプト起動覚えておくと、トラブルシューティングの役に立つ可能性があります。
合い言葉は
PsExec -i -s cmd
です。
ただし、ローカルシステムアカウントはくれぐれもご利用に注意が必要です。濫用はお勧めできません。