Pergunta

Como pode o meu vbscript detectar se ou não ele está sendo executado em um contexto de elevada UAC? ??

Não tenho nenhum problema detectar o usuário, e ver se o usuário está dentro do grupo de administradores. Mas isso ainda não responde à questão de privs se o processo tem elevadas ou não, quando executados no Vista ou Windows 2008. Nota Por favor, preciso apenas para detectar essa condição; Não tente elevar ou (err ..) de-elevar.

Foi útil?

Solução

O método que eu finalmente liquidada em depende do fato de que o Vista e Windows 2008 tem o utilitário whoami.exe, e detecta o nível de integridade do usuário que possui o processo. Um par de screenshots ajudar aqui:

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

Você pode ver que quando cmd está funcionando elevado, whoami / groups relata um nível de integridade "High" obrigatório e um SID diferente do que quando executado não elevado. Na foto, a sessão de topo é normal, o baixo está funcionando elevada após UAC alerta.

Sabendo que, aqui está o código que eu usei. Essencialmente verifica a versão OS, e se for Vista ou Server 2008, chama CheckforElevation que corre grupos / Whoami.exe, e olha para a cadeia S-1-16-12288 na saída. Neste exemplo eu apenas eco estatuto; no ramo I roteiro real para diferentes acções com base no 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

Outras dicas

Aqui está a minha solução mais curto:

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

Esta função é ficar sozinho, e não exibir qualquer janela do console piscar quando executado.

A solução que eu estou postando é uma produção casal VBScripts prontos que a alavancagem whoami para encontrar esta informação. Um fresco coisa sobre eles é que eles funcionam com o XP (para a informação que está disponível no XP) se você colocar uma cópia da versão Resource Kit de whoami.exe ao lado do roteiro (ou na pasta system32 de cada máquina).

CSI_IsSession.vbs contém uma única função que pode dizer-lhe quase tudo que quiser para saber sobre UAC ou a sessão atual do script está sendo executado.

VBScriptUACKit.vbs (que usa CSI_IsSession.vbs) permite que você seletivamente prompt para UAC em um roteiro de relançamento si. Foi concebido e depurado de trabalhar sob muitos cenários de execução.

Ambos os scripts contêm código de exemplo que demonstra como usar o código de script núcleo.

Um pouco mais curto em 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());
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top