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
The way I have gotten this to work in the past is by using PsKill from Microsoft's SysInternals. PsKill can terminate system processes and any processes that are locked.
You need to download the executable and place it in the same directory as the script or add it's path in the WshShell.Exec call. Here's your sample code changed to use PsKill.
Const strComputer = "."
Set WshShell = CreateObject("WScript.Shell")
Dim objWMIService, colProcessList
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'Process.exe'")
For Each objProcess in colProcessList
WshShell.Exec "PSKill " & objProcess.ProcessId
Next
Best Answer
The
Win32_Process
class provides access to both 32-bit and 64-bit processes when the script is run from a 64-bit command shell.If this is not an option for you, you can try using the
taskkill
command: