批处理脚本:如何检查管理员权限

fla*_*acs 266 windows cmd admin batch-file

如何检查当前批处理脚本是否具有管理员权限?

我知道如何使用runas调用它自己,而不是如何检查管理员权限.我见过的唯一解决方案是粗暴的黑客工作或使用外部程序.好吧,实际上我并不关心它是否是一个黑客工作,只要它适用于Windows XP及更新版本.

myt*_*lon 444

问题

blak3r/Rushyo的解决方案适用于除Windows 8以外的所有内容.AT在Windows 8上运行会导致:

The AT command has been deprecated. Please use schtasks.exe instead.

The request is not supported.
Run Code Online (Sandbox Code Playgroud)

(见截图#1)并将返回%errorLevel% 1.

 

研究

所以,我去搜索需要提升权限的其他命令.rationalallyparanoid.com有一个列表,所以我在当前Windows操作系统(XP和8)的两个相反极端上运行每个命令,希望找到一个命令,当使用标准权限运行时,两个操作系统都将被拒绝访问.

最终,我找到了一个 - NET SESSION.一个真实,干净,通用的解决方案,不涉及:

  • 在安全位置创建或与数据交互
  • 分析FOR循环返回的数据
  • 在"管理员"中搜索字符串
  • 使用AT(Windows 8不兼容)或WHOAMI(Windows XP不兼容).

每个都有自己的安全性,可用性和可移植性问题.

 

测试

我已经独立证实这适用于:

  • Windows XP,x86
  • Windows XP,x64
  • Windows Vista,x86
  • Windows Vista,x64
  • Windows 7,x86
  • Windows 7,x64
  • Windows 8,x86
  • Windows 8,x64

(见截图#2)

 

实施/使用

因此,要使用此解决方案,只需执行以下操作:

@echo off
goto check_Permissions

:check_Permissions
    echo Administrative permissions required. Detecting permissions...

    net session >nul 2>&1
    if %errorLevel% == 0 (
        echo Success: Administrative permissions confirmed.
    ) else (
        echo Failure: Current permissions inadequate.
    )

    pause >nul
Run Code Online (Sandbox Code Playgroud)

如果您懒惰,请在此处访问:https://dl.dropbox.com/u/27573003/Distribution/Binaries/check_Permissions.bat

 

说明

NET SESSION是用于"管理服务器计算机连接的标准命令.在没有参数的情况下使用,[it]显示有关与本地计算机的所有会话的信息."

那么,这是我给定实现的基本过程:

  1. @echo off
    • 禁用命令显示
  2. goto check_Permissions
    • 跳转到:check_Permissions代码块
  3. net session >nul 2>&1
    • 运行命令
    • 隐藏命令的视觉输出
      1. 将标准输出(数字句柄1/STDOUT)流重定向到nul
      2. 将标准错误输出流(数字句柄2/STDERR)重定向到与数字句柄1相同的目标
  4. if %errorLevel% == 0
    • 如果退出代码(%errorLevel%)的值是, 0那么这意味着没有发生错误,因此,立即上一个命令成功运行
  5. else
    • 如果退出代码(%errorLevel%)的值不是 0那么这意味着发生错误,因此,前一个命令运行失败
  6. 将根据满足哪些标准来执行相应括号之间的代码

 

截图

Windows 8AT %errorLevel%:

[imgur]

 

NET SESSION在Windows XP x86上 - Windows 8 x64:

[imgur]

 

感谢@Tilka将您接受的答案更改为我的答案.:)

  • +1很棒的工作!好的研究.你的帖子应该是新接受的答案. (11认同)
  • 此解决方案通常很有效,但是如果停止"服务器"(LanmanServer)服务,则"服务器服务尚未启动"的错误代码与"访问被拒绝"的错误代码相同,从而导致错误否定.换句话说,在某些情况下,您可以使用管理权限运行此检查,并且它将返回与没有这些权限时相同的错误. (11认同)
  • 如果用户是高级用户,则此代码返回误报(至少在Windows 7上).高级用户也可以"提升"然后成功运行`net session`(ERRORLEVEL = 0) - 但他们实际上没有管理员权限.使用`openfiles`(参见下面的**Lucretius**的答案)没有这个问题. (8认同)
  • @Lectrode我发布了一个没有相同问题的替代解决方案:http://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights#21295806 (3认同)
  • 如果网络设备没有完全工作(例如:Windows 调试),这将挂起提示。fltmc >nul 2>&1 在这方面效果更好。 (2认同)

bla*_*k3r 78

Anders解决方案对我有用,但我不知道如何反转它以获得相反的结果(当你不是管理员时).

这是我的解决方案.它有两个案例是IF和ELSE案例,还有一些ascii艺术,以确保人们真正阅读它.:)

最小版本

Rushyo在此发布了此解决方案:如何检测CMD是否以管理员身份运行/具有提升的权限?

NET SESSION >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
    ECHO Administrator PRIVILEGES Detected! 
) ELSE (
    ECHO NOT AN ADMIN!
)
Run Code Online (Sandbox Code Playgroud)

添加错误消息,暂停和退出的版本

@rem ----[ This code block detects if the script is being running with admin PRIVILEGES If it isn't it pauses and then quits]-------
echo OFF
NET SESSION >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
    ECHO Administrator PRIVILEGES Detected! 
) ELSE (
   echo ######## ########  ########   #######  ########  
   echo ##       ##     ## ##     ## ##     ## ##     ## 
   echo ##       ##     ## ##     ## ##     ## ##     ## 
   echo ######   ########  ########  ##     ## ########  
   echo ##       ##   ##   ##   ##   ##     ## ##   ##   
   echo ##       ##    ##  ##    ##  ##     ## ##    ##  
   echo ######## ##     ## ##     ##  #######  ##     ## 
   echo.
   echo.
   echo ####### ERROR: ADMINISTRATOR PRIVILEGES REQUIRED #########
   echo This script must be run as administrator to work properly!  
   echo If you're seeing this after clicking on a start menu icon, then right click on the shortcut and select "Run As Administrator".
   echo ##########################################################
   echo.
   PAUSE
   EXIT /B 1
)
@echo ON
Run Code Online (Sandbox Code Playgroud)

适用于WinXP - > Win8(包括32/64位版本).

编辑:8/28/2012更新以支持Windows 8. @BenHooper在下面的答案中指出了这一点.请提出他的回答.


and*_*415 39

更多问题

正如@Lectrode所指出的,如果net session在服务器服务停止时尝试运行该命令,则会收到以下错误消息:

The Server service is not started.

More help is available by typing NET HELPMSG 2114
Run Code Online (Sandbox Code Playgroud)

在这种情况下,%errorLevel%变量将设置为2.

注意在安全模式下(有或没有网络),服务器服务未启动.

寻找替代方案

一些东西:

  • 可以在Windows XP及更高版本(32位和64位)上开箱即用;
  • 不接触注册表或任何系统文件/文件夹;
  • 无论系统区域设置如何,都可以
  • 即使在安全模式下也能提供正确的结

所以我启动了一个vanilla Windows XP虚拟机,然后我开始滚动C:\Windows\System32文件夹中的应用程序列表,试图获得一些想法.经过试验和错误,这是我提出的肮脏(双关语)方法:

fsutil dirty query %systemdrive% >nul
Run Code Online (Sandbox Code Playgroud)

fsutil dirty命令需要管理员权限才能运行,否则将失败.%systemdrive%是一个环境变量,它返回安装操作系统的驱动器号.输出重定向到nul,因此被忽略.仅在成功执行时才将%errorlevel%变量设置为0.

以下是文档说的内容:

Fsutil很脏

查询或设置卷的脏位.设置卷的脏位后,autochk会在下次重新启动计算机时自动检查卷的错误.

句法

fsutil dirty {query | set} <VolumePath>
Run Code Online (Sandbox Code Playgroud)

参数

query           Queries the specified volume's dirty bit.
set             Sets the specified volume's dirty bit.
<VolumePath>    Specifies the drive name followed by a colon or GUID.
Run Code Online (Sandbox Code Playgroud)

备注

卷的脏位表示文件系统可能处于不一致状态.可以设置脏位,因为:

  • 该卷是在线的,它有很大的变化.
  • 对卷进行了更改,并且在将更改提交到磁盘之前关闭了计算机.
  • 在卷上检测到腐败.

如果在计算机重新启动时设置了脏位,则chkdsk将运行以验证文件系统完整性并尝试修复卷的任何问题.

例子

要查询驱动器C上的脏位,请键入:

fsutil dirty query C:
Run Code Online (Sandbox Code Playgroud)

进一步的研究

虽然上面的解决方案适用于Windows XP,但值得补充的是Windows 2000和Windows PE(预安装环境)没有附带fsutil.exe,所以我们不得不求助于其他事情.

在我之前的测试中,我注意到运行sfc没有任何参数的命令会导致:

  • 如果您没有足够的权限,则会出错;
  • 可用参数及其用法的列表.

那就是:没有参数,没有派对.我们的想法是,我们可以解析输出并检查是否有任何错误:

sfc 2>&1 | find /i "/SCANNOW" >nul
Run Code Online (Sandbox Code Playgroud)

首先将错误输出重定向到标准输出,然后将其传送到find命令.此时,我们必须寻找自Windows 2000以来所有Windows版本支持唯一参数:.搜索不区分大小写,并通过将其重定向到丢弃输出./SCANNOWnul

以下是文档的摘录:

证监会

扫描并验证所有受保护系统文件的完整性,并使用正确版本替换不正确的版本.

备注

您必须以Administrators组成员的身份登录才能运行sfc.exe.

样本用法

以下是一些粘贴并运行的示例:

Windows XP及更高版本

@echo off

call :isAdmin
if %errorlevel% == 0 (
echo Running with admin rights.
) else (
echo Error: Access denied.
)

pause >nul
exit /b

:isAdmin
fsutil dirty query %systemdrive% >nul
exit /b
Run Code Online (Sandbox Code Playgroud)

Windows 2000/Windows PE

@echo off

call :isAdmin
if %errorlevel% == 0 (
echo Running with admin rights.
) else (
echo Error: Access denied.
)

pause >nul
exit /b

:isAdmin
sfc 2>&1 | find /i "/SCANNOW" >nul
exit /b
Run Code Online (Sandbox Code Playgroud)

适用于

  • Windows 2000
  • Windows XP
  • Windows Vista
  • Windows 7的
  • Windows 8
  • Windows 8.1
    ---
  • Windows PE

  • @ ss64 Windows 10不再为fsutil脏查询&gt; nul返回非零错误级别,但是fsutil脏查询%systemdrive%&gt; nul仍然有效 (2认同)

npo*_*aka 19

还有一个方法

fltmc >nul 2>&1 && (
  echo has admin permissions
) || (
  echo has NOT admin permissions
)
Run Code Online (Sandbox Code Playgroud)

fltmc 自XP以来,每个Windows系统都有命令,所以这应该是非常便携的.


One more solution tested on XP,8.1,7 (unfortunately does not work on all win10 machines - see the comments.) - there's one specific variable =:: which is presented only if the console session has no admin privileges.As it is not so easy to create variable that contains = in it's name this is comparatively reliable way to check for admin permission (and pretty fast as it does not call external executables)

setlocal enableDelayedExpansion
set "dv==::"
if defined !dv! ( 
   echo has NOT admin permissions
) else (
   echo has admin permissions
)
Run Code Online (Sandbox Code Playgroud)

  • 我看到 `=::` 是在 Windows 10 1709 上为非管理员 CMD 定义的。无论如何,这不是一种可靠的方法,您甚至可以轻松地强制在管理员 CMD 会话上定义它:`subst :: c:\ &amp; for % (::) 中的 a 执行 %a &amp; 设置,` (2认同)

And*_*ers 17

>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"&&(
 echo admin...
)
Run Code Online (Sandbox Code Playgroud)


Luc*_*ius 15

替代方案:

@echo off
pushd %SystemRoot%
openfiles.exe 1>nul 2>&1
if not %errorlevel% equ 0 (
    Echo here you are not administrator!
) else (
    Echo here you are administrator!
)
popd
Pause
Run Code Online (Sandbox Code Playgroud)

  • 你能在答案中加上解释吗? (7认同)
  • 虽然这段代码可能会回答这个问题,但您应该为其解释原因. (4认同)
  • 是! 即使用户是超级用户(与“网络会话”不同),这也可以正常工作。但是,不需要推送/弹出。仅运行`openfiles`并检查ERRORLEVEL就足够了。 (2认同)
  • 我一直在使用此解决方案,并且效果很好。问题在于,`openfiles.exe`在WinPE中不起作用,因此脚本将始终返回该用户不是admin。 (2认同)

Phi*_*ilm 13

不仅要检查,而且要自动获得管理员权限,
也就是Win 7/8/8.1 ff的自动UAC.
:以下是一个非常酷的功能,还有一个功能:此批处理代码段不仅会检查管理员权限,还会自动获取它们!(以前的测试,如果生活在支持UAC的操作系统上.)

有了这个技巧,你不需要再用"管理员权限"来批量处理你的批处理文件了.如果您忘记了,要以提升的权限启动它,UAC会自动启动!此外,首先测试,如果操作系统需要/提供UAC,所以它的行为正确,例如Win 2000/XP,直到Win 8.1测试.

@echo off
REM Quick test for Windows generation: UAC aware or not ; all OS before NT4 ignored for simplicity
SET NewOSWith_UAC=YES
VER | FINDSTR /IL "5." > NUL
IF %ERRORLEVEL% == 0 SET NewOSWith_UAC=NO
VER | FINDSTR /IL "4." > NUL
IF %ERRORLEVEL% == 0 SET NewOSWith_UAC=NO


REM Test if Admin
CALL NET SESSION >nul 2>&1
IF NOT %ERRORLEVEL% == 0 (

    if /i "%NewOSWith_UAC%"=="YES" (
        rem Start batch again with UAC
        echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
        echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
        "%temp%\getadmin.vbs"
        del "%temp%\getadmin.vbs"
        exit /B
    )

    rem Program will now start again automatically with admin rights! 
    rem pause
    goto :eof
)
Run Code Online (Sandbox Code Playgroud)

该片段将一些好的批处理模式合并在一起,尤其是(1)Ben Hooper在此线程中的管理测试和(2)在BatchGotAdmin上读取的UAC激活并由robvanderwoude(尊重)在批处站点上引用.(3)对于通过"VER | FINDSTR模式"识别操作系统,我只是找不到参考.)

(关于一些非常小的限制,当"NET SESSION"不能像另一个答案中提到的那样工作时 - 可以随意插入另一个命令.对于我在Windows安全模式或特殊标准服务中运行,这不是一个重要的用例 - 对于某些管理员来说,也许他们是.)


Vit*_*.us 11

我有两种检查特权访问的方法,两者都非常可靠,并且几乎在每个Windows版本中都非常便携.

1.方法

set guid=%random%%random%-%random%-%random%-%random%-%random%%random%%random%

mkdir %WINDIR%\%guid%>nul 2>&1
rmdir %WINDIR%\%guid%>nul 2>&1

IF %ERRORLEVEL%==0 (
    ECHO PRIVILEGED!
) ELSE (
    ECHO NOT PRIVILEGED!
)
Run Code Online (Sandbox Code Playgroud)

这是最可靠的方法之一,因为它的简单性,并且这种非常原始的命令的行为不太可能改变.这不是其他内置CLI工具的情况,例如可以通过管理/网络策略禁用的网络会话,或者更改Windows 10上的输出的fsutils等命令.

*适用于XP及更高版本

2.方法

REG ADD HKLM /F>nul 2>&1

IF %ERRORLEVEL%==0 (
    ECHO PRIVILEGED!
) ELSE (
    ECHO NOT PRIVILEGED!
)
Run Code Online (Sandbox Code Playgroud)

有时你不喜欢触摸用户磁盘的想法,即使它像使用fsutils或创建一个空文件夹一样无害,是不可能的,但如果出现问题,它可能导致灾难性的失败.在这种情况下,您只需检查注册表的权限.

为此,您可以尝试使用默认权限在HKEY_LOCAL_MACHINE上创建一个密钥,您将获得Access DeniedERRORLEVEL == 1,但是如果您以Admin身份运行,它将打印"命令已成功执行"ERRORLEVEL == 0.由于密钥已存在,因此对注册表没有影响.这可能是最快的方式,REG很长一段时间.

*在NT(Win 9X)之前不可用.

*适用于XP及更高版本


工作实例

清除临时文件夹的脚本

@echo off
:main
    echo.
    echo. Clear Temp Files script
    echo.

    call :requirePrivilegies

    rem Do something that require privilegies

    echo. 
    del %temp%\*.*
    echo. End!

    pause>nul
goto :eof


:requirePrivilegies
    set guid=%random%%random%-%random%-%random%-%random%-%random%%random%%random%
    mkdir %WINDIR%\%guid%>nul 2>&1
    rmdir %WINDIR%\%guid%>nul 2>&1
    IF NOT %ERRORLEVEL%==0 (
        echo ########## ERROR: ADMINISTRATOR PRIVILEGES REQUIRED ###########
        echo # This script must be run as administrator to work properly!  #
        echo # Right click on the script and select "Run As Administrator" #
        echo ###############################################################
        pause>nul
        exit
    )
goto :eof
Run Code Online (Sandbox Code Playgroud)


Wil*_*iam 6

我发现使用CMD脚本检查管理员权限的最简洁方法是这样的:

@echo off

REM  Calling verify with no args just checks the verify flag,
REM   we use this for its side effect of setting errorlevel to zero
verify >nul

REM  Attempt to read a particular system directory - the DIR
REM   command will fail with a nonzero errorlevel if the directory is
REM   unreadable by the current process.  The DACL on the
REM   c:\windows\system32\config\systemprofile directory, by default,
REM   only permits SYSTEM and Administrators.
dir %windir%\system32\config\systemprofile >nul 2>nul

REM  Use IF ERRORLEVEL or %errorlevel% to check the result
if not errorlevel 1 echo has Admin privs
if     errorlevel 1 echo has only User privs
Run Code Online (Sandbox Code Playgroud)

此方法仅使用CMD.exe内置,因此它应该非常快.它还会检查进程的实际功能,而不是检查SID或组成员身份,因此会测试有效权限.这可以追溯到Windows 2003和XP.正常用户进程或非高速进程无法通过目录探测器进行管理或提升的进程成功.


Ben*_*oit 5

以下尝试在Windows目录中创建文件.如果它成功,它将删除它.

copy /b/y NUL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
if errorlevel 1 goto:nonadmin
del %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
:admin
rem here you are administrator
goto:eof
:nonadmin
rem here you are not administrator
goto:eof
Run Code Online (Sandbox Code Playgroud)

请注意,06CF2EB6-94E6-4a60-91D8-AB945AE8CF38是今天生成的GUID,并且假定它不可能与现有文件名冲突.


zum*_*ard 5

whoami /groups 在一种情况下不起作用。如果您完全关闭了 UAC(不仅仅是关闭通知),并且您从管理员提示开始,然后发出:

runas /trustlevel:0x20000 cmd
Run Code Online (Sandbox Code Playgroud)

您将运行非高架,但发出:

whoami /groups
Run Code Online (Sandbox Code Playgroud)

会说你被提升了。这是错的。这是错误的原因:

在此状态下运行时,如果 IsUserAdmin ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa376389(v=vs.85).aspx ) 返回 FALSE 并且 UAC 完全禁用,并且 GetTokenInformation返回 TokenElevationTypeDefault ( http://blogs.msdn.com/b/cjacks/archive/2006/10/24/modifying-the-mandatory-integrity-level-for-a-securable-object-in-windows-vista.aspx ) 然后该进程没有运行提升,但whoami /groups声称它是。

实际上,从批处理文件执行此操作的最佳方法是:

net session >nul 2>nul
net session >nul 2>nul
echo %errorlevel%
Run Code Online (Sandbox Code Playgroud)

你应该做net session两次,因为如果有人at事先做了,你会得到错误的信息。


Mat*_*att 5

在为获取管理员权限而编写的批处理脚本Elevate.cmd中(请参阅此链接),我通过以下方式完成此操作:

:checkPrivileges
  NET FILE 1>NUL 2>NUL
  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
Run Code Online (Sandbox Code Playgroud)

针对Windows 7、8、8.1、10甚至Windows XP进行了测试,并且不需要任何资源,例如特殊目录,文件或注册表项。


归档时间:

查看次数:

177267 次

最近记录:

5 年,10 月 前