如何在Windows命令行中以管理员身份运行命令?

90

我有一个小脚本,用于在Windows上构建和安装我管理的Bazaar代码库。我想要在Windows shell(cmd.exe)中以提升的管理员权限运行该脚本,就像右键单击并选择“以管理员身份运行”一样,但不使用任何需要使用图形界面的方法。


1
为了以管理员身份运行命令,我制作了一个类似于sudo的Windows工具,可作为Chocolatey软件包使用:https://dev59.com/t2kw5IYBdhLWcg3wx9eC#54642324 - noseratio - open to work
1
@noseratio 虽然您的评论不符合问题的精神,但这似乎是一个方便的工具。 - jpaugh
12个回答

81

您只需使用runas命令以管理员身份运行程序(但有一个注意事项)。

runas /user:Administrator "cmdName parameters"

在我的情况下,这是
runas /user:Administrator "cmd.exe /C %CD%\installer.cmd %CD%"

请注意必须使用引号,否则runas命令将吞噬cmd的开关选项。
另请注意,管理shell(cmd.exe)在C:\Windows\System32文件夹中启动。这不是我想要的,但很容易传递当前路径给我的安装程序,并使用绝对路径引用它。
注意:启用管理员帐户
以这种方式使用runas需要启用管理员帐户,在Windows 7或Vista上默认情况下不启用。但是,此处有一个很好的教程,介绍了三种不同的方法来启用它:
我自己通过打开“管理工具”,“本地安全策略”,然后导航到“本地策略-安全选项”,并更改“帐户:管理员帐户状态”策略的值为已启用来启用它,这与链接中显示的三种方法都不同。
甚至更简单的方法来实现这一点:
C:> net user Administrator /active:yes

4
有没有办法以不同的用户身份(具有管理员权限)运行程序,而不是以管理员身份运行?对我们使用工作电脑的人来说这非常重要... - Urchin
我想应该可以。试一下,看看是否可行。但是,我不知道用户需要哪些具体权限才能运行特定命令或者获得“管理员权限”。 - jpaugh
1
这个可以用,但不完全像Linux。我注意到在使用中会有一些小问题。另外,在执行命令之前,首先大约会有5秒的暂停时间。请自行决定是否使用。 - KeyC0de
1
你说的关于 hiccups 的问题是正确的!有些程序需要管理员权限才能运行,除非 shell(explorer.exe)也以管理员用户身份运行。(例如:control.exe。)然而,对于我的最初目的(无缝安装),Ander 的答案 更加适合。 - jpaugh

72

按下开始按钮。在搜索框中输入“cmd”,然后按下Ctrl+Shift+Enter


19
虽然这不是原问题所询问的,但是知道这个快捷方式还是不错的!谢谢。 - eXe
2
这并没有尝试回答问题,实际上也不应该成为最高评价的答案。-1 - James

52

一个批处理/WSH混合体可以调用ShellExecute来显示UAC提升对话框...

@if (1==1) @if(1==0) @ELSE
@echo off&SETLOCAL ENABLEEXTENSIONS
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"||(
    cscript //E:JScript //nologo "%~f0"
    @goto :EOF
)
echo.Performing admin tasks...
REM call foo.exe
@goto :EOF
@end @ELSE
ShA=new ActiveXObject("Shell.Application")
ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5);
@end

1
请问,@Anders,这个脚本需要哪些条件才能运行?a) Windows版本,b)已安装Visual Basic或.NET,c)已安装Java。乍一看,好像只需要Windows系统就可以了,但我不确定。谢谢。 - Sopalajo de Arrierez
2
@SopalajodeArrierez:据我所知,runas动词是在Win2000中添加的,而cscript.exe是在Win98/IE4中添加的。 - Anders
我认为早期版本的 NT 使用 STARTUPINFO 中未记录的标志来在控制台中设置图标,但对该功能的支持在 NT4 或 NT5 中已经被废弃。如果您已经有自己的程序,为什么不能在那里执行管理员检查呢?.pif 文件可能仍然可以设置图标,但我不知道 .pif 文件是否在64位Windows上得到支持... - Anders
3
在批处理文件中,“@”前缀会关闭该命令的回显,而在 Windows 脚本宿主 (http://msdn.microsoft.com/en-us/library/58dz2w55) 中,“@”是“预处理器”指令的前缀。在批处理和 WSH 中,“@if (1==1)”都是合法语法,其余内容用于根据实际运行脚本的处理器执行批处理或 WSH 代码。 (批处理文件调用 WSH(如果需要),然后再次调用批处理文件,在使用特殊动词执行后第二次被执行) - Anders
显示剩余8条评论

20
@echo off
fsutil dirty query %systemdrive% >nul || (
    echo Requesting administrative privileges...
    set "ELEVATE_CMDLINE=cd /d "%cd%" & call "%~f0" %*"
    findstr "^:::" "%~sf0">"%temp%\getadmin.vbs"
    cscript //nologo "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs" & exit /b
)

rem ------- getadmin.vbs ----------------------------------
::: Set objShell = CreateObject("Shell.Application")
::: Set objWshShell = WScript.CreateObject("WScript.Shell")
::: Set objWshProcessEnv = objWshShell.Environment("PROCESS")
::: strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
::: objShell.ShellExecute "cmd", "/c " & strCommandLine, "", "runas"
rem -------------------------------------------------------

echo Running script as admin.
echo Script file : %~f0
echo Arguments   : %*
echo Working dir : %cd%
echo.
:: administrator commands here
:: e.g., run shell as admin
cmd /k

它还允许将命令行参数传递给批处理脚本。
演示:self-elevating.bat "带有空格的路径" arg2 3 4 "另一个长参数"
这是另一个不需要创建临时文件的版本。
@echo off
<!-- : --- self-elevating_no_temp.bat ---------------------
fsutil dirty query %systemdrive% >nul && goto :gotAdmin
echo Requesting administrative privileges...
set "ELEVATE_CMDLINE=cd /d "%cd%" & call "%~f0" %*"
cscript //nologo "%~f0?.wsf" //job:Elevate
exit /b

-->
<job id="Elevate"><script language="VBScript">
  Set objShell = CreateObject("Shell.Application")
  Set objWshShell = WScript.CreateObject("WScript.Shell")
  Set objWshProcessEnv = objWshShell.Environment("PROCESS")
  strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
  objShell.ShellExecute "cmd", "/c " & strCommandLine, "", "runas"
</script></job>
:gotAdmin -------------------------------------------------

echo Running script as admin.
echo Script file : %~f0
echo Arguments   : %*
echo Working dir : %cd%
echo.
:: administrator commands here
:: e.g., run shell as admin
cmd /k

编辑于11/2023: 将当前工作目录更正为"%CD%"而不是"%~dp0" 更可靠的命令来检测脚本是否以管理员身份运行。

第二个版本真的很棒。看看那个美丽的 cscript "self-elevating.bat?.wsf" 部分。 - Rockallite
1
纯文本的 .bat 和 XML 的 .wsh 混合内容也非常漂亮。 - Rockallite
“find "S-1-16-12288"”中的SID是什么?当我使用“whoami /groups”时它没有出现。 - lit
1
非常酷。我会将ELEVATE_CMDLINE更改为cd到%cd%,以便初始调用中的相对路径是正确的。 - sgraham

6
尽管 @amr ali's 的代码很棒,但我遇到了一个问题,我的批处理文件包含 > < 符号,由于某种原因它们被阻塞了。
我找到了另一种方法。只需将其放在您的代码之前,它就可以完美地工作。
REM  --> Check for permissions
>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"
    echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
    "%temp%\getadmin.vbs"
    exit /B
:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------

3

使用一些 .vbs 在批处理文件顶部的简单管道技巧, ||。它将正常退出并以管理员身份重新启动。

@AT>NUL||echo set shell=CreateObject("Shell.Application"):shell.ShellExecute "%~dpnx0",,"%CD%", "runas", 1:set shell=nothing>%~n0.vbs&start %~n0.vbs /realtime& timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit

它在使用完temp.vbs后也会使用del /Q删除它。


5
这太酷了!您介意更深入地解释一下这句话吗? - jpaugh

2
我会设置一个快捷方式,可以是CMD或你想运行的东西,然后设置快捷方式的属性要求管理员权限,最后从批处理文件中运行该快捷方式。我还没有测试过它是否会遵守这些属性,但我认为这更加优雅,不需要激活管理员帐户。
另外,如果你将其设置为计划任务(可以从代码中设置),那么有一个选项可以在其中提升运行权限。

1
我的目标是完全通过命令行来完成。我不能期望每个使用我的安装程序的人在运行我的安装程序之前都遵循这个过程。 - jpaugh
@Kate - 我其实和你有同样的想法,今天在win2012服务器上尝试了一下,但不幸的是,它并没有起作用。即使你将快捷方式设置为“以管理员身份运行”,命令提示符仍然没有管理员权限。当我尝试通过任务计划程序使用快捷方式时,就会出现这种情况。任务计划程序必须在内部执行某些操作,以防止它以管理员身份运行,我不确定。 - dcp

2
我刚刚在桌面上创建了一个快捷方式,目标路径为:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command Start-Process -verb RunAs wt

在任务栏上固定后 :)

这个快捷方式在原问题的上下文中既不必要也无法使用,原问题是关于制作一个安装程序以在最终用户系统上运行。然而,这个命令很有趣。它看起来是对被接受答案的简化。这是正确的吗?它会弹出UAC对话框吗? - jpaugh

1

您可以通过其CLI调用PowerShellpowershell.exe,以调用其支持使用提升启动进程的Start-Process命令,这样做有两个优点:

  • 您不需要一个“混合”批处理文件,该文件使用巧妙但晦涩的技巧将两个不同环境的语言组合到单个文件中。

  • 您可以在-Verb RunAs之前放置-Wait(参见下文),以使提升重新调用同步,即等待其退出并将其退出代码传达给调用者。

以下内容借鉴了Amr Ali的有用的WSH辅助答案;例如,保存并运行为 run-elevated.cmd

@echo off & setlocal

:: Check if the current session is already elevated.
:: `net session` only succeeds in elevated sessions.
net session >NUL 2>&1 && goto :ELEVATED

:: Getting here means that we must reinvoke with elevation.
:: Add -Wait before -Verb RunAs to wait for the reinvocation to exit.
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
powershell.exe -noprofile -c Start-Process -Verb RunAs cmd.exe \"/k $env:ELEVATE_CMDLINE\"
exit /b %ERRORLEVEL%

:: Getting here means that we are (now) running with elevation.
:ELEVATED

echo === Running in elevated session:
echo Script file : %~f0
echo Arguments   : %*
echo Working dir : %cd%

说到Amr Ali的WSH辅助答案;这里有一个重新制定的方案,使得传递参数更加健壮,因此可以传递诸如"a & b"之类的参数,并通过避免使用call来防止在参数中重复"^"字符 - 请参见第set ELEVATE_CMDLINE=...行;此外,除了一些可读性的格式化之外,还确保不会意外地回显任何原始批处理语句:

<!-- : (":" is required)
@echo off & setlocal
net session >NUL 2>&1 && goto :ELEVATED
set ELEVATE_CMDLINE=cd /d "%~dp0" ^& "%~f0" %*
cscript.exe //nologo "%~f0?.wsf" //job:Elevate & exit /b
-->

<job id="Elevate">
  <script language="VBScript">
    Set objShell = CreateObject("Shell.Application")
    Set objWshShell = WScript.CreateObject("WScript.Shell")
    Set objWshProcessEnv = objWshShell.Environment("PROCESS")
    strCommandLine = Trim(objWshProcessEnv("ELEVATE_CMDLINE"))
    objShell.ShellExecute "cmd", "/k " & strCommandLine, "", "runas"
  </script>
</job>

:ELEVATED

echo === Running in elevated session:
echo Script file: %~f0
echo Arguments  : %*
echo Working dir: %cd%

0

浏览到 C:\windows\System32,右键单击 cmd.exe 并以管理员身份运行。在 Windows 7 上对我有效。

如果您正在尝试以提升的权限运行脚本,则可以对脚本文件执行相同操作,或使用计划程序的“以不同用户身份运行”选项来运行脚本。


这很棒,但不是我可以从命令行内完成的事情,例如从安装脚本中。唯一需要用户干预的是确认提升权限,类似于在Windows 6/7上安装任何程序时的操作。 - jpaugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接