Chapter 18

管理者権限昇格

zetamatta
zetamatta
2020.11.18に更新

今、管理者権限で動作しているかどうか

net session >nul 2>&1

は管理者権限でないと ERRORLEVEL=2 で失敗することで判別できます。
Office 365のデスクトップアプリケーションをバッチファイルで修復 - Qiitaより)

管理者権限に昇格する

いろいろ方法がありますが:

powershell "start-process -FilePath '実行ファイル名' -ArgumentList '引数' -verb runas"

が最も短いようです。
管理者権限でbatを実行したい時にやッた事 - Qiita

これで実行ファイル名や引数を自分自身などに渡せばよいので、一つの方法としては

if not "%~1" == "ADMINMODE" (
  powershell "start-process -FilePath '%~dpnx0' -ArgumentList 'ADMINMODE' -verb runas"
  exit /b
)
echo 以下管理者モードでさせるコマンド
pause

といったところでしょうか。PowerShell では文字列を囲むのに一重引用符でも二重引用符でも、どちらでも使えます。ただ、パラメータを渡す時、埋め込み置換だと妙な誤動作が発生する恐れもあるので、環境変数を経由して

setlocal
set "ME=%~dpnx0"
set "ARG=%*"
if not "%~1" == "ADMINMODE" (
  powershell "start-process -FilePath $env:ME -ArgumentList ('ADMINMODE '+$env:ARG) -verb runas"
  exit /b
)
echo 以下管理者モードでさせるコマンド
shift
echo ARG1=%~1 ARG3=%~2 ARG4=%~3 ARG5=%~4
pause
endlocal

とかした方が安全かもしれません。ただ、バッチファイルに手間暇かけすぎても、保守性が下がるだけであまり益もないので、ここらはホドホドでよいと思います。

管理者モードでのネットワークドライブの復元

注意事項としては、管理者モードではネットワークドライブの接続が継承されないという点があります。管理者モードでネットワークドライブを使う場合は、ネットワークドライブの設定を復元するようなコードを書く必要があります。

(レジストリを書き換えれば継承されるという情報もあるのですが、たまに一部の環境で期待どおり動かなかったりしますし、ユーザの環境設定を書き換えを要求するのはあまりよろしくないので「それはできない」という前提で進めます)

普通は分かっている範囲でよいと思いますが、もし、通常モードで張られているすべてのネットワークドライブを管理者モードで復元しなくてはいけないといったことをやらないといけない場合(滅多にないと思いますが)、次のように PowerShell でがんばらないといけません。

@echo off
rem **** make.cmd ****
call :"%1"
:"_install"
    rem 管理者モードで実際にすること
    exit /b
:""
   powershell "start-process -FilePath 'cmd.exe' -ArgumentList ('/s /c '+[char]34+((get-wmiobject win32_networkconnection | %%{ 'net use '+$_.LocalName+' '+[char]34+$_.RemoteName+[char]34 }) -join ' & ') + ' & ' + [char]34 + '%~dpnx0' + [char]34 + ' _install' + [char]34) -verb 'runas'"
   exit /b