こんにちは!今回はWindowsにおける最上位権限の一つである「システム権限」でバッチファイルを実行する方法を紹介していきたいと思います。
通常、Windowsで操作を行う際の「権限」といえば「ユーザー権限(Usersグループ)」だったり、「管理者権限(Administratorsグループ)」権限などが一般によく用いられるでしょう。しかし、それらの権限ではできない操作も多々あります。
そんな時、管理者権限よりさらに強い権限である「システム権限」を使う事で解決できるかもしれません。
「管理者権限で実行」をしてもどうにもうまく処理できなかったり、逆にどうやっても停止できないプロセスがある!といった場合に今回の方法を使ってみてはいかがでしょうか。
やりたいこと
・Windowsの根幹である「システムファイル」と呼ばれる、Windowsの重要なフォルダ・ファイルの移動・削除や、重要なプロセスを終了させるとき、それらのコマンドをシステム権限で実行したい。
普通に「コマンドプロンプト」からコマンドを実行したり、「タスクマネージャー」から「タスクの終了」をしても「アクセスが拒否されました」と出てしまい、思ったようにやりたいことができないことがあると思います。
それを解決するために、今回は「バッチファイル」単体で「システム権限」で任意の処理を実行してみたいと思います。
スクリプト例
@echo off
cd /d %~dp0
setlocal
set path=%PATH%;%windir%system32;%windir%\system32\WindowsPowerShell\v1.0
whoami /priv | find "SeDebugPrivilege">nul
if %errorlevel% neq 0 (
@powershell start-process %~0 -verb runas
exit
)
rem ここからシステム権限への昇格処理
set taskName=PromoteToSystemPrivileges
schtasks /delete /tn %taskName% /f
if "%1" equ "1" (
goto :Main
) else (
schtasks /create /tn %taskName% /tr "'%~0' 1" /sc onlogon /ru system
schtasks /run /tn %taskName%
exit
)
rem ここからシステム権限で実行したい処理を記載します
:Main
whoami>%~dp0sample.log
exit
使い方
1.上記で作成したバッチの「:Main」ラベルの下行に「システム権限」で実行したい処理を記入する。
2.出来上がったバッチを任意の場所に、拡張子を「.bat」にして保存する。
3.ダブルクリックで実行
解説
タスクスケジューラにシステム権限で実行するバッチを登録する。
タスクスケジューラの登録には「schtasks /create」コマンドを使います。
「/tn」は登録するタスク名で、好きな名前を付けてあげればOKです。今回は「PromoteToSystemPrivileges」という名前を付けてみました。
「/tr」は実際に登録するコマンドです。「%~0」は自分自身のフルパスという意味なので、このパターンだと、「自分自身に引数「1」を付けて実行」というコマンドにあんります。
「/sc onlogon」はログイン時に実行するというオプションですが、これがないとタスクスケジューラに登録できないことがあるので、ダミーとして入れてあります。
set taskName=PromoteToSystemPrivileges schtasks /create /tn %taskName% /tr "'%~0' 1" /sc onlogon /ru system exit
そして最後につけた「/ru system」オプションが今回のミソで、これを付けてタスクスケジューラに登録すると、起動時にシステム権限で実行してくれます。
これによってバッチをシステム権限で実行させています。
※実行時にタスクスケジューラを見てみると、登録されているのが確認できると思います。
タスクスケジューラに登録してあるタスクを即時実行する
これは先ほどの「schtasks」に/runオプションを付けて実行する形で実現できます。
「/run」オプションは「/tn」で指定した名前のタスクを即時実行するというコマンドですので、問題なく実現できると思います。
schtasks /run /tn %taskName%
これを、先ほど行ったタスクスケジューラに登録するコマンドの後に置けば、すぐさまタスクを実行してくれます。
システム権限での処理実行
先ほどの起動処理では、「1」を引数にしてシステム権限で実行するというタスクを登録しました。
ということは、引数に「1」がある場合はシステム権限で起動できている。ということになりますね。
その判断をするために、「if "%1" equ "1"」を実行させ、「1だったら:Mainにジャンプ」するという処理にしています。
rem ここからシステム権限への昇格処理 set taskName=PromoteToSystemPrivileges schtasks /delete /tn %taskName% /f rem タスクスケジューラから起動された場合、引数に「1」が渡されている if "%1" equ "1" ( goto :Main ) else ( rem タスクスケジューラに自分自身を引数「1」で呼び出すタスクを登録 schtasks /create /tn %taskName% /tr "'%~0' 1" /sc onlogon /ru system schtasks /run /tn %taskName% exit ) :Main rem ~~~ここに処理を記入~~~ whoami>%~dp0sample.log exit
上記サンプルコードでは、「システム権限」に昇格した後、不要になった自身を起動したタスクを削除しています。その後、引数判定をして「:Main」へジャンプさせて処理を実行させています。
試しに、バッチファイルのあるフォルダに「システム権限」に昇格された「whoami」コマンドの結果が「sample.log」として出力されます。
その中身を確認すると、「System」という出力がされていれば、システム権限での実行が出来ています。通常であれば実行したユーザー名が出力されます。
注意点
注意点として、システム権限では画面上にコマンドプロンプトの黒い画面が表示されません。
実行した人に入力を求めるような「対話型」のバッチファイルにはそのままでは使えません。
また、最上位の権限のため、消してはいけないデータやプロセスなども容易に操作できてしまいます。
テストの際は、壊れてしまっても大丈夫な環境を用意してから実行してください。
システム権限での処理は、目的をしっかり決め、最小限の処理にとどめておいたほうが無難です。
あとがき
今回は、システム権限で処理を実行するバッチファイルの作成方法について紹介させていただきました。
前書きでも記載しましたが、「システム権限」が必要になる処理の多くは、「Windowsの根幹」にあたる「ファイルやフォルダ、プロセス」の操作にまつわるものです。
上記の方法で「アクセスが拒否されました」を表示させずに操作が実行できる場合も多々あり魅力的ですが、そもそも「アクセス」を「拒否」する理由があるファイルやプロセスの操作がほとんどのため、十分に注意して利用してみてください。
まず「アクセスが拒否されました」と出る箇所をいじらないで済むのが理想的ですが、どうしても動作がおかしく必要になる場合などもあるでしょう。実行後にリカバリできる範囲で利用してみてください。
他に、「PSTools」と呼ばれるファイルの「PsExec」を用いた手法もあり、Windowsを使いこなす上で非常に便利なツールセットの「PSTools」も別記事にて紹介予定です!
何かのお役に立てれば幸いです。
コメント