windows-vista vbscript windows-server-2008 uac

windows vista - Vbscript detecta si UAC está elevado



windows-vista windows-server-2008 (4)

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

No tengo problemas 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.


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 ayudan aquí:

WHOAMI, normal y elevado, en Vista http://lh3.ggpht.com/_Svunm47buj0/SQ6ql4iNjPI/AAAAAAAAeA/iwbcSrAZqRg/whoami%20-%20adminuser%20-%20groups%20-%20cropped.png?imgmax=512

Puede ver que cuando cmd se ejecuta elevado, whoami / groups informa un nivel de integridad obligatorio "Alto" y un SID diferente que cuando se ejecuta no elevado. 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


La solución que estoy publicando es un par de VBScripts preparados para producción 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 en la que 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 demuestra cómo usar el código del script central.


Aquí está mi solución más corta:

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 autónoma y no mostrará ninguna ventana de consola parpadeante cuando se ejecute.


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());