Как мой vbscript определить, работает ли он в контексте с повышенными правами UAC?
У меня нет проблем с обнаружением пользователя и проверкой, входит ли он в группу администраторов. Но это все еще не дает ответа на вопрос, имеет ли процесс повышенные привилегии при работе под Vista или Windows 2008. Обратите внимание, мне нужно только обнаруживать этот статус; не пытайтесь поднять или (ошибиться ...) опустить.





Метод, на котором я остановился, зависит от того, что в Vista и Windows 2008 есть утилита whoami.exe, которая определяет уровень целостности пользователя, владеющего процессом. Здесь поможет пара скриншотов:
Вы можете видеть, что при запуске cmd с повышенными правами whoami / groups сообщает об обязательном уровне целостности «High» и другом SID, чем при запуске без повышенных прав. На рисунке верхний сеанс нормальный, нижний - запущенный после запроса UAC.
Зная это, вот код, который я использовал. По сути, он проверяет версию ОС и, если это Vista или Server 2008, вызывает CheckforElevation, который запускает whoami.exe / groups, и ищет в выходных данных строку S-1-16-12288. В этом примере я просто повторяю статус; в реальном скрипте я перехожу к различным действиям в зависимости от результата.
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
Конечно, это отстой. Было бы проще получить доступ к API GetTokenInformation. Но, видимо, это выходит за рамки VBscript. Ну что ж - мы делаем, что можем.
Решение, которое я публикую, - это пара готовых сценариев VBScripts, которые используют whoami для поиска этой информации. В них есть одна интересная особенность: они работают с XP (информация доступна по XP), если вы поместите копию whoami.exe из Resource Kit версии рядом со сценарием (или в папке system32 на каждой машине).
CSI_IsSession.vbs содержит единственную функцию, которая может сказать вам почти все, что вы хотите знать о UAC или текущем сеансе, в котором выполняется скрипт.
VBScriptUACKit.vbs (который использует CSI_IsSession.vbs) позволяет выборочно запрашивать UAC в сценарии путем перезапуска самого себя. Был разработан и отлажен для работы во многих сценариях выполнения.
Оба сценария содержат образец кода, демонстрирующий, как использовать основной код сценария.
Вау, вы действительно исследовали это! Статья в блоге по вашей ссылке CSI_IsSession.vbs наполнена полезной информацией; Спасибо за это. Тем не менее, это все еще облом, что vbscript не может сделать это без вызова whoami.exe.
Вот мое более короткое решение:
Function IsElevated
IsElevated = CreateObject("WScript.Shell").Run("cmd.exe /c ""whoami /groups|findstr S-1-16-12288""", 0, true) = 0
End function
Эта функция является автономной и при выполнении не отображает ни одного мигающего окна консоли.
Отлично, это лучше принятого ответа.
немного короче в 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());
Внимание, ниже был добавлен гораздо лучший ответ, чем принятый.