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

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


当前回答

编辑:版权已指出这是不可靠的。使用UAC批准读访问将允许dir成功。我有更多的脚本来提供另一种可能性,但它不是只读的。

reg query "HKLM\SOFTWARE\Foo" >NUL 2>NUL && goto :error_key_exists
reg add "HKLM\SOFTWARE\Foo" /f >NUL 2>NUL || goto :error_not_admin
reg delete "HKLM\SOFTWARE\Foo" /f >NUL 2>NUL || goto :error_failed_delete
goto :success

:error_failed_delete
  echo Error unable to delete test key
  exit /b 3
:error_key_exists
  echo Error test key exists
  exit /b 2
:error_not_admin
  echo Not admin
  exit /b 1
:success
  echo Am admin

旧答案如下

警告:不可靠


根据and31415提出的其他一些很好的答案和观点,我发现我是以下人的粉丝:

dir "%SystemRoot%\System32\config\DRIVERS" 2>nul >nul || echo Not Admin

依赖性少,速度快。

其他回答

使用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

这个方法只使用CMD.exe内置程序,所以它应该非常快。它还检查流程的实际功能,而不是检查sid或组成员关系,因此测试有效的权限。这可以追溯到Windows 2003和XP。普通用户进程或非提升进程目录探测失败,而Admin进程或提升进程成功。

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

退出代码:

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

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

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

@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是对这些命令的输出进行过滤。

whoami /groups | find "S-1-16-12288" > nul
if not errorlevel 1 (
  echo ...  connected as admin
)

可选择的解决方案:

@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