如何检测CMD是否以管理员身份运行/具有提升的特权?


101

从一个批处理文件中,我想测试我是否正在使用管理员/提升的特权运行。

选择“以管理员身份运行”时,用户名不会更改,因此不起作用。

如果有一个普遍可用的命令,该命令无效但需要管理特权,那么我可以运行该命令并检查错误代码,以测试特权。到目前为止,我还没有找到这样的命令。我发现的命令似乎返回单个非特定的错误代码,该错误代码可能指示任何内容,并且由于各种原因,它们很容易失败。

我只关心Windows 7,尽管对早期操作​​系统的支持会很好。


一种黑客可能会尝试echo > somefile进入需要管理员权限的目录。它会产生一个副作用的文件,但是您可以检查冲突并创建唯一的文件名来解决。
Marc B


1
[你可以在这里找到一个自升批次] [1] [1]:stackoverflow.com/questions/4051883/...
阿穆尔·阿里


1
@npocmaka您链接的问题实际上是该副本的重复;)(2013年与2011年)
Matthieu

Answers:


62

附录:对于Windows 8,它将不起作用;看到这个很好的答案


在此处找到此解决方案:http : //www.robvanderwoude.com/clevertricks.php

AT > NUL
IF %ERRORLEVEL% EQU 0 (
    ECHO you are Administrator
) ELSE (
    ECHO you are NOT Administrator. Exiting...
    PING 127.0.0.1 > NUL 2>&1
    EXIT /B 1
)

假设这不起作用,并且由于我们正在谈论Win7,则可以在Powershell中使用以下命令:

$principal = new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
$principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)

如果不是(并且可能不是,因为您明确提出了批处理文件),则可以在.NET中编写以上代码,然后根据结果返回exe的退出代码以供批处理文件使用。


4
AT命令非常完美!您的Google-fu优于我的Google-fu。;-)
Jeff

2
+1 @Rushyo,我稍微扩展了您的解决方案并将其发布在这里,因为那是我最初遇到的一个解决方案。谢谢! stackoverflow.com/questions/4051883/...
blak3r

16
AT在Windows 8上不起作用,但是我找到了更好的解决方案。我将其发布为另一个问题的答案,在这里:stackoverflow.com/questions/4051883/…
mythofechelon

4
我推荐whoami / groups | findstr / b BUILTIN \ Admin | findstr / c:“启用的组” &&回声“我有管理员!” -在95、98、2000,xp,vista,7、8上工作!(摘自评论“我喜欢Rushyo对使用AT的建议...”)
barwnikk

1
我喜欢用ping替换丢失的内容sleep:)
Matthieu

96

此技巧仅需一个命令:net session在命令提示符下键入。

如果您不是管理员,则会收到拒绝访问消息。

System error 5 has occurred.

Access is denied.

如果您是管理员,则会收到不同的消息,最常见的是:

There are no entries in the list.

来自MS Technet

使用不带参数的net session可以显示有关与本地计算机的所有会话的信息。


这在功能上与使用AT命令的Rushyo的答案相同。
杰夫

12
在Windows 8.1上,由于不建议使用AT,因此它优先于AT。使用Rushyo的答案,但是用net sessionnet.exe session代替AT对我来说是完美的。
kayleeFrye_onDeck 2014年

这似乎是在命令提示符下执行此操作的最简单方法(尽管与批处理文件不同)。
enderland

2
只需There are no entries in the list.在Windows 10 Pro中打印
gman

1
在批处理文件中,使用类似以下的内容:net session >nul 2>&1 || (echo not admin&goto :eof)
anilech

27

我喜欢Rushyo关于使用AT的建议,但这是另一种选择:

whoami /groups | findstr /b BUILTIN\Administrators | findstr /c:"Enabled group" && goto :isadministrator

如果需要,此方法还可以使您区分非管理员和非高阶管理员。未提升权限的管理员在组列表中仍具有BUILTIN \ Administrators,但未启用它。

但是,这在某些非英语语言系统上不起作用。相反,尝试

whoami /groups | findstr /c:" S-1-5-32-544 " | findstr /c:" Enabled group" && goto :isadministrator

(这在Windows 7上应该可以使用,但是我不确定较早的版本。)


1
在波兰语版本中,我具有:BUILTIN \ Administratorzy,因此,我建议:whoami / groups | findstr / b BUILTIN \ Admin | findstr / c:“启用的组” &&转到:isadministrator
barwnikk 2013年

@barwnikk,我建议whoami/groups然后手动扫描线。不会花费太长的时间,命令就适合您的大脑。
Pacerier,2015年

@Pacerier:问题的关键是要检测批处理文件中的高程。如果有人在命令行上,他们所要做的就是查看窗口标题,如果您有提升权限,该窗口标题始终以“ Administrator:”开头。
哈里·约翰斯顿

@哈里·约翰斯顿,哇没意识到。是否在所有版本的Windows中都显示“管理员”标题?
Pacerier,2015年

@Pacerier:所有当前版本(Vista起)。
哈里·约翰斯顿

24

几乎其他人之前已经做过的一样,但作为一个衬里可以在批处理命令的开始处放置。(好吧,通常在@echo关闭之后。)

net.exe session 1>NUL 2>NUL || (Echo This script requires elevated rights. & Exit /b 1)

2
这是最新版本,它很好地隐藏了net.exe的无关输出
andersand

2
在Windows 10,效果很好
詹姆斯包

效果很好,只需将末尾调整为&Timeout / t 10和Exit / b 1),以便在批处理文件中窗口不会立即消失。
WhoIsRich

12

在Vista,Win 7及更高版本上执行此操作的最简单方法是枚举令牌组并查找当前的完整性级别(如果只有组成员身份很重要,则请查找管理员sid):

检查我们是否正在升高运行:

whoami /groups | find "S-1-16-12288" && Echo I am running elevated, so I must be an admin anyway ;-)

检查我们是否属于本地管理员:

whoami /groups | find "S-1-5-32-544" && Echo I am a local admin

检查我们是否属于域管理员:

whoami /groups | find "-512 " && Echo I am a domain admin

下面的文章列出了Windows使用的完整性级别SID:http : //msdn.microsoft.com/zh-cn/library/bb625963.aspx


whoami / groups在极端情况下会收到错误的信息。见stackoverflow.com/questions/4051883/...
zumalifeguard

7

这是对哈利的回答的轻微修改,该回答着重于提高地位。我在install.bat文件的开头使用它:

set IS_ELEVATED=0
whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" | findstr /c:"Enabled group" > nul: && set IS_ELEVATED=1
if %IS_ELEVATED%==0 (
    echo You must run the command prompt as administrator to install.
    exit /b 1
)

这绝对对我有用,原理似乎很合理。来自MSFT的Chris Jackson

在高空运行时,令牌包含一个称为“强制标签\高强制级别”的ACE。


whoami / groups在极端情况下会收到错误的信息。见stackoverflow.com/questions/4051883/...
zumalifeguard

7

解决方案:

at >nul
if %ErrorLevel% equ 0 ( echo Administrator ) else ( echo NOT Administrator )

在Windows 10下不起作用

对于所有版本的Windows都可以这样做:

openfiles >nul 2>&1
if %ErrorLevel% equ 0 ( echo Administrator ) else ( echo NOT Administrator )

6

我阅读了很多(大多数?)答复,然后开发了一个在Win 8.1中对我有用的bat文件。以为我会分享。

setlocal
set runState=user
whoami /groups | findstr /b /c:"Mandatory Label\High Mandatory Level" > nul && set runState=admin
whoami /groups | findstr /b /c:"Mandatory Label\System Mandatory Level" > nul && set runState=system
echo Running in state: "%runState%"
if not "%runState%"=="user" goto notUser
  echo Do user stuff...
  goto end
:notUser
if not "%runState%"=="admin" goto notAdmin
  echo Do admin stuff...
  goto end
:notAdmin
if not "%runState%"=="system" goto notSystem
  echo Do admin stuff...
  goto end
:notSystem
echo Do common stuff...
:end

希望有人觉得这有用:)


whoami / groups在极端情况下会收到错误的信息。见stackoverflow.com/questions/4051883/...
zumalifeguard

这次真是万分感谢!在Windows 8.1上,其他“ whoami”解决方案对我不起作用。这个做了。
瑞安


1

我知道我参加这个聚会真的很晚,但是这是我确定管理员身份的班轮。

它不依赖于错误级别,仅依赖于systeminfo

for /f "tokens=1-6" %%a in ('"net user "%username%" | find /i "Local Group Memberships""') do (set admin=yes & if not "%%d" == "*Administrators" (set admin=no) & echo %admin%)

根据用户的管理员状态,它返回是或否。

它还相应地将变量“ admin”的值设置为“是”或“否”。


仅当用户是Administrators本地组的直接成员时,此方法才有效。如果用户是作为Administrators组成员的域组的成员(例如,“ Domain Admins”),则它将不起作用。
哈里·约翰斯顿

1

如果您以具有管理员权限的用户身份运行,那么将不会定义环境变量SessionName,并且在运行批处理文件时您仍然没有管理员权限。

您应该使用“ net session”命令并查找错误返回码“ 0”以验证管理员权限。

例; -第一个echo语句是响铃字符 net session >nul 2>&1 if not %errorlevel%==0 (echo echo You need to start over and right-click on this file, echo then select "Run as administrator" to be successfull. echo.&pause&exit)


0

这是我在Windows 7到Windows 10上使用的一种简单方法。基本上,我只使用“ IF EXIST”命令检查Windows \ System32 \ WDI \ LogFiles文件夹。从Windows 7开始(至少从7开始),WDI文件夹存在于每一次Windows安装中,并且需要管理员权限才能访问。WDI文件夹中始终始终有一个LogFiles文件夹。因此,如果以admin身份运行,则在WDI \ LogFiles文件夹上运行“ IF EXIST”将返回true,如果不以admin运行,则将返回false。可以在批处理文件中使用它来检查特权级别,并根据该结果跳转到所需的任何命令。

这是示例代码的简短片段:

IF EXIST %SYSTEMROOT%\SYSTEM32\WDI\LOGFILES GOTO GOTADMIN
(Commands for running with normal privileges)

:GOTADMIN
(Commands for running with admin privileges)

请记住,此方法假定未在WDI文件夹上修改默认的安全权限(在大多数情况下不太可能发生,但请参阅下面的警告2)。即使在这种情况下,也只需修改代码以检查是否需要管理员访问权限的其他通用文件/文件夹(System32 \ config \ SAM可能是一个不错的替代选择),或者甚至可以为此专门创建自己的文件夹目的。

关于此方法有两个警告:

  1. 禁用UAC可能会打破一个简单的事实,那就是无论如何一切都将以管理员身份运行。

  2. 尝试在Windows资源管理器中打开WDI文件夹,然后在出现提示时单击“继续”,将为该用户帐户添加永久访问权限,从而破坏了我的方法。如果发生这种情况,可以通过从WDI文件夹安全权限中删除用户帐户来解决。如果出于某种原因用户必须能够使用Windows资源管理器访问WDI文件夹,则您必须修改代码以检查其他文件夹(如上所述,为此专门创建自己的文件夹可能是个不错的选择) 。

因此,诚然,我的方法并不是很完美,因为它可以被破坏,但是它是一种相对较快的方法,易于实现,并且与Windows 7、8和10的所有版本均兼容,并且只要我牢记上述注意事项对我来说100%有效。


0

适用于Win7 Enterprise和Win10 Enterprise

@if DEFINED SESSIONNAME (
    @echo.
    @echo You must right click to "Run as administrator"
    @echo Try again
    @echo.
    @pause
    @goto :EOF
)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.