如何检查当前批处理脚本是否具有管理权限?
我知道如何使它调用自己与runas,但不知道如何检查管理权限。我所见过的唯一解决方案是粗糙的黑客工作或使用外部程序。好吧,其实我不在乎这是不是一份苦差事,只要它能在Windows XP或更新版本上运行就行。
如何检查当前批处理脚本是否具有管理权限?
我知道如何使它调用自己与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 -管理员的当前用户成员,但未运行提升