如何检测 CMD 是否以管理员身份运行/具有更高的权限?

在批处理文件中,我想测试我是否使用 Administrator/ 提升的特權運行。

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

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

我只关心 Windows7,尽管支持早期的操作系统会更好。

158867 次浏览

附录 : 对于 Windows8,这将不起作用; 请参见 这个绝妙的答案


在这里找到了这个解决方案: 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 返回退出代码。

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

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

如果您愿意,这种方法还允许您区分非管理员和非升级管理员。未升级的管理员在组列表中仍然有 BUILTIN 管理员,但是没有启用它。

然而,这在一些非英语语言系统上是行不通的

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

(这个应该可以在 Windows7上运行,但我不确定早期版本是否可行。)

下面是对 Harry 的回答的一个小小的修改,主要关注提升的状态; 我在 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 的克里斯 · 杰克逊:

当您运行提高,您的令牌包含一个 ACE 称为强制标签高强制等级。

这个技巧只需要一个命令: 在命令提示符下键入 net session

如果您是 不是管理员,您将得到一个访问被拒绝的消息。

System error 5 has occurred.


Access is denied.

如果你是 是一个管理员,你会得到一个不同的信息,最常见的是:

There are no entries in the list.

来自 微软科技:

在不使用参数的情况下,net 会话显示有关所有 与本地计算机的会话。

我知道我真的迟到了,但这是我决定管理权的唯一线索。

它不依赖于错误级别,只依赖于 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”的值设置为等于 yes 或 no。

在 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

下面的文章列出了 SID 窗口使用的完整性级别: http://msdn.microsoft.com/en-us/library/bb625963.aspx

我读了很多(大部分?)然后开发了一个在 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

希望有人觉得这个有用:)

和其他人之前放置的差不多,但是作为一行,可以放置在批处理命令的开头。(通常在“ echo off”之后)

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

解决办法:

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

在 Windows10下无法工作

所有版本的视窗都可以这样做:

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

https://stackoverflow.com/a/38856823/2193477的“非一行程序”版本

@echo off
net.exe session 1>NUL 2>NUL || goto :not_admin
echo SUCCESS
goto :eof


:not_admin
echo ERROR: Please run as a local administrator.
exit /b 1

下面是我在 Windows7到 Windows10上使用过的一个简单方法。基本上,我只是使用“ IF EXIST”命令来检查 Windows System32 WDI LogFiles 文件夹。WDI 文件夹至少从7开始存在于 Windows 的每一次安装中,并且它需要管理员特权才能访问。WDI 文件夹中始终有一个 LogFiles 文件夹。因此,在 WDI LogFiles 文件夹中运行“ IF EXIST”,如果作为管理员运行,返回 true; 如果不作为管理员运行,返回 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. 尝试在文件资源管理器中打开 WDI 文件夹,然后在提示时单击“继续”将为该用户帐户添加永久访问权限,从而破坏我的方法。如果发生这种情况,可以通过从 WDI 文件夹的安全权限中删除用户帐户来修复。如果因为任何原因,用户必须能够访问文件资源管理器的 WDI 文件夹,那么你必须修改代码来检查一个不同的文件夹(正如上面提到的,专门为此目的创建自己的文件夹可能是一个不错的选择)。

因此,我承认我的方法并不完美,因为它可能会被破坏,但它是一个相对快速的方法,很容易实现,同样兼容所有版本的 Windows 7,8和10,并提供我留意所提到的警告已经100% 有效的我。

为 Win7企业版和 Win10企业版工作

@if DEFINED SESSIONNAME (
@echo.
@echo You must right click to "Run as administrator"
@echo Try again
@echo.
@pause
@goto :EOF
)

如果你作为一个拥有管理员权限的用户运行,那么环境变量 SessionName 将不会被定义,而且在运行批处理文件时你仍然没有管理员权限。

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

例子; 第一个 echo 语句是 Bell 字符 净会期 > 空2 > 及1 如果不是% 错误级别% = = 0(回显 您需要重新开始并右键单击此文件, Echo 然后选择“ Run as Administrator”以获得成功。 回声 & 暂停 & 退出)

不幸的是,其他人提出的“ S-1-5-32-544”并不能证明海拔升高。

Windows10或更高版本,独立于语言的方法是:

whoami /groups | find "S-1-16-12288"

这是“高强制级别”,实际上已经升级了。

常规命令提示:

C:\> whoami /groups | find "S-1-16-12288"
C:\>

管理员命令提示:

C:\> whoami /groups | find "S-1-16-12288"
Mandatory Label\High Mandatory Level                          Label            S-1-16-12288




C:\>

在. bat 文件中使用:

whoami /groups | find "S-1-16-12288" && set ELEVATED=true || set ELEVATED=false

你也可以在 powershell 中使用:

function is_elevated() {
Param( [String] $ToGroup = "S-1-16-12288" )
return [bool] ( whoami /groups | select-string $ToGroup )
}

例如:

PS> cd c:/temp
PS> set-content is-elevated.ps1 "return [bool] ( whoami /groups | sls S-1-16-12288 )"
PS> ./is-elevated.ps1
False
PS> start -verb runas powershell.exe
...
PS C:\Windows\system32> cd \temp
PS C:\temp> ./is-elevated.ps1
True

谢谢 Torin Dark Flight, 你的方法是我在 Windows11上唯一有效的方法。 下面是一个扩展到你的文章的脚本示例:

IF EXIST %SYSTEMROOT%\SYSTEM32\WDI\LOGFILES GOTO :Running_As_An_Admin
ECHO You are NOT an Administrator. This command requires admin rights. & Echo: & Echo Quitting......
@TIMEOUT /T 10
goto :QUIT
:Running_As_An_Admin
Echo Do Admin stuff here!!!


:QUIT