배치 파일 내에서 관리자 액세스를 요청하는 방법


179

사용자가 UAC를 사용하는 Vista 컴퓨터에서 실행할 수 있도록 배치 파일을 작성하려고합니다. 파일이 호스트 파일을 다시 쓰고 있으므로 관리자 권한으로 실행해야합니다. .bat 파일에 대한 링크가 포함 된 전자 메일을 보낼 수 있어야합니다. 원하는 동작은 파일을 마우스 오른쪽 단추로 클릭하고 열기라고 말하면 화면이 어두워지고 응용 프로그램 관리자에게 실행 권한을 부여할지 여부를 묻는 UAC 대화 상자 중 하나를 얻게됩니다. 대신 명령 행 창에 "액세스 거부"가 표시됩니다.

다르게 할 수 있습니까?


2
이 문제를 겪고 나와 같이 PowerShell 사용에 만족한다면 @ toster-cx의 one-liner를 놓치지 마십시오. 완전한!
Michael Repucci

답변:


353

이 스크립트는 트릭을 수행합니다! 박쥐 파일의 맨 위에 붙여 넣기 만하면됩니다. 스크립트의 출력을 검토하려면 배치 파일 맨 아래에 "일시 중지"명령을 추가하십시오.

업데이트 :이 스크립트는 이제 명령 행 인수 및 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
나는이 불결한 일을 말도 안되는 일을하는 것을 싫어하지만 때로는 강요 당하고 이것이 효과적입니다. 건배!
matt burns

4
이 방법은 인수를 전달하지 않습니다. 어떻게 할 수 있는지 아십니까? 기본적으로 첫 번째 줄 % 1에는 값이 있고 마지막 줄 % 1은 null입니다. 나는 논쟁을 전달해야한다.
갈래

3
참고로 이것은 Windows 8 Embedded에서 작동하는 것으로 테스트되었습니다
Robert Snyder

6
이것은 내 컴퓨터를 화면을 가로 질러 대각선으로 열고 닫는 나선형의 명령 창에 넣습니다. 중지하는 유일한 방법은 원본 배치 파일을 삭제하는 것입니다. 내 배치 파일을 반복적으로 실행하고 vbs 파일을 작성 중입니다. 처음으로 인증을 요청했지만 그 후에는 반복됩니다.
TomDestry

2
무한 루프 및 리턴 코드 2에서 TomDestry와 동일한 문제가 발생했습니다. 이것은 Windows 8.1에있었습니다. Windows 8.0에서 작동했으며 8.1 업데이트인지 또는 문제를 일으킨 다른 것인지 확실하게 알 수 없습니다. 나를 위해 일한 해결책은 cacls.exe (또는 icacls)를 사용하지 않고 오히려 net session> nul 2> & 1 IF ERRORLEVEL 1 go 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)그들이 어디 위의 하나가 될 것입니다 PARAMS
토니 브릭스를

또한 사용 가능은 'am_admin %*'당신이 사용할 수있는 / : 모든 것을 통과, 상점 시세 및 공간과 잘 재생되지 않습니다 shift따라서 제외한 모든 인수를 고정, 첫 번째 인수를 팝업 일괄 %0.
toster-cx

이것은 좋은 대답이지만 FIRST 실행시 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로 오류 수준을 설정하고 그 비트를 제거하고 그것을 완벽했다. Windows 10 Home을 사용하고 있습니다.
Knyri

% temp % 폴더의 경로에 괄호가 있습니까? 이 경우에만 오류 수준 1을 설정해야합니다.
cyberponk 2016 년

아니. 그것이 fc;:바로 이후에 필요합니까? 그 작은 부분이 왜 문제를 일으켰는지 잘 모르겠습니다.
Knyri

"fc ;: 2> nul"은 의도적으로 종료하기 전에 ERRORLEVEL 1을 설정하여 오류를 나타냅니다. @echo를 제거하고 실행하여 개인 메시지로 출력을 보내 주시겠습니까? 감사!
cyberponk

어쨌든 yout 환경 변수에 char echo/%TEMP%| findstr /C:"(" >nul가 있는지 테스트 하고 if 양수 뒤에 부분을 실행해야합니다 . 그래도 테스트가 긍정적으로 돌아가는 것은 이상한 일입니다 . (%temp%&&(
cyberponk

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에서 파일을 시작했을 때는 그렇지 않았습니다.

따라서 두 개의 개별 배치 파일을 사용하는 것이 좋습니다. 첫 번째는 두 번째 배치 파일을 호출하는 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"라는 두 번째는 첫 번째와 동일한 디렉토리에 있으며 실제 명령은 다음과 같습니다.

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

이로 인해 무한 루프가 발생하지 않으며 오류가 발생하기 쉬운 관리자 권한 검사도 제거됩니다.


당신을 위해 일했습니까? 슬프게도 , 같은 기본 문제로 인해 여기와 다른 스레드 에서이 모든 것과 다른 모든 스레드가 실패합니다. "runas"parm (또는 명령)은 셸 개체가 다른 프로그램 내부에서 간접적으로 만들어 질 때마다 실패합니다 . 관심있는 스레드는 여기 입니다.
Laurie Stearn

:) 나를 위해 일한
Sritam Jagadev

6

다른 PowerShell 솔루션 ...

이것은 관리자 권한으로 배치 스크립트를 실행하는 것이 아니라 배치에서 다른 프로그램을 높이는 방법입니다.

exe에 대한 배치 파일 "wrapper"가 있습니다. "루트 파일 이름"은 동일하지만 대체 확장자입니다. exe를 관리자로 시작하고 다음 한 줄 powershell 호출로 작업 디렉토리를 스크립트가 포함 된 디렉토리로 설정할 수 있습니다 .

@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한 줄 과 같습니다 . %~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

1

이 페이지의 toster-cx 게시물 및 기타 흥미로운 게시물을 기반으로 문제를 구성하고 해결하는 방법에 대한 통찰력을 얻었습니다. 디스크 정리 유틸리티가 월요일과 목요일에 점심 시간 (오후 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

덕분에 여기 포럼 및 REMS POST에 대한 많은 [ https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need-to-pass-parameters-to-script ][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

배치 파일에서 관리자 권한을 요청할 수는 없지만 % temp %에서 Windows 스크립팅 호스트 스크립트를 작성하고 실행할 수 있습니다 (그리고 배치를 관리자로 실행 함). Shell에서 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.