如何检查当前批处理脚本是否具有管理权限?
我知道如何使它调用自己与runas,但不知道如何检查管理权限。我所见过的唯一解决方案是粗糙的黑客工作或使用外部程序。好吧,其实我不在乎这是不是一份苦差事,只要它能在Windows XP或更新版本上运行就行。
如何检查当前批处理脚本是否具有管理权限?
我知道如何使它调用自己与runas,但不知道如何检查管理权限。我所见过的唯一解决方案是粗糙的黑客工作或使用外部程序。好吧,其实我不在乎这是不是一份苦差事,只要它能在Windows XP或更新版本上运行就行。
当前回答
本页中四个看似最兼容的方法的集合。第一个真的很天才。从XP开始测试。令人困惑的是,没有标准的命令可以检查管理权限。我猜他们现在只是专注于PowerShell,这对于我自己的大部分工作来说都是无用的。
我把这个批处理称为“exit-if-not-admin”。Cmd `可以从其他批中调用,以确保如果没有给定所需的管理权限,它们不会继续执行。
rem Sun May 03, 2020
rem Methods for XP+ used herein based on:
rem https://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights
goto method1
:method1
setlocal enabledelayedexpansion
set "dv==::"
if defined !dv! goto notadmin
goto admin
:method2
call fsutil dirty query %SystemDrive% >nul
if %ERRORLEVEL%==0 goto admin
goto notadmin
:method3
net session >nul 2>&1
if %ERRORLEVEL%==0 goto admin
goto notadmin
:method4
fltmc >nul 2>&1 && goto admin
goto notadmin
:admin
echo Administrator rights detected
goto end
:notadmin
echo ERROR: This batch must be run with Administrator privileges
pause
exit /b
goto end
:end```
其他回答
下面尝试在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
请注意,06CF2EB6-94E6-4a60-91D8-AB945AE8CF38是今天生成的GUID,假定它与现有文件名不太可能冲突。
whoami /groups在一种情况下不起作用。如果你已经完全关闭了UAC(不仅仅是关闭了通知),并且你从一个管理员提示开始,然后发出:
runas /trustlevel:0x20000 cmd
你将运行非提升,但发出:
whoami /groups
会说你升职了。这是错误的。这就是为什么它是错误的:
当在这种状态下运行时,如果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),那么进程不是在运行elevated,但是whoami /groups声称它是。
实际上,从批处理文件中做到这一点的最好方法是:
net session >nul 2>nul
net session >nul 2>nul
echo %errorlevel%
你应该做两次net session,因为如果有人事先做了at,你会得到错误的信息。
还有两种方法——快速和向后兼容。
fltmc >nul 2>&1 && (
echo has admin permissions
) || (
echo has NOT admin permissions
)
fltmc命令在自XP以来的每个windows系统上都可用,所以这应该是相当可移植的。
在XP,8.1,7上测试的另一个真正快速的解决方案-有一个特定的变量=::,仅当控制台会话没有管理特权时才会显示。因为在它的名称中创建包含=的变量并不容易,这是一种相对可靠的检查管理权限的方法(它不调用外部可执行文件,所以它执行得很好)
setlocal enableDelayedExpansion
set "dv==::"
if defined !dv! (
echo has NOT admin permissions
) else (
echo has admin permissions
)
如果你想通过命令行直接使用,而不是从批处理文件,你可以使用:
set ^"|find "::"||echo has admin permissions
@echo off
:start
set randname=%random%%random%%random%%random%%random%
md \windows\%randname% 2>nul
if %errorlevel%==0 (echo You're elevated!!!
goto end)
if %errorlevel%==1 (echo You're not elevated :(:(
goto end)
goto start
:end
rd \windows\%randname% 2>nul
pause >nul
我将逐行解释代码:
@echo off
如果没有这个选项,用户会对超过一行的代码感到厌烦。
:start
指向程序开始的位置。
set randname=%random%%random%%random%%random%%random%
设置要创建的目录的文件名。
md \windows\%randname% 2>nul
在<DL>:\Windows上创建目录(将<DL>替换为驱动器号)。
if %errorlevel%==0 (echo You're elevated!!!
goto end)
如果ERRORLEVEL环境变量为零,则返回成功消息。 读到最后(不要再继续了)。
if %errorlevel%==1 (echo You're not elevated :(:(
goto end)
如果ERRORLEVEL为1,回显失败消息并返回结束。
goto start
如果文件名已经存在,则重新创建文件夹(否则goto end命令将不让该文件夹运行)。
:end
指定结束点
rd \windows\%randname% 2>nul
删除已创建的目录。
pause >nul
暂停以便用户可以看到消息。
注意:>nul和2>nul是对这些命令的输出进行过滤。
可选择的解决方案:
@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