外部ツールを使用せずに簡単な方法があります-Windows 7、8、8.1、10で正常に動作します下位互換性もあります(Windows XPにはUACがないため、昇格は必要ありません-その中でスクリプトが続行する場合)。
このコードをチェックしてください(私はスレッドバッチファイルに投稿されたNIronwolfのコードに触発されました-Windows 7で「アクセス拒否」?)、私はそれを改善しました-私のバージョンでは、作成および削除されたディレクトリはありません管理者権限を確認してください):
::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "https://stackoverflow.com/a/12264592/1016343" for description
::::::::::::::::::::::::::::::::::::::::::::
@echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
set winSysFolder=System32
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
if '%cmdInvoke%'=='1' goto InvokeCmd
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
goto ExecElevation
:InvokeCmd
ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"
:ExecElevation
"%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
REM Run shell as admin (example) - put here code as you like
ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
cmd /k
スクリプトは、NET FILE
管理者特権を必要とするという事実を利用して戻りますerrorlevel 1
、それがない場合利用しています。昇格は、特権を取得するためにバッチファイルを再起動するスクリプトを作成することによって行われます。これにより、WindowsはUACダイアログを表示し、管理者アカウントとパスワードを要求します。
私はWindows 7、8、8.1、10とWindows XPでテストしました-すべての人に問題なく動作します。利点は、たとえば、デバッグのためにWindowsサービスを再インストールして再実行する場合(mypackage.msiがサービスインストーラーパッケージであると想定)、システム管理者特権を必要とするものを何でも配置できることです。 :
msiexec /passive /x mypackage.msi
msiexec /passive /i mypackage.msi
net start myservice
この特権昇格スクリプトがないと、UACは管理者ユーザーとパスワードを3回要求します。今では、最初に1回だけ要求され、必要な場合のみ要求されます。
自動昇格の代わりに、スクリプトがエラーメッセージを表示し、管理者権限がない場合に終了する必要がある場合、これはさらに簡単です。これは、スクリプトの先頭に次の行を追加することで実現できます。
@ECHO OFF & CLS & ECHO.
NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO You must right-click and select &
ECHO "RUN AS ADMINISTRATOR" to run this batch. Exiting... & ECHO. &
PAUSE & EXIT /D)
REM ... proceed here with admin rights ...
このように、ユーザーは右クリックして[ 管理者として実行 ]を選択する必要があります。スクリプトはREM
、管理者権限を検出した場合はステートメントの後に進み、それ以外の場合はエラーで終了します。が不要な場合はPAUSE
、削除してください。
重要: NET FILE [...] EXIT /D)
同じ行にある必要があります。読みやすくするために、ここでは複数行で表示されています。
一部のマシンで問題が発生しましたが、上記の新しいバージョンで既に解決されています。1つは二重引用符の処理の違いによるもので、もう1つはWindows 7マシンでUACが無効になっている(最低レベルに設定されている)ためで、スクリプトが何度も何度も呼び出します。
パス内の引用符を削除して後で再度追加することで、これを修正しました。スクリプトが昇格された権限で再起動するときに追加されるパラメーターを追加しました。
二重引用符は以下によって削除されます(詳細はここにあります):
setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion
その後、を使用してパスにアクセスできます!batchPath!
。二重引用符は含まれていないため"!batchPath!"
、スクリプトの後半で言っても安全です。
この線
if '%1'=='ELEV' (shift & goto gotPrivileges)
権限を昇格させるためにVBScriptスクリプトによってスクリプトが既に呼び出されているかどうかをチェックし、無限の再帰を回避します。を使用してパラメータを削除しますshift
。
更新:
登録しなくても済むようにする.vbs
に内線番号のWindows 10を、私はラインを交換した
"%temp%\OEgetPrivileges.vbs"
ことにより、
"%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
上記のスクリプトでは、またcd /d %~dp0
、Stephen(別の回答)とTomášZato(コメント)が提案したように、スクリプトディレクトリをデフォルトとして設定するために追加されました。
これで、スクリプトは、渡されるコマンドラインパラメータを尊重します。jxmallet、TanisDLJ、およびPeter Mortensenの観察とインスピレーションに感謝します。
Artjom B.のヒントに従って、私はそれを分析し、に置き換えましSHIFT
たSHIFT /1
。これは、%0
パラメーターのファイル名を保持します
クリーンアップdel "%temp%\OEgetPrivileges_%batchName%.vbs"
する:gotPrivileges
セクションに追加されました(mltが推奨)。%batchName%
異なるバッチを並行して実行する場合の影響を回避するために追加されました。ファイル名だけを抽出するfor
などの高度な文字列関数を利用するには、を使用する必要があることに注意してください%%~nk
。
最適化されたスクリプト構造、改良(vbsGetPrivileges
ファイルのパスまたは名前を簡単に変更できるように変数が追加されました。.vbs
バッチを昇格する必要がある場合にのみファイルを削除してください)
場合によっては、昇格に別の呼び出し構文が必要でした。スクリプトが機能しない場合は、次のパラメーターを確認
set cmdInvoke=0
set winSysFolder=System32
しset cmdInvoke=1
てください。1番目のパラメーターをに変更して、問題が既に修正されているかどうかを確認します。cmd.exe
昇格を実行するスクリプトに追加されます。
または、2番目のパラメータをに変更してみてくださいwinSysFolder=Sysnative
。これは、64ビットシステムで役立つ場合があります(ただし、ほとんどの場合は必要ありません)。(ADBaileyはこれを報告しています)。「Sysnative」は、32ビットスクリプトホストから64ビットアプリケーションを起動する場合にのみ必要です(例:Visual Studioビルドプロセス、または別の32ビットアプリケーションからのスクリプト呼び出し)。
パラメータがどのように解釈されるかをより明確にするために、今はのように表示していP1=value1 P2=value2 ... P9=value9
ます。これは、パスなどのパラメータを二重引用符で囲む必要がある場合に特に役立ちます"C:\Program Files"
。
VBSスクリプトをデバッグする場合は、ここで//X
提案するように、パラメーターをWScript.exeに最初のパラメーターとして追加できます(CScript.exeについて説明されていますが、WScript.exeでも機能します)。
役立つリンク: