7

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

我检测用户并查看用户是否在管理员组中没有问题。但这仍然不能回答在 Vista 或 Windows 2008 下运行时进程是否提升了 privs 的问题。请注意,我只需要检测此状态;不要试图提升或(错误..)去提升。

4

4 回答 4

7

我最终确定的方法取决于 Vista 和 Windows 2008 都有 whoami.exe 实用程序,它会检测拥有该进程的用户的完整性级别。一些屏幕截图在这里有所帮助:

WHOAMI,正常和升高,在 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
于 2008-11-03T07:35:59.023 回答
7

这是我较短的解决方案:

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

该函数是独立的,执行时不会显示任何闪烁的控制台窗口。

于 2013-11-10T20:24:52.653 回答
4

我发布的解决方案是几个可用于生产的 VBScript,它们利用 whoami 来查找此信息。关于它们的一个很酷的事情是,如果您将资源工具包版本 whoami.exe 的副本放在脚本旁边(或每台机器的 system32 文件夹中),它们可以与 XP 一起使用(有关 XP 上可用的信息)。

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

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

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

于 2010-05-25T14:47:44.833 回答
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());
于 2015-05-27T13:59:37.103 回答