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

我知道如何使它调用自己与runas,但不知道如何检查管理权限。我所见过的唯一解决方案是粗糙的黑客工作或使用外部程序。好吧,其实我不在乎这是不是一份苦差事,只要它能在Windows XP或更新版本上运行就行。


当前回答

从字面上看,在SE上有几十个答案和相关的问题,所有这些都在这样或那样的方式上存在缺陷,清楚地表明Windows没有提供可靠的内置控制台实用程序。所以,是时候推出你自己的了。

下面的C代码,基于检测程序是否以完全管理员权限运行,在Win2k+1中工作,在任何地方和所有情况下(UAC,域,可传递组…)-因为它在检查权限时与系统本身相同。它用消息(可以用开关使其静音)和退出代码表示结果。

它只需要编译一次,然后你可以复制。exe到处-它只依赖于kernel32.dll和advapi32.dll(我已经上传了一个副本)。

chkadmin.c:

#include <malloc.h>
#include <stdio.h>
#include <windows.h>
#pragma comment (lib,"Advapi32.lib")

int main(int argc, char** argv) {
    BOOL quiet = FALSE;
    DWORD cbSid = SECURITY_MAX_SID_SIZE;
    PSID pSid = _alloca(cbSid);
    BOOL isAdmin;

    if (argc > 1) {
        if (!strcmp(argv[1],"/q")) quiet=TRUE;
        else if (!strcmp(argv[1],"/?")) {fprintf(stderr,"Usage: %s [/q]\n",argv[0]);return 0;}
    }

    if (!CreateWellKnownSid(WinBuiltinAdministratorsSid,NULL,pSid,&cbSid)) {
        fprintf(stderr,"CreateWellKnownSid: error %d\n",GetLastError());exit(-1);}

    if (!CheckTokenMembership(NULL,pSid,&isAdmin)) {
        fprintf(stderr,"CheckTokenMembership: error %d\n",GetLastError());exit(-1);}

    if (!quiet) puts(isAdmin ? "Admin" : "Non-admin");
    return !isAdmin;
}

1MSDN声称api是XP+,但这是错误的。CheckTokenMembership是2k+,另一个甚至更老。最后一个链接还包含一种更复杂的方法,即使在NT中也可以工作。

其他回答

>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"&&(
 echo admin...
)

在批处理脚本Elevate。cmd(见此链接),这是我写来获得管理权限,我已经这样做了:

@echo off

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

脚本的其余部分看起来像这样:

:getPrivileges
  rem need to get admin rights, check batch script Elevate.cmd to see how to do that
  echo You have no admin rights. Cannot continue.
  goto end

:gotPrivileges
  echo You have admin rights. Continuing...
  rem *** do your admin tasks here ***

:end
  pause

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

它利用命令NET FILE需要具有管理权限才能运行的事实,如果成功运行(并且检测到管理权限),将返回错误级别0,否则将返回错误级别> 0。任何消息都被抑制1>NUL 2>NULL。

NET FILE的优点是,它不会更改系统上的任何内容来检测管理权限(就像其他解决方案一样,试图通过在受保护区域中创建注册表项或文件/目录来探测管理权限)。

这里有另一个添加到列表中;-)

(尝试在系统位置创建文件)

CD.>"%SystemRoot%\System32\Drivers\etc\_"
MODE CON COLS=80 LINES=25

IF EXIST "%SystemRoot%\System32\Drivers\etc\_" (

  DEL "%SystemRoot%\System32\Drivers\etc\_"

  ECHO Has Admin privileges

) ELSE (

  ECHO No Admin privileges

)

MODE CON重新初始化屏幕,并在没有权限写入系统位置时压制任何文本/错误。

我有两种检查特权访问的方法,这两种方法都非常可靠,而且几乎在每个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!
)

这是最可靠的方法之一,因为它很简单,而且这个非常原始的命令的行为不太可能改变。这不是其他内置CLI工具的情况,比如可以通过管理/网络策略禁用的net session,或者像fsutils这样在Windows 10上改变输出的命令。

*适用于XP及以后

2. 方法

REG ADD HKLM /F>nul 2>&1

IF %ERRORLEVEL%==0 (
    ECHO PRIVILEGED!
) ELSE (
    ECHO NOT PRIVILEGED!
)

Sometimes you don't like the idea of touching the user disk, even if it is as inoffensive as using fsutils or creating a empty folder, is it unprovable but it can result in a catastrophic failure if something goes wrong. In this scenario you can just check the registry for privileges. For this you can try to create a key on HKEY_LOCAL_MACHINE using default permissions you'll get Access Denied and the ERRORLEVEL == 1, but if you run as Admin, it will print "command executed successfully" and ERRORLEVEL == 0. Since the key already exists it have no effect on the registry. This is probably the fastest way, and the REG is there for a long time. * It's not avaliable on pre 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

替代方案:使用专门为此目的设计的外部实用程序,例如IsAdmin.exe(不受限制的免费软件)。

退出代码:

0 -当前用户不是Administrators组的成员

1 -管理员的当前用户成员和运行提升

2 -管理员的当前用户成员,但未运行提升