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

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

다르게 할 수 있습니까?



답변

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

업데이트 :이 스크립트는 이제 명령 행 인수 및 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>


답변

여기 내가 사용하고있는 하나의 라이너가 있습니다.

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

echo main code here
pause

노트:

  • Windows 7 및 10에서만 테스트되었으며 따옴표로 엉망이 될 수 있습니다.
  • 현재 인수 전달을 지원하지 않습니다.

답변

여기 내 코드가 있습니다! 그것은 커 보이지만 대부분 주석 줄입니다 (::로 시작하는 줄).

풍모:

  • 전체 인수 전달
  • 작업 폴더를 변경하지 않습니다
  • 오류 처리
  • 괄호가있는 경로를 허용합니다 (% 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]


답변

다른 접근법은

  • 로컬로 바로 가기를 생성하고 관리자 권한을 요구하도록 설정 [속성, 고급, 관리자 권한으로 실행]

그리고

  • 사용자에게 바로 가기 (또는 배치 파일 자체가 아닌 바로 가기의 링크)를 보냅니다.

데니스

[나중에 추가됨-예,이 스레드의 날짜를 알지 못했습니다.]


답변

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

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


답변

다른 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매개 변수는 고도를 제공합니다 .


답변

나는 이것이 OP의 해결책이 아니라는 것을 알고 있지만 여기에 다른 많은 사용 사례가 있다고 확신하기 때문에 공유 할 것이라고 생각했습니다.

이 답변의 모든 코드 예제에 문제가 있었지만 다음을 발견했습니다.
http://www.robotronic.de/runasspcEn.html

관리자 권한으로 실행할 수있을뿐만 아니라 파일이 변경되지 않았는지 확인하고 필요한 정보를 안전하게 저장합니다. 사용법을 알아내는 가장 확실한 도구는 아니지만 코드를 작성하는 사람들에게는 충분히 간단해야합니다.