Question

How can my vbscript detect whether or not it is running in a UAC elevated context?

I have no problem detecting the user, and seeing if the user is within the Administrators group. But this still doesn't answer the question of whether the process has elevated privs or not, when running under Vista or Windows 2008. Please note, I need only to detect this status; not attempt to elevate or (err ..) de-elevate.

Was it helpful?

Solution

The method I finally settled on depends on the fact that Vista and Windows 2008 have the whoami.exe utility, and it detects the integrity level of the user who owns the process. A couple of screenshots help here:

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

You can see that when cmd is running elevated, whoami /groups reports a "High" mandatory integrity level and a different SID than when running non-elevated. In the pic, the top session is normal, the one underneath is running elevated after UAC prompt.

Knowing that, here is the code I used. It essentially checks the OS version, and if it is Vista or Server 2008, calls CheckforElevation which runs whoami.exe /groups, and looks for the string S-1-16-12288 in the output. In this example I just echo status; in the real script I branch to different actions based on the result.

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

OTHER TIPS

Here's my shorter solution:

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

This function is stand alone, and won't display any flashing Console Window when executed.

The solution I am posting is a couple production ready VBScripts that leverage whoami to find this information. One cool thing about them is that they work with XP (for information that is available on XP) if you place a copy of the Resource Kit version of whoami.exe next to the script (or in the system32 folder of each machine).

CSI_IsSession.vbs contains a single function that can tell you almost anything you want to know about UAC or the current session the script is running under.

VBScriptUACKit.vbs (which uses CSI_IsSession.vbs) allows you to selectively prompt for UAC in a script by relaunching itself. Has been designed and debugged to work under many execution scenarios.

Both scripts contain sample code that demonstrates how to use the core script code.

a little bit shorter in 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());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top