2008-10-25 22 views
6

¿Cómo puede mi vbscript detectar si se está ejecutando o no en un contexto elevado de UAC?Vbscript detectar si UAC-elevated

No tengo ningún problema para detectar al usuario y ver si el usuario está dentro del grupo Administradores. Pero esto todavía no responde a la pregunta de si el proceso tiene privilegios elevados o no, cuando se ejecuta con Vista o Windows 2008. Tenga en cuenta que solo necesito detectar este estado; no intente elevar o (err ..) de-elevar.

+0

Heads Up, una respuesta mucho mejor que la que se ha añadido aceptado a continuación. – Tomalak

Respuesta

5

El método que finalmente establecí depende del hecho de que Vista y Windows 2008 tienen la utilidad whoami.exe y detecta el nivel de integridad del usuario que posee el proceso. Un par de capturas de pantalla ayuda aquí:

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

Se puede ver que cuando se está ejecutando cmd elevado, whoami/grupos reporta un nivel de integridad obligatoria "alta" y un SID diferente que cuando se ejecuta no elevada. En la imagen, la sesión superior es normal, la que está debajo se está ejecutando elevada después de la solicitud de UAC.

Sabiendo eso, aquí está el código que utilicé. Básicamente comprueba la versión del sistema operativo, y si es Vista o Server 2008, llama a CheckforElevation, que ejecuta whoami.exe/groups, y busca la cadena S-1-16-12288 en la salida. En este ejemplo, solo echo estado; en el guión real me ramifico a diferentes acciones basadas en el resultado.

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

Por supuesto, esto es una mierda. Sería más limpio tener acceso a la API GetTokenInformation. Pero aparentemente eso está fuera de los límites de VBscript. Oh, bueno, hacemos lo que podemos. – quux

4

La solución que estoy publicando es un par de VBScripts de producción preparados que aprovechan a whoami para encontrar esta información. Una cosa genial de ellos es que funcionan con XP (para información que está disponible en XP) si coloca una copia de la versión del Kit de recursos de whoami.exe junto al script (o en la carpeta system32 de cada máquina).

CSI_IsSession.vbs contiene una sola función que le puede decir casi cualquier cosa que desee saber sobre UAC o la sesión actual bajo la cual se ejecuta el script.

VBScriptUACKit.vbs (que usa CSI_IsSession.vbs) le permite solicitar selectivamente UAC en un script relancándose a sí mismo. Ha sido diseñado y depurado para funcionar bajo muchos escenarios de ejecución.

Ambos scripts contienen un código de muestra que muestra cómo usar el código del script del núcleo.

+0

¡Guau, realmente investigaste esto! El artículo del blog en su enlace CSI_IsSession.vbs está lleno de buena información; gracias por eso. Sin embargo, todavía es una pena que vbscript no pueda hacer esto sin una llamada a whoami.exe. – quux

4

aquí está mi solución más corto:

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

Esta función es autolimpiante, y no mostrar ninguna ventana de la consola de parpadear cuando se ejecuta.

+1

Excelente, esto es mejor que la respuesta aceptada. – Tomalak

0

un poco más corto en 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());