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

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


当前回答

更多的问题

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

The Server service is not started.

More help is available by typing NET HELPMSG 2114

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

注意:服务器服务在安全模式下(有无联网)不会启动。

寻找替代方案

的东西:

可以在Windows XP及更高版本(32位和64位)上运行; 不涉及注册表或任何系统文件/文件夹; 与系统区域无关的工作; 即使在安全模式下也能给出正确的结果。

于是我启动了一台普通的Windows XP虚拟机,开始在C:\Windows\System32文件夹中滚动应用程序列表,试图获得一些想法。经过反复试验,这是我想出的肮脏(双关语)方法:

fsutil dirty query %systemdrive% >nul

fsutil dirty命令需要管理员权限才能运行,否则将失败。“%systemdrive%”为环境变量,返回安装操作系统的盘符。输出被重定向为null,因此被忽略。%errorlevel%变量只有在成功执行时才会被设置为0。

以下是文档的内容:

Fsutil dirty Queries or sets a volume's dirty bit. When a volume's dirty bit is set, autochk automatically checks the volume for errors the next time the computer is restarted. Syntax fsutil dirty {query | set} <VolumePath> Parameters 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. Remarks A volume's dirty bit indicates that the file system may be in an inconsistent state. The dirty bit can be set because: The volume is online and it has outstanding changes. Changes were made to the volume and the computer was shut down before the changes were committed to the disk. Corruption was detected on the volume. If the dirty bit is set when the computer restarts, chkdsk runs to verify the file system integrity and to attempt to fix any issues with the volume. Examples To query the dirty bit on drive C, type: fsutil dirty query C:

进一步的研究

虽然上面的解决方案从Windows XP开始工作,值得补充的是,Windows 2000和Windows PE(预安装环境)没有附带fsutil.exe,所以我们必须求助于其他东西。

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

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

那就是:没有参数,没有聚会。这个想法是我们可以解析输出并检查我们是否得到了错误以外的任何东西:

sfc 2>&1 | find /i "/SCANNOW" >nul

错误输出首先被重定向到标准输出,然后通过管道传输到find命令。此时,我们必须寻找自Windows 2000以来所有Windows版本都支持的唯一参数:/SCANNOW。搜索是不区分大小写的,输出被重定向为nul而被丢弃。

以下是文档的节选:

香港证监会 扫描并验证所有受保护的系统文件的完整性,将错误的版本替换为正确的版本。 讲话 您必须作为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

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

适用于

Windows 2000 Windows XP Windows Vista Windows 7 Windows 8 Windows 8.1 --- Windows体育

其他回答

whoami /groups | find "S-1-16-12288" > nul
if not errorlevel 1 (
  echo ...  connected as 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的优点是,它不会更改系统上的任何内容来检测管理权限(就像其他解决方案一样,试图通过在受保护区域中创建注册表项或文件/目录来探测管理权限)。

PowerShell有人吗?

param (
    [string]$Role = "Administrators"
)

#check for local role

$identity  = New-Object Security.Principal.WindowsIdentity($env:UserName)
$principal = New-Object Security.Principal.WindowsPrincipal($identity)

Write-Host "IsInRole('$Role'): " $principal.IsInRole($Role)

#enumerate AD roles and lookup

$groups = $identity::GetCurrent().Groups
foreach ($group in $groups) {
    $trans = $group.Translate([Security.Principal.NTAccount]);
    if ($trans.Value -eq $Role) {
       Write-Host "User is in '$Role' role"
    }
}

使用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进程或提升进程成功。

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