バッチファイル内の管理者アクセスを要求する方法


179

ユーザーがUACを使用してVistaマシンから実行できるバッチファイルを作成しようとしています。ファイルはホストファイルを書き換えているため、管理者権限で実行する必要があります。.batファイルへのリンクをメールで送信できるようにする必要があります。目的の動作は、ファイルを右クリックして[開く]と言うと、画面が暗くなり、アプリケーションに管理者として実行する許可を与えるかどうかをユーザーに尋ねるUACダイアログの1つを表示することです。代わりに、コマンドラインウィンドウに「アクセス拒否」と表示されます。

これは別の方法で可能ですか?


2
これに遭遇し、私のようにPowerShellの使用に満足している場合は、@ toster-cxからのワンライナーをお見逃しなく。パーフェクト!
マイケル・レプッチ2016

回答:


352

このスクリプトでうまくいきます。バットファイルの先頭に貼り付けてください。スクリプトの出力を確認する場合は、バッチファイルの下部に「一時停止」コマンドを追加します。

更新:このスクリプトは、コマンドライン引数と64ビットOSをサポートするように少し編集されています。

ありがとうEneerge @ https://sites.google.com/site/eneerge/scripts/batchgotadmin

@echo off

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
) ELSE (
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
)

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params= %*
    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------    
    <YOUR BATCH SCRIPT HERE>

22
私はこの汚いdosバッチナンセンスをしなければならないのは嫌いですが、時々あなたは強制され、これは素晴らしい働きをします。乾杯!
マットは

4
このメソッドは引数を転送しません。それがどのようにできるか知っていますか?基本的に、最初の行では%1に何らかの値があり、最後の行では%1がnullであることがわかります。議論を転送する必要があります。
プロング

3
参考までに、これはWindows 8 Embeddedで動作するようにテストされています
Robert Snyder

6
これにより、マシンがコマンドウィンドウのらせん状になり、画面を斜めに開閉します。停止する唯一の方法は、元のバッチファイルを削除することです。それは私のバッチファイルを繰り返し実行し、vbsファイルを書き込んでいます。初めて認証を要求しましたが、その後はループします。
TomDestry 2013年

2
無限ループと戻りコード2で、TomDestryとまったく同じ問題が発生しました。これはWindows 8.1で発生しました。私はそれがWindows 8.0で機能したことを知っており、問題の原因となったのが8.1のアップデートなのか他の何かなのか、はっきりとは言えません。私にとって有効な解決策は、cacls.exe(またはicacls)を使用しないことでした。netsession> nul 2>&1 IF ERRORLEVEL 1 goto UACPrompt ...
crig

55

これが私が使ってきたワンライナーです:

@echo off
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)

echo main code here
pause

ノート:

  • Windows 7と10でのみテストされているので、引用をいじる必要があるかもしれません。
  • 現在、引数の引き渡しはサポートされていません

1
あなたががあるかもしれませんどのように多くのparamsわかっている場合は、後にそれらを含めることによって、パラメータを渡すことができますam_admin if not "%1"=="am_admin" (powershell start -verb runas '%0' 'am_admin "%~1" "%~2"' & exit)彼らがいた場所の上1になるのparams
トニー・ブリックスを

また、使用することが可能で'am_admin %*'、すべてを渡すために、カントー引用符とスペースでうまく再生されない:/あなたは使用することができますshiftので、以外のすべての引数を固定し、最初の引数オフをポップするバッチで%0
toster-cx 2017

これは良い答えですが、受け入れるべきではありません。最初の実行時にADMIN特権で実行されたかどうかをチェックしないためです。
T.Todua

作業ディレクトリの追加を維持するために、cd /D %~dp0if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
ペドロ・ドゥアルテ

いい答えだ。%temp%の書き込み権限がある場合でも、VBスクリプトが無限ループを作成する間、単に機能します。
Twonky

19

これが私のコードです!大きく見えますが、ほとんどがコメント行(::で始まる行)です。

特徴:

  • 完全な引数の転送
  • 作業フォルダを変更しません
  • エラー処理
  • 括弧付きのパスを受け入れます(%TEMP%フォルダーを除く)
  • UNCパスをサポート
  • マップされたフォルダのチェック(管理者がマップされたドライブにアクセスできない場合に警告します)

  • 外部ライブラリとして使用できます(このトピックの投稿を確認してくださいhttps : //stackoverflow.com/a/30417025/4932683

  • コードの任意の場所で、必要に応じて呼び出すことができます

これをバッチファイルの最後に添付するか、ライブラリとして保存します(上記を確認)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:RequestAdminElevation FilePath %* || goto:eof
:: 
:: By:   Cyberponk,     v1.5 - 10/06/2016 - Changed the admin rights test method from cacls to fltmc
::          v1.4 - 17/05/2016 - Added instructions for arguments with ! char
::          v1.3 - 01/08/2015 - Fixed not returning to original folder after elevation successful
::          v1.2 - 30/07/2015 - Added error message when running from mapped drive
::          v1.1 - 01/06/2015
:: 
:: Func: opens an admin elevation prompt. If elevated, runs everything after the function call, with elevated rights.
:: Returns: -1 if elevation was requested
::           0 if elevation was successful
::           1 if an error occured
:: 
:: USAGE:
:: If function is copied to a batch file:
::     call :RequestAdminElevation "%~dpf0" %* || goto:eof
::
:: If called as an external library (from a separate batch file):
::     set "_DeleteOnExit=0" on Options
::     (call :RequestAdminElevation "%~dpf0" %* || goto:eof) && CD /D %CD%
::
:: If called from inside another CALL, you must set "_ThisFile=%~dpf0" at the beginning of the file
::     call :RequestAdminElevation "%_ThisFile%" %* || goto:eof
::
:: If you need to use the ! char in the arguments, the calling must be done like this, and afterwards you must use %args% to get the correct arguments:
::      set "args=%* "
::      call :RequestAdminElevation .....   use one of the above but replace the %* with %args:!={a)%
::      set "args=%args:{a)=!%" 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal ENABLEDELAYEDEXPANSION & set "_FilePath=%~1"
  if NOT EXIST "!_FilePath!" (echo/Read RequestAdminElevation usage information)
  :: UAC.ShellExecute only works with 8.3 filename, so use %~s1
  set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)
  :: Remove parenthesis from the temp filename
  set _FN=%_FN:(=%
  set _vbspath="%temp:~%\%_FN:)=%.vbs" & set "_batpath=%temp:~%\%_FN:)=%.bat"

  :: Test if we gave admin rights
  fltmc >nul 2>&1 || goto :_getElevation

  :: Elevation successful
  (if exist %_vbspath% ( del %_vbspath% )) & (if exist %_batpath% ( del %_batpath% )) 
  :: Set ERRORLEVEL 0, set original folder and exit
  endlocal & CD /D "%~dp1" & ver >nul & goto:eof

  :_getElevation
  echo/Requesting elevation...
  :: Try to create %_vbspath% file. If failed, exit with ERRORLEVEL 1
  echo/Set UAC = CreateObject^("Shell.Application"^) > %_vbspath% || (echo/&echo/Unable to create %_vbspath% & endlocal &md; 2>nul &goto:eof) 
  echo/UAC.ShellExecute "%_batpath%", "", "", "runas", 1 >> %_vbspath% & echo/wscript.Quit(1)>> %_vbspath%
  :: Try to create %_batpath% file. If failed, exit with ERRORLEVEL 1
  echo/@%* > "%_batpath%" || (echo/&echo/Unable to create %_batpath% & endlocal &md; 2>nul &goto:eof)
  echo/@if %%errorlevel%%==9009 (echo/^&echo/Admin user could not read the batch file. If running from a mapped drive or UNC path, check if Admin user can read it.)^&echo/^& @if %%errorlevel%% NEQ 0 pause >> "%_batpath%"

  :: Run %_vbspath%, that calls %_batpath%, that calls the original file
  %_vbspath% && (echo/&echo/Failed to run VBscript %_vbspath% &endlocal &md; 2>nul & goto:eof)

  :: Vbscript has been run, exit with ERRORLEVEL -1
  echo/&echo/Elevation was requested on a new CMD window &endlocal &fc;: 2>nul & goto:eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

使い方の例

:EXAMPLE
@echo off

 :: Run this script with elevation
 call :RequestAdminElevation "%~dpfs0" %* || goto:eof

  echo/I now have Admin rights!
  echo/
  echo/Arguments using %%args%%:    %args%
  echo/Arguments using %%*: %*
  echo/%%1= %~1
  echo/%%2= %~2
  echo/%%3= %~3

  echo/
  echo/Current Directory: %CD%
  echo/
  echo/This file: %0
  echo/

pause &goto:eof

[here you paste the RequestAdminElevation function code]

うまく機能しましたが、機能させるために行を変更する必要がありました。&fc;: 2>nul中にはset "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)1にERRORLEVELを設定した私は、そのビットを取り出して、それが完璧に働きました。Windows 10 Homeを使用しています。
Knyri

%temp%フォルダーのパスに括弧がありますか?この場合のみ、エラーレベル1が設定されることになっています。
cyberponk 2016年

いいえ。fc;:それは行くのでそれが必要ですか?それが実行されるはずなので、その少しが問題の原因である理由もわかりません。
Knyri

"fc ;: 2> nul"は、終了する前にERRORLEVEL 1を意図的に設定して、エラーを通知します。@echoをオフにして実行して、プライベートメッセージで出力を送っていただけませんか。ありがとう!
cyberponk 2016年

とにかく、yout 環境変数にchar echo/%TEMP%| findstr /C:"(" >nulがあるかどうかをテストし、ifが正の場合にのみ部分を実行する必要があります。なぜあなたのテストがポジティブに戻っているのかは奇妙です。(%temp%&&(
cyberponk 2016年

7

別のアプローチは

  • ローカルにショートカットを作成し、管理者権限を要求するように設定します[プロパティ、詳細設定、管理者として実行]

その後

  • ユーザーにショートカット[またはバッチファイル自体へのリンクではなく、ショートカットへのリンク]を送信します。

デニス

[後で追加-はい、このスレッドの日付に気づかなかった。]


6

Ben Gripkaのソリューションは無限ループを引き起こします。彼のバッチは次のように機能します(疑似コード):

IF "no admin privileges?"
    "write a VBS that calls this batch with admin privileges"
ELSE
    "execute actual commands that require admin privileges"

ご覧のとおり、VBSが管理者権限の要求に失敗した場合、これにより無限ループが発生します。

ただし、管理者権限が正常に要求されていても、無限ループが発生する可能性があります。

Ben Gripkaのバッチファイルでのチェックは、エラーが発生しやすいだけです。バッチをいじってみたところ、チェックは失敗しましたが、管理者権限は利用可能です。興味深いことに、Windowsエクスプローラーからバッチファイルを開始した場合、チェックは期待どおりに機能しましたが、IDEから開始した場合は機能しませんでした。

したがって、2つの個別のバッチファイルを使用することをお勧めします。1つ目は2つ目のバッチファイルを呼び出すVBSを生成します。

@echo off

echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~dp0\my_commands.bat"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"

"my_commands.bat"という名前で、最初のものと同じディレクトリにある2番目のファイルには、実際のコマンドが含まれています。

pushd "%CD%"
CD /D "%~dp0"
REM Your commands which require admin privileges here

これにより無限ループは発生せず、エラーが発生しやすい管理者権限チェックも削除されます。


あなたのために働きましたか?悲しいことに、これとここにある他のスレッド他のすべてのスレッドは、同じ根本的な問題のために失敗します。「runas」パラメーター(またはコマンド)は、別のプログラム内から間接的にシェルオブジェクトが作成されると失敗します。ここに興味のあるスレッド。
Laurie Stearn

私のために働いた:)
Sritam Jagadev

6

別のPowerShellソリューション...

これは、管理者としてバッチスクリプトを実行することではなく、別のプログラムをバッチから昇格する方法です...

私はexeのバッチファイル「ラッパー」を持っています。「ルートファイル名」は同じですが、拡張子が異なります。次の1行の PowerShell呼び出しで、exeを管理者として起動し、スクリプトを含むディレクトリに作業ディレクトリを設定できます。

@powershell "Start-Process -FilePath '%~n0.exe' -WorkingDirectory '%~dp0' -Verb RunAs"

より詳しい情報

Start-Process適用できる追加のオプションもたくさんあります!チェックアウト:https : //docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6

@接頭辞を使用していることに注意してください。これ@echo offは1行の場合と同じです。%~n0ここでは、バッチスクリプトの「ルート名」を取得するために使用してから、を連結し.exeて、隣接するバイナリをポイントしています。の使用は%~dp0、バッチが存在するディレクトリへのフルパスを提供します。そしてもちろん、この-Verb RunAsパラメータは標高を提供します


4

これはOPの解決策ではないことはわかっていますが、ここには他にも多くのユースケースがあると確信しているので、共有したいと思いました。

これらの回答のすべてのコード例で問題が発生しましたが、次のことがわかりました:http : //www.robotronic.de/runasspcEn.html

管理者として実行できるだけでなく、ファイルが改ざんされていないことを確認し、必要な情報を安全に保存します。私はそれが使い方を理解するための最も明白なツールではないことを認めますが、私たちがコードを書く人にとってはそれは十分に単純であるべきです。


3

@echo offそしてtitle、このコードの前に来ることができます。

net session>nul 2>&1
if %errorlevel%==0 goto main
echo CreateObject("Shell.Application").ShellExecute "%~f0", "", "", "runas">"%temp%/elevate.vbs"
"%temp%/elevate.vbs"
del "%temp%/elevate.vbs"
exit

:main
    <code goes here>
exit

以下について心配する必要がない場合、他の多くの回答はやりすぎです。

  • パラメーター
  • 作業ディレクトリ(cd %~dp0バッチファイルを含むディレクトリに変更されます)

3
@echo off 
Net session >nul 2>&1 || (PowerShell start -verb runas '%~0' &exit /b)
Echo Administrative privileges have been got. & pause

上記は私のWindows 10バージョン1903で動作します


1

このスクリプトで問題が発生したため、(Win 7 Proを使用して)無限ループで再度実行され、新しいコマンドプロンプトがポップアップするため、別のアプローチを試すことをお勧めします。バッチファイルを自動昇格させて、必要な場合、UAC管理者権限はありますか?

編集で述べたように、スクリプトの最後にこれを追加する必要があるので注意してください。特権が昇格された後、スクリプトディレクトリに戻ります。cd / d%〜dp0


この質問に対する私の答えを確認してください。これらすべての問題を処理します。
cyberponk 2016

1

このページのtoster-cxによる投稿とその他の興味深い投稿に基づいて、問題を構成して解決する方法についての洞察を得ました。ディスククリーンアップユーティリティを毎週月曜日と木曜日のランチタイム(たとえば午後2時)に2回実行したいと思っていたのと同じような問題がありました。ただし、これには権限の昇格が必要でした。

私のような他の初心者を助けるかもしれないバッチファイルを共有する-

@echo off
echo  Welcome to scheduling 'PC Maintenance Activity'
ping localhost -n 3 >nul
echo -- Step - 1 of 3 : Please give 'Admin' rights on next screen
ping localhost -n 5 >nul
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit)
cls
echo -- Step - 2 of 3 : In next screen, select temp areas for cleaning 
during routine scheduled activity
ping localhost -n 3 >nul
C:\Windows\System32\cleanmgr.exe /sageset:112
cls
echo    Now scheduling maintenance activity...
SchTasks /Create /SC WEEKLY /D MON,THU /TN PC_Cleanup /TR 
"C:\Windows\System32\cleanmgr.exe "/sagerun:112 /ST 14:00

cls

echo                         -- Thanks for your co-operation --
echo                    -- Maintenance activity is scheduled for --
echo                       -- Every Monday and Thursday at 2 pm --

ping localhost -n 10 >nul

このフォーラムとレムスPOSTに感謝します。 ] [1]

彼の投稿は、タスクのスケジュール中にオプションの引数を構成するのに役立ちました。


1

この投稿からのFSUTILクエリもあり、これss64.comでリンクされており、次のコードがあります。

@Echo Off
Setlocal
:: First check if we are running As Admin/Elevated
FSUTIL dirty query %SystemDrive% >nul
if %errorlevel% EQU 0 goto START

::Create and run a temporary VBScript to elevate this batch file
   Set _batchFile=%~f0
   Set _Args=%*
   :: double up any quotes
   Set _batchFile=""%_batchFile:"=%""
   Set _Args=%_Args:"=""%

   Echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\~ElevateMe.vbs"
   Echo UAC.ShellExecute "cmd", "/c ""%_batchFile% %_Args%""", "", "runas", 1 >> "%temp%\~ElevateMe.vbs"

   cscript "%temp%\~ElevateMe.vbs" 
   Exit /B

:START
:: set the current directory to the batch file location
cd /d %~dp0
:: Place the code which requires Admin/elevation below
Echo We are now running as admin [%1] [%2]
pause

FSUTILが存在する限り、それは信頼できる代替手段です。


0

バッチファイルから管理者権限を要求することはできませんが、Windowsスクリプトホストスクリプトを%temp%で記述して実行することができます(これにより、バッチが管理者として実行されます)シェルでShellExecuteメソッドを呼び出します。 「runas」を動詞として持つアプリケーションオブジェクト


0

mshta管理者権限を要求するために使用します。

@echo off
net session >nul 2>&1 && goto :admintasks
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
exit /b
:admintasks
rem ADMIN TASKS HERE

または、powershellを使用します。

powershell -c Start-Process "%~nx0" -Verb runas

-5

runasコマンドを使用します。しかし、.batファイルを簡単にメールで送信できるとは思いません。


6
この答えは間違っています。このrunasコマンドを使用して昇格を引き起こすことはできません。
Bill_Stewart 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.