我正在编写一个批处理文件,将分发给用户。我需要以提升的权限运行一些命令。我最初的解决方案是使用:
runas /noprofile /user:Administrator SOME_COMMAND
但是许多机器(包括我的机器)的隐藏管理员帐户处于非活动状态,因此没有设置管理员密码。我也不能指定其他用户名,因为不同的机器会有不同的用户。有没有办法通过批处理文件复制“右键单击 -> 以管理员身份运行”操作?我不介意弹出提示,我只是不希望用户明确右键单击并以管理员身份运行。
答案1
您可以利用每个现代 Windows 系统上都存在的 PowerShell。
将需要提升权限的命令拆分为单独的批处理文件,例如elevated.bat
。然后,在运行它们时,从非提升权限的脚本中使用它:
powershell -command "Start-Process elevated.bat -Verb runas"
这-Verb runas
部分是导致提升权限提示的原因。如果原始批处理文件已经以管理员身份运行,或者 UAC 提示已关闭,则新文件将在没有提示的情况下提升权限。
请注意,提升的批处理器的当前目录将以 开始System32
。如果这是一个问题,您可以使用此替代版本让它在与非提升脚本相同的目录中启动:
powershell -command "Start-Process cmd -ArgumentList '/c cd /d %CD% && elevated.bat' -Verb runas"
这会导致新cmd
实例首先cd
进入未提升的提示符变量提供的目录%CD%
,然后执行所需的批处理文件。
答案2
运行管理员让您以提升的权限从命令行运行程序(它将显示 UAC,以便用户可以输入凭据)。
答案3
继续 Ben N 的回答:
为了使批处理脚本自动提升(如果未提升权限启动则自动以管理员身份重新启动),您可以在脚本中首先使用以下代码(这里我用它来FSUTIL DIRTY query
测试管理员权限)。
FSUTIL DIRTY query %SystemDrive% >NUL || (
PowerShell "Start-Process -FilePath '%0' -Verb RunAs"
EXIT
)
REM Main code here
或者,如果您的脚本要求工作目录与批处理文件位置相同,请使用:
FSUTIL DIRTY query %SystemDrive% >NUL || (
PowerShell "Start-Process -FilePath cmd.exe -Args '/C CHDIR /D %CD% & "%0"' -Verb RunAs"
EXIT
)
REM Main code here
答案4
抱歉,我的英语很糟糕。这将以提升权限(具有管理员权限)运行批处理文件。此脚本由 Matt 创建(https://stackoverflow.com/users/1016343/matt)我修改了 Matt 脚本。更新:添加了 Windows 系统文件夹检查器。脚本:
::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "https://stackoverflow.com/a/12264592/1016343" for description
:: Sorry for very bad english
:: Modified script. Added check windows
:: system folder and then add it to ENV
:: (Envronment Variable)
::::::::::::::::::::::::::::::::::::::::::::
@echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
:checkWinSys
set "ResultFile=%temp%\checkSysResult.txt"
if exist "%SystemRoot%\Sysnative" (
echo 1
goto checkSysResult
) > "%ResultFile%"
if exist "%SystemRoot%\System32" (
echo 2
goto checkSysResult
) > "%ResultFile%"
setlocal EnableDelayedExpansion
set count=0
for /f "tokens=*" %%x in (%ResultFile%) do (
set /a count+=1
set var[!count!]=%%x
)
:checkSysResult
if "%var[3]%"=="1" ( set winSysFolder=Sysnative & goto skip ) else ( set winSysFolder=System32 & goto skip )
:skip
del "%ResultFile%"
setlocal DisableDelayedExpansion
:init(1)
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=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 & pushd .
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