Vbscript检测UAC是否升高

时间:2008-10-25 03:12:19

标签: windows-vista vbscript windows-server-2008 uac

我的vbscript如何检测它是否在UAC提升的上下文中运行?

检测用户没问题,看看用户是否在Administrators组中。但是,当在Vista或Windows 2008下运行时,这仍然无法解决该进程是否提升了私有性的问题。请注意,我只需要检测这种状态;不要试图提升或(错误地)降低。

4 个答案:

答案 0 :(得分:6)

我最终确定的方法取决于Vista和Windows 2008具有whoami.exe实用程序的事实,并且它检测拥有该进程的用户的完整性级别。这里有两个截图帮助:

WHOAMI, normal and elevated, on Vista http://lh3.ggpht.com/_Svunm47buj0/SQ6ql4iNjPI/AAAAAAAAAeA/iwbcSrAZqRg/whoami%20-%20adminuser%20-%20groups%20-%20cropped.png?imgmax=512

您可以看到,当cmd正在运行时,whoami / groups会报告“高”强制完整性级别和不同于运行非提升的SID。在图片中,顶部会话是正常的,在UAC提示后,下面的会话正在升高。

知道,这是我使用的代码。它基本上检查操作系统版本,如果是Vista或Server 2008,则调用运行whoami.exe / groups的CheckforElevation,并在输出中查找字符串S-1-16-12288。在这个例子中,我只是回显状态;在真实的脚本中,我根据结果分支到不同的行为。

sub GetOSVersion
Dim strComputer, oWMIService, colOSInfo, oOSProperty, strCaption, strOSFamily
strComputer = "."
Set oWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOSInfo = oWMIService.ExecQuery("Select * from Win32_OperatingSystem")
'I hate looping through just to get one property. But dunno another way!
For Each oOSProperty in colOSInfo 
  strCaption = oOSProperty.Caption 
Next
If InStr(1,strCaption, "Vista", vbTextCompare) Then strOSFamily = "Vista"
If InStr(1,strCaption, "2008", vbTextCompare) Then strOSFamily = "2008"
If InStr(1,strCaption, "XP", vbTextCompare) Then strOSFamily = "XP"
If InStr(1,strCaption, "2003", vbTextCompare) Then strOSFamily = "2003"
If InStr(1,strCaption, "2000", vbTextCompare) Then strOSFamily = "2000"
If strOSFamily = "" Then 
    Wscript.Echo "No known OS found. (Script can detect Windows 2000, 2003, XP, Vista, 2008.)" 
Else 
    Wscript.Echo "OS Family = " & strOSFamily
End If
Select Case strOSFamily 'if Vista/2008 then call CheckforElevation
Case "Vista"
    CheckforElevation
Case "2008"
    CheckforElevation
Case Else
    Exit Sub
End Select
end sub

sub CheckforElevation 'test whether user has elevated token 
Dim oShell, oExecWhoami, oWhoamiOutput, strWhoamiOutput, boolHasElevatedToken
Set oShell = CreateObject("WScript.Shell")
Set oExecWhoami = oShell.Exec("whoami /groups")
Set oWhoamiOutput = oExecWhoami.StdOut
strWhoamiOutput = oWhoamiOutput.ReadAll
If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then boolHasElevatedToken = True
If boolHasElevatedToken Then
    Wscript.Echo "Current script is running with elevated privs."
Else
    Wscript.Echo "Current script is NOT running with elevated privs."
End If
end sub

答案 1 :(得分:5)

这是我的简短解决方案:

Function IsElevated
    IsElevated = CreateObject("WScript.Shell").Run("cmd.exe /c ""whoami /groups|findstr S-1-16-12288""", 0, true) = 0
End function 

此功能是独立的,执行时不会显示任何闪烁的控制台窗口。

答案 2 :(得分:4)

我发布的解决方案是一些生产就绪的VBScripts,利用whoami来查找此信息。关于它们的一个很酷的事情是,如果你在脚本旁边(或在每台机器的system32文件夹中)放置一个whokg.exe资源工具包版本的副本,它们可以使用XP(对于XP上可用的信息)。 / p>

CSI_IsSession.vbs包含一个函数,可以告诉您几乎所有关于UAC或脚本运行的当前会话的信息。

VBScriptUACKit.vbs(使用CSI_IsSession.vbs)允许您通过重新启动自己选择性地在脚本中提示UAC。已经过设计和调试,可以在许多执行场景下工作。

这两个脚本都包含演示如何使用核心脚本代码的示例代码。

答案 3 :(得分:0)

WSH Jscript

稍微短一些
function isElevated(){
    var strCaption  = "";
    for (var enumItems=new Enumerator(GetObject("winmgmts:\\\\.\\root\\CIMV2").ExecQuery("Select * from Win32_OperatingSystem")); !enumItems.atEnd(); enumItems.moveNext()) {
        strCaption  +=  enumItems.item().Caption;
    }
    if(/Vista|2008|Windows\s7|Windows\s8/.test(strCaption)){
        return (new ActiveXObject("WScript.Shell").run('cmd.exe /c "whoami /groups|findstr S-1-16-12288"', 0, true)) == 0;
    }else{return true}
}    

WScript.Echo(isElevated());