PCにあまり詳しくない人にバッチファイルを実行してもらう時に困るのが、”管理者実行”の問題です。コマンドの内容によっては管理者権限で実行しないといけないものもあるのですが、事前に説明しておいても右クリックして管理者実行してもらえないというケースがよくあります。
ネットで調べてみると、バッチファイルの書き方次第ではバッチファイル自身が権限を昇格してコマンドを実行できるような書き方ができるようなので、試してみました。
管理者権限の判定
今バッチファイルが管理者権限・ユーザ権限どちらで実行されているかを判断するには、openfilesコマンドを使います。
このコマンドは現在開かれている共有フォルダや共有ファイルを列挙するコマンドなのですが、管理者権限がないと実行できません。
ユーザ権限で実行した場合は変数errorlevelに1、管理者権限で実行した場合は0が格納されるので、これを権限の判定に使用します。
自己昇格
自分自身の権限を昇格して実行するには、powershellの力を借ります。powershellでよく使う”start-process hogehoge -verb runas”という管理者でプロセス実行する文がありますが、ここで実行するプロセスにコマンドプロンプトの変数である”%~0”を使用します。
%~0はバッチファイル自身を意味する変数で、これにより自分自身を再度管理者権限で実行することができます。
表示上の一工夫
最初に権限確認のため実行するopenfilesですが、実行結果が1枚目のコマンドプロンプトに表示されてしまいます。ちょっとうっとうしいのでこれを表示させないために、結果を標準ログにまとめて捨ててしまいます。
記述としては”openfiles > NUL 2>&1”となり、”2>&1”の部分が「エラーログを標準ログにまとめる」の意で、”>NUL”の部分が「出力を捨てる」という意味合いになります。
なので、口語に直すと「openfilesの出力を捨てる。ただし、エラーログと標準ログはまとめる」といった感じになります。ちなみに”>NUL”と”2>&1”の順序を逆にすると普通に結果が画面に出力されてきますのでご注意下さい。
できあがったバッチファイル
[bat]
@echo off
rem openfilesを実行して実行権限を判定できる数値をerrorlevelに格納する
rem このopenfilesの結果はウインドウに出力しない
openfiles >NUL 2>&1
rem errorlevelの値が1(ユーザ権限)だった場合は管理者権限により自身を再実行
if %errorlevel% equ 1 (
powershell start-process %~0 -verb runas
) else (
rem 実行したい処理(例としてopenfiles)
openfiles
)
参考情報
こちらのサイトの情報が大変参考になりました。ありがとうございました。
How to check in a batch file if you are running it elevated
[winaero.com]