UAC自動昇格
システムの設定変更やサービスの操作など、管理者権限が必要な処理をバッチファイルで行おうとしたとき、「アクセスが拒否されました」というエラーに遭遇したことはありませんか?通常はバッチファイルを右クリックして「管理者として実行」を選ぶ必要があります。しかし、ユーザーにその操作を毎回求めるのは手間がかかります。
この記事では、バッチファイル自身が管理者権限で実行されているかどうかを自動的に確認し、権限が不足している場合は UAC(ユーザーアカウント制御)ダイアログを表示して自動的に昇格する方法を解説します。
管理者権限で実行されているか確認する
自動昇格を実装するには、まず「現在のプロセスが管理者権限で動いているか」を判定する必要があります。これには net session コマンドを利用するのが一般的な方法です。
net session は、管理者権限がなければアクセスが拒否されるコマンドです。出力を捨てつつ実行し、ERRORLEVEL で結果を判断します。
net session >nul 2>&1
| 状況 | ERRORLEVEL |
|---|---|
| 管理者権限あり | 0 |
| 管理者権限なし | 0 以外(通常は 2) |
net session >nul 2>&1
if %errorlevel% equ 0 (
echo 管理者権限で実行されています。
) else (
echo 管理者権限がありません。
)
net session はネットワークセッション情報を表示するコマンドですが、管理者権限がないと実行できないという特性を権限チェックに利用しています。シンプルで信頼性が高いため広く使われている手法です。
PowerShell を使った UAC 自動昇格
管理者権限がないと判定された場合、PowerShell の Start-Process コマンドレットを使ってバッチファイル自身を管理者権限で再起動させます。
基本パターン
@echo off
net session >nul 2>&1
if %errorlevel% neq 0 (
powershell -Command "Start-Process '%~f0' -Verb RunAs"
exit /b
)
rem ここから管理者権限で実行される処理
echo 管理者権限で実行中です。
pause
各部分の役割を整理します。
| 記述 | 説明 |
|---|---|
net session >nul 2>&1 | 管理者権限の有無を確認する |
if %errorlevel% neq 0 | 権限がない場合に昇格処理を実行 |
Start-Process '%~f0' | このバッチファイル自身をフルパスで起動する |
-Verb RunAs | 管理者として実行(UAC ダイアログを表示) |
exit /b | 元の(権限なし)プロセスを終了する |
%~f0 は「このバッチファイル自身のフルパス」を意味する特殊変数です。バッチファイルが C:\tools\setup.cmd に置かれていれば C:\tools\setup.cmd に展開されます。これにより、ファイルがどこに置かれていても自分自身を正しく再起動できます。
動作フローをまとめます。
net sessionで管理者権限を確認する- 権限がなければ PowerShell 経由で自身を管理者として起動する
- UAC ダイアログが表示され、ユーザーが「はい」を押すと新しいウィンドウが開く
- 元のウィンドウは
exit /bで閉じる - 新しいウィンドウは管理者権限を持つため、以降の処理が実行される
引数を保持して昇格する
バッチファイルに引数を渡して使う場合、そのまま昇格すると引数が失われます。-ArgumentList オプションで元の引数を引き継ぎましょう。
@echo off
net session >nul 2>&1
if %errorlevel% neq 0 (
powershell -Command "Start-Process '%~f0' -ArgumentList '%*' -Verb RunAs"
exit /b
)
rem 引数を使った処理
echo 管理者権限で実行中です。
echo 引数: %*
pause
%* はバッチファイルに渡されたすべての引数を展開します。たとえば setup.cmd install verbose と実行した場合、%* は install verbose になります。
引数にスペースや引用符などの特殊文字が含まれる場合、-ArgumentList '%*' では正しく渡せないことがあります。そのような場合は引数を個別にエスケープするか、PowerShell スクリプトへの移行を検討してください。
実践例:サービスの起動タイプを変更する
Windows サービスの設定変更には管理者権限が必要です。自動昇格の仕組みと組み合わせた実践的な例を示します。
@echo off
setlocal
rem UAC 自動昇格チェック
net session >nul 2>&1
if %errorlevel% neq 0 (
echo 管理者権限が必要です。UAC ダイアログを表示します...
timeout /t 2 >nul
powershell -Command "Start-Process '%~f0' -ArgumentList '%*' -Verb RunAs"
exit /b
)
rem ここから管理者権限で実行される処理
set SERVICE_NAME=%1
if "%SERVICE_NAME%"=="" set SERVICE_NAME=wuauserv
echo ================================
echo サービス管理ツール(管理者)
echo ================================
echo 対象サービス: %SERVICE_NAME%
echo.
sc query %SERVICE_NAME% | findstr /i "STATE"
echo.
echo サービスを手動起動に変更します...
sc config %SERVICE_NAME% start= demand
if %errorlevel% equ 0 (
echo 設定を変更しました。
) else (
echo エラーが発生しました。サービス名を確認してください。
)
echo.
pause
endlocal
timeout /t 2 >nul を昇格前に挟むことで、「管理者権限が必要です」というメッセージをユーザーが読む時間を確保できます。UAC ダイアログが突然表示されると驚かれることがあるため、一言添えるのが親切です。
注意点
UAC の昇格ダイアログは必ずユーザーの確認(「はい」ボタンのクリック)が必要です。スクリプトから自動的にダイアログをスキップすることはできません。ユーザーが「いいえ」を押した場合、昇格は行われず処理は終了します。
グループポリシーによって UAC が無効化されていたり、昇格の挙動が制御されていたりする環境では、このスクリプトが意図どおりに動作しないことがあります。また、UAC 自体が無効な場合は net session が常に成功(ERRORLEVEL=0)を返すこともあります。
管理者権限で実行されるバッチファイルは、システムの重要な設定やファイルを変更できます。信頼できない配布元から入手したバッチファイルに自動昇格の仕組みが組み込まれている場合は、実行前に内容を十分確認してください。
まとめ
| 項目 | 内容 |
|---|---|
| 管理者権限の確認 | net session >nul 2>&1 |
| 昇格の判定 | if %errorlevel% neq 0 |
| UAC 昇格の実行 | powershell -Command "Start-Process '%~f0' -Verb RunAs" |
| 引数の引き継ぎ | -ArgumentList '%*' を追加する |
| 元プロセスの終了 | exit /b で昇格後に元のウィンドウを閉じる |