2008-10-25 11 views
6

Wie kann mein VBScript erkennen, ob es in einem UAC erhöhten Kontext ausgeführt wird?Vbscript erkennt, ob UAC-erhöht

Ich habe kein Problem, den Benutzer zu erkennen und zu sehen, ob der Benutzer in der Gruppe Administratoren ist. Aber das beantwortet immer noch nicht die Frage, ob der Prozess privats erhöht hat oder nicht, wenn unter Vista oder Windows 2008 ausgeführt. Bitte beachten Sie, ich brauche nur erkennen diesen Status; Versuchen Sie nicht zu erhöhen oder (err ..) zu heben.

+0

Heads up, eine viel bessere Antwort als die akzeptierte unter hinzugefügt wurde. – Tomalak

Antwort

5

Die Methode, auf die ich mich schließlich festgelegt habe, hängt von der Tatsache ab, dass Vista und Windows 2008 das Dienstprogramm whoami.exe enthalten und das Integritätslevel des Benutzers erkennt, der den Prozess besitzt. Ein paar Screenshots helfen hier:

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

Sie können sehen, dass, wenn cmd erhöht läuft, whoami/groups meldet einen „High“ obligatorischen Integritätslevel und einen anderen SID als beim Laufen nicht erhöht. Im Bild ist die oberste Sitzung normal, die darunterliegende wird nach der UAC-Eingabeaufforderung erhöht angezeigt.

Wissen, das ist der Code, den ich verwendet habe. Es prüft im Wesentlichen die Betriebssystemversion, und wenn es Vista oder Server 2008 ist, ruft CheckforElevation whofami.exe/groups auf und sucht in der Ausgabe nach der Zeichenfolge S-1-16-12288. In diesem Beispiel gebe ich nur den Status zurück; Im realen Skript verzweige ich basierend auf dem Ergebnis zu verschiedenen Aktionen.

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 
+0

Natürlich ist das nervtötend. Es wäre sauberer, Zugriff auf die GetTokenInformation-API zu haben. Aber anscheinend ist das für VBscript nicht möglich. Na gut - wir machen was wir können. – quux

4

Die Lösung, die ich poste, ist ein paar production ready VBScripts, die whoami nutzen, um diese Informationen zu finden. Eine coole Sache an ihnen ist, dass sie mit XP arbeiten (für Informationen, die auf XP verfügbar sind), wenn Sie eine Kopie der Resource Kit-Version von whoami.exe neben dem Skript (oder im system32-Ordner jedes Rechners) platzieren.

CSI_IsSession.vbs enthält eine einzelne Funktion, die Ihnen fast alles sagen kann, was Sie über UAC oder die aktuelle Sitzung, unter der das Skript läuft, wissen möchten.

VBScriptUACKit.vbs (die CSI_IsSession.vbs verwendet) können Sie selektiv zur UAC in einem Skript aufgefordert werden, indem Sie sich neu starten. Wurde entwickelt und getestet, um unter vielen Ausführungsszenarien zu arbeiten.

Beide Skripts enthalten Beispielcode, der veranschaulicht, wie der Kernskriptcode verwandt wird.

+0

Wow, du hast wirklich nachgeforscht! Der Blog-Artikel auf Ihrem CSI_IsSession.vbs-Link ist voll mit guten Informationen; Dank dafür. Es ist immer noch ein Mist, dass VBScript das nicht ohne Aufruf von whoami.exe tun kann. – quux

4

Hier ist meine kürzere Lösung:

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

Diese Funktion steht allein ist, und wird jedes blinkende Konsolenfenster nicht angezeigt, wenn sie ausgeführt werden.

+1

Ausgezeichnet, das ist besser als die angenommene Antwort. – Tomalak

0

etwas kürzer 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()); 
Verwandte Themen