1 (изменено: TAOSoft, 2021-12-20 23:37:28)

Тема: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Доброго времени суток уважаемые знатоки! Могу ли я к Вам обратиться за помощью в теории, а по возможности и практической реализации, вот такой задачи, решение для которой я не могу уловить. Есть некий скрипт на vbs (пусть будет script.vbs), есть домен и пользователи (права конечно же на уровне - пользователи). Ситуация 1. Для пользователя необходимо провести ряд настроек, которые выполняет Script.vbs. Запуск скрипта осуществляется путем ПКМ "Запуск от имени" или же через cmd при помощи RunAs. Вопрос: как скрипту узнать, что он выполняется в сессии "сервисного" юзера и как в скрипте отловить сессию рядового юзера? Ситуация 2. Та же схема запуска скрипта, только на уровне терминального сервера. При условии, что одномоментно на сервере может работать одновременно N-ое количество рядовых юзеров. Как скрипту понять что он работает в терминале и из под чьей сессией был осуществен его запуск ? Заранее благодарю за ответ. PS: Смотрел на юзера, который вошел в систему, со стороны objWMI.ExecQuery("Select * from Win32_ComputerSystem") .UserName, ну что то не шибко нравится вариант. Так же смотрел на сессию с позиции CreateObject("WScript.Shell") .ExpandEnvironmentStrings("%SessionName%"), но что то ни то дает при запуске от имени, видимо параметры среды такой вариант не устанавливает и возвращает строку = %SessionName%

2

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Попробуйте такой:

+ открыть спойлер
Option Explicit


Dim objSWbemServicesEx
Dim objSWbemObjectEx

Dim strUserDomain
Dim strUserName

Set objSWbemServicesEx = WScript.CreateObject("WbemScripting.SWbemLocator").ConnectServer(".", "root\cimv2")

For Each objSWbemObjectEx In objSWbemServicesEx.ExecQuery("SELECT * from Win32_Process WHERE ProcessID = '" & CStr(GetScriptProcessID()) & "'")
	objSWbemObjectEx.GetOwner strUserName, strUserDomain
	WScript.Echo strUserDomain & "\" & strUserName
Next

Set objSWbemServicesEx = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
Function GetScriptProcessID()
	With WScript.CreateObject("WScript.Shell").Exec( _
		"""mshta.exe"" " & _
		"""<HTML><HEAD><HTA:APPLICATION APPLICATIONNAME='GetParentPID' " & _
		"WINDOWSTATE='minimize' SHOWINTASKBAR='no'</HEAD></HTML>""" _
	)
		GetScriptProcessID = objSWbemServicesEx.Get("Win32_Process.Handle='" & CStr(.ProcessID) & "'").ParentProcessID
		.Terminate
	End With
End Function
'=============================================================================

3

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

alexii

Увы, показывает Админского юзера, т.е. юзера от имени которого запущен скрипт, но ни того, который залогинился (под чьей сессий произошел запуск)

4 (изменено: Rumata, 2021-12-25 12:04:15)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

andypetr пишет:

USERDOMAIN_ROAMINGPROFILE

Мне кажется, это малоинформативная переменная. На ss64 говорят, что она

The user domain for RDS or standard roaming profile paths.

Например, у меня на рабочем компе ее значение совпадает с USERDOMAIN.

А вот переменная USERNAME указывает на одного и того же пользователя и в обычном режиме и в режиме с повышенными привелегиями.

В своем батнике с громким названием sudo.bat я использую такой код для проверки уровня привилегий:


for /f "tokens=3 delims=\ " %%a in ( '
	call "%SystemRoot%\system32\whoami.exe" /groups ^| findstr /b /c:"Mandatory Label"
' ) do if /i "%%~a" == "system" (
	echo:system
) else if /i "%%~a" == "high" (
	echo:admin
) else if /i "%%~a" == "medium" (
	echo:user
) else (
	echo:others
)

Решение взято отсюда: https://stackoverflow.com/a/27717205/3627676.
Хотя утвержают (здесь - https://stackoverflow.com/a/30921854/3627676), что этот подход не является 100% надежным.

Видимо эта информация весьма ненадежная. Судя по этой ссылке, вывод может быть локализован.

Возможно, медитация над этим C#-кодом как-то поможет реализовать искомое на WSH. Возможно, и не поможет.
https://github.com/gerardog/gsudo/blob/ … #L142-L157


                WindowsIdentity identity = WindowsIdentity.GetCurrent();
                WindowsPrincipal principal = new WindowsPrincipal(identity);
                _cacheIsAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
                return _cacheIsAdmin.Value;
( 2 * b ) || ! ( 2 * b )

5 (изменено: Xameleon, 2021-12-26 16:20:33)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Господа, приветствую. К сожалению, проверить на домене не имею возможности. Подскажите, пожалуйста, такой вариант тоже не подходит ?:


With CreateObject("WScript.Network")
    MsgBox .UserDomain & "\" & .UserName
End With

В принципе на 90% уверен, что раз вы использовали гораздо более сложные конструкции кода, то видимо этот простейший вариант явно не катит. Но вижу, что он не упомянут, поэтому всё же рискнул спросить.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

6

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Xameleon
Это было бы слишком просто. Данный вариант опять же показывает Админского юзера, т.е. юзера от имени которого запущен скрипт, но ни того, который залогинился (под чьей сессий произошел запуск).

7

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Xameleon
можно слово домен вообще не брать в расчет, на локальной тачке создать User1 (входит в группу - Пользователи) и Admin (входит в - Администраторы). Залогинится под User1 и запустить скрипт от имени Admin. Точно такая же история будет

8

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

TAOSoft

Вариант с сайта coderoad:
https://coderoad.ru/20985756/Получить-т … -в-систему

Dim strCmd
    strCmd = "cmd /q /c ""quser console | find /i ""console"" "" "

Dim buffer 
    buffer = WScript.CreateObject("WScript.Shell").Exec(strCmd).StdOut.ReadAll()

Dim c, consoleUserName
    c = InStr(buffer,"console")
    If c > 2 Then
        consoleUserName = Trim(Mid(buffer,2,c-2))
    Else
        consoleUserName = ""
    End If

    WScript.Echo consoleUserName

9 (изменено: TAOSoft, 2021-12-28 08:06:45)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

andypetr

ну что-то в этом есть интересное, только лучше этими командами: query session или qwinsta. Ибо quser знает лишь, если мне память не изменяет , Win10 и Srv 2012 и более.

Но: 1) хотелось бы более элегантный вариант, без вызова сторонних утилит.
2) quser/query session/qwinsta CONSOLE не имеет значение при работе в терминале, возвращает пустое значение. Юзеры же, которые работают на терминале, обзываются сеансами типа rdp-tcp#XXX, поэтому вообще не понять кто из N-ого количества запустил на выполнение скрипт. А как следствие при выполнении скрипта, ему нужно определить в каком режиме работы выполняется сессия пользователя Console или rdp (переменная среды SESSIONNAME у пользователя с повышенными правами вообще отсутствует).

10 (изменено: TAOSoft, 2021-12-28 08:07:03)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

Rumata
Ваше решение определяет права пользователя (RunAs) для которого повышение привилегий сделано. Я считаю , что этот юзер по умолчанию Админ.

11

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

TAOSoft, ознакомьтесь, пожалуйста, с Правилами, отредактируйте свои посты. Обратите внимание на точки в конце предложений.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12 (изменено: Xameleon, 2021-12-27 23:15:57)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

TAOSoft, нашёл вот такой скрипт (немного сократил):


Option Explicit
Dim objWMIService, colComputer, objComputer
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colComputer = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
    Wscript.Echo objComputer.UserName
Next

cсылка

Последовал вашему предложению. Создал пользователя admin и запустил от его имени скрипт в консоли. Авторизован на компьютере как superuser. Вот что вижу в консоли:

+ открыть спойлер

https://i.imgur.com/aZDBLPN.png

P.S На той же странице в ответах приведены примеры кода на случай RDP сессий

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

13

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

TAOSoft пишет:

ибо quser знает лишь, если мне память не изменяет , Win10 и Srv 2012 и более

Как минимум, Windows 7 SP1 знает.

Xameleon, помнится, в Win32_ComputerSystem.UserName будет имя пользователя, залогинившегося последним. Не факт, что им окажется пользователь, от чьего имени было вызвано 'Запуск от имени Администратора'.

Коллеги, мне сдаётся, что проверять надо именно вариант «Пользователь, не обладающий административными привилегиями, вызывает 'Запуск от имени Администратора'», а не «Администратор вызывает 'Запуск от имени Администратора'» и не «Пользователь вызывает 'Запуск от имени другого пользователя'».

14 (изменено: Xameleon, 2021-12-28 03:17:54)

Re: WSH,VBS,JS: Как скриптом определить юзера, запустившего скрипт?

alexii, приветствую !

alexii пишет:

помнится, в Win32_ComputerSystem.UserName будет имя пользователя, залогинившегося последним. Не факт, что им окажется пользователь, от чьего имени было вызвано 'Запуск от имени Администратора'.

А есть возможность проверить ? На ночь глядя никак не соображу как протестить этот кейс.

alexii пишет:

Коллеги, мне сдаётся, что проверять надо именно вариант «Пользователь, не обладающий административными привилегиями, вызывает 'Запуск от имени Администратора'», а не «Администратор вызывает 'Запуск от имени Администратора'» и не «Пользователь вызывает 'Запуск от имени другого пользователя'».

Перечитал раза 3, на третий раз дошло. Тонко подмечено.

А из ответов, которые по ссылке ничего подходящего нет ?

Там для сессий ещё какой-то такой код предлагают:

+ открыть спойлер

strComputer = "." ' " use "." for local computer

Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colSessions = objWMI.ExecQuery _
("Select * from Win32_LogonSession Where LogonType = 2 OR LogonType = 10")

If colSessions.Count = 0 Then
    Wscript.Echo "No interactive users found"
Else
    For Each objSession in colSessions
        If objSession.LogonType = 2 Then
            WScript.Echo "Logon type: Console"
        Else
            WScript.Echo "Logon type: RDP/Terminal Server"
        End If
        Set colList = objWMI.ExecQuery("Associators of " _
            & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "} " _
            & "Where AssocClass=Win32_LoggedOnUser Role=Dependent" )

        For Each objItem in colList
            WScript.Echo "User: " & objItem.Name
            WScript.Echo "FullName: " & objItem.FullName
            WScript.Echo "Domain: " & objItem.Domain
        Next
        Wscript.Echo "Session start time: " & objSession.StartTime
        WScript.Echo
    Next
End If
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !