Как узнать имя пользователя на удаленном компьютере?

25.03.2021

itpro

Active Directory, PowerShell, Windows 10, Windows Server 2016

комментариев 7
Довольно часто администратору нужно быстро узнать имя пользователя, который выполнил вход на удаленном компьютере Windows. В это статье мы рассмотрим несколько утилит и PowerShell скриптов, которые помогут вам узнать имена пользователей, залогиненых на удаленных компьютерах в сети.
Утилиты PSLoggedOn и Qwinsta
В комплекте утилит SysInternals PSTools от Microsoft есть консольная утилита PSLoggedOn.exe, которую можно использовать для получения имени пользователя, который вошел на удаленный компьютер, а также список подключенных к нему SMB сеансов.
Скачайте утилиту и запустите ее в формате:

Как вы видите, утилита вернула имя залогиненного пользователя (Users logged on locally), а также список пользователей, которые по сети используют ресурсы с этого компьютера (Users logged on via resource shares).
Если нужно получить только имя пользователя, вошедшего локально, используйте опцию –l:
Psloggedon.exe \\wks215s1 –l
Утилита Psloggedon подключается к реестру и проверяет в нем имя пользователя, вошедшего локально. Для этого должна быть включена служба RemoteRegistry. Вы можете запустить ее и настроить автозапуск службы с помощью PowerShell:
Set-Service RemoteRegistry –startuptype automatic –passthru
Start-Service RemoteRegistry
Также можно получить список сессий на удаленном компьютере с помощью встроенной утилиты qwinsta . Эта утилита должна быть знакома любому администратору, управляющему терминальными серверами с Remote Desktop Services. Чтобы получить список сессий с удаленного компьютера, выполнит команду:

Утилита возвращает список всех сессий (активных и отключенных по таймауту) на RDS сервере или десктопной редакции Windows 10 (даже если вы разрешили к ней множественные RDP подключения).
Если при подключении к удаленному серверу через qwinsta вы получаете ошибку Error 5 Access Denied, проверьте что на удаленном компьютере разрешено удаленное управление пользователями через RPC. Включите, если нужно через реестр следующей командой или через GPO:
reg add «HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server» /v «AllowRemoteRPC» /t «REG_DWORD» /d «1» /f
Получаем имя пользователя на удаленном компьютере через PowerShell
Вы можете получить имя пользователя, который залогинен на компьютере через WMI класс Win32_ComputerSystem. Откройте консоль PowerShell и выполните команду:
Get-WmiObject -class Win32_ComputerSystem | Format-List Username
Команда вернула имя пользователя, который выполнил вход на компьютер.

У командлета Get-WmiObject есть параметр –ComputerName, который можно использовать для получения доступа к WMI объектам на удаленном компьютере. Следующая команда вернет имя пользователя с удаленного компьютера:
(Get-WmiObject -class Win32_ComputerSystem –ComputerName wks215s1).Username

Данная команда показывает только пользователя, вошедшего на консоль (не через RDP).
Также для получения информации с удаленных компьютеров можно использовать PSRemoting с помощью командлета Invoke-Command.
Если нужно получить только имя пользователя на компьютере (без домена), воспользуетесь следующими командами:
$userinfo = Get-WmiObject -ComputerName ‘wks215s1’ -Class Win32_ComputerSystem
$user = $userinfo.UserName -split ‘\\’
$user[1]

В современных версиях PowerShell Core (pwsh.exe) вместо Get-WmiObject нужно использовать CIM командлет Get-CimInstance:
Get-CimInstance –ComputerName wks215s1 –ClassName Win32_ComputerSystem | Select-Object UserName
(Get-CimInstance -ComputerName wks215s1 -ClassName Win32_ComputerSystem).CimInstanceProperties | where| select value
![]()
GetCiminstance использует WinRM для подключения к удаленным компьютерам, поэтому на них нужно включить и настроить WinRM через GPO или командой:
PowerShell скрипт для проверки пользователей на удаленных компьютерах
Если вам нужно собрать информацию о пользователях сразу с нескольких компьютерах, можете использовать следующую PowerShell функцию получить имена пользователей.
function Get-LoggedUser < [CmdletBinding()] param ( [string[]]$ComputerName ) foreach ($comp in $ComputerName) < $output = @$output.UserName = (Get-WmiObject -Class win32_computersystem -ComputerName $comp).UserName [PSCustomObject]$output > >
На вход функции Get-LoggedUser нужно передать имена компьютеров, на которых нужно проверить имена пользователей:

Если для какого-то компьютера функция вернула пустое имя пользователя, значит на компьютер никто не залогинен.
Можно получить имена пользователей, которые работают на компьютерах в домене Active Directory. Для получения списка компьютеров нужно использовать командлет Get-ADComputer. В следующем примере мы получим имена пользователей, которые работают за активными компьютерами в определенном OU домена. Чтобы скрипт работал быстрее перед тем, как обратится к обратится к удаленному компьютеру, я добавил проверку его доступности по сети через ICMP пинг с помощью командлета Test-NetConnection:
function Get-LoggedUser < [CmdletBinding()] param ( [string[]]$ComputerName ) foreach ($comp in $ComputerName) < if ((Test-NetConnection $comp -WarningAction SilentlyContinue).PingSucceeded -eq $true) < $output = @$output.UserName = (Get-WmiObject -Class win32_computersystem -ComputerName $comp).UserName > else < $output = @$output.UserName = "offline" > [PSCustomObject]$output > > $computers = (Get-AdComputer -Filter -SearchBase 'OU=Kazan,DC=winitpro,DC=loc').Name Get-LoggedUser $computers |ft -AutoSize

Также обратите внимание, что вы можете хранить в свойствах компьютеров в AD имя пользователя, который выполнил вход. Для этого можно использовать логон скрипт, описанный в статье “Set-ADComputer: добавляем информацию о пользователе в свойства компьютеров AD”
После этого вам не нужно сканировать все компьютеры, чтобы найти где залогинен определенный пользователь. Можно найти компьютер пользователя простым запросом к Active Directory:
$user=’dvpetrov’
$user_cn=(get-aduser $user -properties *).DistinguishedName
Get-ADComputer -Filter «ManagedBy -eq ‘$user_cn'» -properties *|select name,description,managedBy|ft
Предыдущая статья Следующая статья
Powershell как узнать кто залогинен на пк
Сообщения: 3665
Благодарности: 1563
Get-WMIObject -Class Win32_ComputerSystem -Computer "Comp1"|Select-Object Username
——-
Как сообщить о том, что моя проблема решена?
не оказываю техподдержку через ПМ/ICQ/Mail — для этого есть форум
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.
Сообщения: 1
Благодарности: 0
ваш способ работает, если вы запускаете с Comp1
если вы с Comp1 будете смотреть Comp2 — поле будет пустым Username
ваш способ к сожалению не актуален
Сообщения: 27449
Благодарности: 8086
soadm, если так?
Цитата shs:
| Принимать же значение пусто он может, если на опрашиваемом компьютере никто не залогонен, либо произошла ошибка опроса, или, если пользователь, в контексте которого работает скрипт, не обладает правами локадмина на опрашиваемом компьютере. |
P.S. Где-то я видел и более подробное описание требований.
Сообщения: 29
Благодарности: 0
(Get-wmiobject -Computername Комп1 win32_computerSystem).Username
Это есле с другого компа.
Сообщения: 258
Благодарности: 1
WMI запрос SELECT UserName FROM Win32_ComputerSystem
выдает кто залогинен на компе, если это RDP подключение то нет, если множественные тоже нет
Подскажите как показывать всех юзеров.
Для примера Advanced IP Scanner, умеет это отображать, причем он отображает учетку пользователя в списке даже если под ней запущен один единственный процесс cbService.exe от кобиан бекап.
Каким запросом он это узнает?

Нужно решение или на WMI или на PowerShell ,чтобы результат выводился в проге для мониторинга Algorius Net Viewer
Сообщения: 6431
Благодарности: 1444
| Конфигурация компьютера | |
| Процессор: Intel Core i5-8259U @ 2.30GHz | |
| Материнская плата: Intel NUC8BEB | |
| Память: Patriot 2400 C15 Series DDR4-2400, 32 GB | |
| HDD: Samsung SSD 970 EVO Plus 500 GB, M.2 | |
| Видеокарта: Intel Iris Plus Graphics 655 | |
| Звук: Behringer UCA222 + M-Audio Studiophile AV 40 | |
| Монитор: BenQ G900 (19″ LCD, 5:4) | |
| ОС: Windows 11 Pro x64 |
Удобного и простого способа нет. Advanced IP Scanner показывает непонятно что, это не те, кто сейчас работает в системе.
Можно попробовать так:
Invoke-Command -ComputerName PC1234 -ScriptBlock < try <(quser.exe 2>$null |select -Skip 1).trim() -replace ">" -replace "\s+.*"> catch >
Для этого на компе должен работать удалённый доступ для PS (включить — winrm qc)
У quser.exe есть ключ /SERVER, который позволяет запрашивать список пользователей удалённо, но этот способ уже давно не работает, т. к. отключен по соображениям безопасности.
Последний раз редактировалось DJ Mogarych, 11-11-2022 в 10:26 . Причина: учёл вариант, когда никого нет
Windows: узнаём, кто где залогинен

Хорошо, если у вас есть инструмент а-ля BgInfo или ваши пользователи знают про шорткат Windows+Pause/Break и умеют его нажимать. Встречаются даже редкие экземпляры, которые успели выучить имя своей машины. Но часто у звонящего вдобавок к его основной проблеме появляется вторая: узнать имя/IP-адрес компьютера. И нередко на решение этой второй проблемы уходит куда больше времени, чем первой (а надо было всего лишь обои поменять или вернуть пропавший ярлык :).
А ведь намного приятнее услышать что-то вроде:
— Татьяна Сергеевна, не беспокойтесь, уже подключаюсь…
А надо для этого не так уж и много. Специалисту техподдержки достаточно лишь выучить наизусть имена машин и помнить, кто за какой работает.
Перед описанием решения, которым мы пользуемся сейчас, я кратко рассмотрю другие варианты, чтобы раскритиковать их в пух и прах объяснить свой выбор.
- BgInfo, Desktop Info и им подобные. Если много денег, есть и платные. Суть в том, что на десктоп выводится техническая информация: имя машины, IP-адрес, логин и т.д. В Desktop Info можно даже графики производительности запилить на половину экрана.
Не устраивает то, что для того же Bginfo, например, пользователю нужно сворачивать окна, чтобы увидеть нужные данные. Еще мы с коллегами не раз наблюдали у BgInfo характерный артефакт, когда новый текст выводится поверх старого.
Некоторых пользователей раздражает тот факт, что админырисуют пугающее 192.168.0.123 на мордочке растянувшегося на рабочем столе котикапортят эстетику фоновой картинки, и, разумеется, это жутко демотивирует и напрочь убивает рабочий настрой. - Ярлык а-ля «Кто я» (не пытайтесь добавить ему знак вопроса в конце :). Классический ярлык на рабочем столе, за которым прячется аккуратный или не очень скрипт, выводящий нужную информацию в виде диалогового окна. Иногда вместо ярлыка на рабочий стол кладут сам скрипт, что ИМХО моветон.
Недостаток в том, что для запуска ярлыка, как и в первом случае, нужно сворачивать все открытые окна (баловней судьбы, у которых на рабочей машине открыто единственное окно с пасьянсом, в расчет не берём). Кстати, а ваши пользователи знают, куда нужно тыкнуть, чтобы свернуть все окна?Правильно, пальцем в глаз админу.
Душу излил, а теперь к делу.
За основу была взята идея хабровчанина mittel из этой статьи.
Суть задумки в том, что при входе пользователя в Windows логон-скрипт заносит нужную информацию (время и имя машины) в определенный атрибут учётной записи пользователя. А при выходе из системы отрабатывает аналогичный логофф-скрипт.
- Групповая политика, в которой прописаны логон- и логофф-скрипты для пользователей, применяется ко всему домену, поэтому скрипты будут отрабатывать на любой машине, на которую логинятся пользователи. Если у вас наряду с рабочими станциями используются терминальные решения (например, Microsoft RDS или продукты Citrix), такой подход будет неудобным.
- Данные заносятся в атрибут Department учетной записи пользователя, на который у рядового пользователя есть доступ только на чтение. Помимо атрибута учётной записи пользователя, скрипт также вносит изменения в атрибут Department учётной записи компьютера, который по умолчанию пользователи также менять не могут. Поэтому чтобы решение работало, автор предлагает изменить стандартые настройки безопасности для объектов AD.
- Формат даты зависит от настроек локализации на конечной машине, поэтому с одной машины можем получить 10 ноября 2018 14:53, а с другой 11/10/18 2:53 p.m.
- GPO линкуется не к домену, а к OU с машинами (я разделяю пользователей и машины по разным OU и другим советую). При этом для loopback policy processing mode выставлен режим merge.
- Скрипт будет заносить данные только в учетную запись пользователя в атрибут Info, который пользователь может менять самостоятельно для своей учётной записи.
- Изменен кусок кода, генерирующий значение атрибута
Теперь скрипты выглядят так:
SaveLogonInfoToAdUserAttrib.vbs
On Error Resume Next Set wshShell = CreateObject("WScript.Shell") strComputerName = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") Set adsinfo = CreateObject("ADSystemInfo") Set oUser = GetObject("LDAP://" & adsinfo.UserName) strMonth = Month(Now()) If Len(strMonth) < 2 then strMonth = "0" & strMonth End If strDay = Day(Now()) If Len(strDay) < 2 then strDay = "0" & strDay End If strTime = FormatDateTime(Now(),vbLongTime) If Len(strTime) < 8 then strTime = "0" & strTime End If strTimeStamp = Year(Now()) & "/" & strMonth & "/" & strDay & " " & strTime oUser.put "info", strTimeStamp & " " & " @ " & strComputerName oUser.Setinfo
SaveLogoffInfoToAdUserAttrib.vbs
On Error Resume Next Set wshShell = CreateObject("WScript.Shell") strComputerName = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") Set adsinfo = CreateObject("ADSystemInfo") Set oUser = GetObject("LDAP://" & adsinfo.UserName) strMonth = Month(Now()) If Len(strMonth) < 2 then strMonth = "0" & strMonth End If strDay = Day(Now()) If Len(strDay) < 2 then strDay = "0" & strDay End If strTime = FormatDateTime(Now(),vbLongTime) If Len(strTime) < 8 then strTime = "0" & strTime End If strTimeStamp = Year(Now()) & "/" & strMonth & "/" & strDay & " " & strTime oUser.put "info", strTimeStamp & " " & " @ " & strComputerName oUser.Setinfo
Кто первым найдет все отличия между логон- и логофф-скриптом, тому плюс в карму. 🙂
Также для получения наглядной информации создан такой небольшой PS-скрипт:
Get-UsersByPCsInfo.ps1
$OU = "OU=MyUsers,DC=mydomain,DC=com" Get-ADUser -SearchBase $OU -Properties * -Filter * | Select-Object DisplayName, SamAccountName, info | Sort DisplayName | Out-GridView -Title "Информация по логонам" -Wait
Итого всё настраивается на раз-два-три:
- создаем GPO с нужными настройками и линкуем его к подразделению с рабочими станциями пользователей:

- идем пить чай (если AD с большим количеством пользователей, то чая нужно много 🙂
- запускам PS-скрипт и получаем результат:

В верхней части окна есть удобный фильтр, в котором можно отбирать данные по значениям одного или нескольких полей. Клик по столбцам таблицы сортирует записи по значениям соответствующих полей.

Можно красиво «упаковать» наше решение.
Для этого добавим ярлык для запуска скрипта специалистам техподдержки, у которого в поле «объект» будет что-то такое:
powershell.exe -NoLogo -ExecutionPolicy Bypass -File "\\server\share\Scripts\Get-UsersByPCsInfo.ps1"
Если сотрудников техподдержки много, то можно раздать ярлык с помощью GPP.

Несколько замечаний напоследок.
- На машине, откуда запускается PS-скрипт, должен быть установлен модуль Active Directory для PowerShell (для этого достаточно добавить средства администрирования AD в компонентах Windows).
- бОльшую часть атрибутов своей учётной записи пользователь по умолчанию редактировать не может. Учитывайте это, если решите использовать атрибут, отличный от Info.
- Проинформируйте всех причастных коллег о том, какой атрибут будете использовать. Например, тот же Info используется для интерактивного добавления заметок к ящику пользователя в админке Exchange Server и кто-то легко может его затереть, либо опечалился, когда добавленную им информацию затрет ваш скрипт.
- Если у вас несколько сайтов Active Directory, то делайте поправку на задержки репликации. Например, если вы хотите получить актуальную информацию о пользователях с AD-сайта A, а запускаете скрипт с машины из AD-сайта B, то можно сделать так:
Get-ADUser -Server DCfromSiteA -SearchBase $OU -Properties * -Filter * | Select-Object DisplayName, SamAccountName, info | Sort DisplayName | Out-GridView -Title "Информация по логонам" -WaitDCfromSiteA — имя контроллера домена сайта A (по умолчанию командлет Get-AdUser подключается к ближайшему контроллеру домена)
Буду признателен, если вы пройдете короткий опрос ниже.
Получаем информацию о последнем входе пользователя
Как системному администратору, отвечающему за Active Directory, мне иногда приходится отвечать на вопросы типа ″куда и когда заходил вот этот пользователь″. Чтобы иметь возможность быстро получить требуемую информацию, можно записывать данные о входе прямо в свойства пользователя. Для этого надо всего лишь определить имя компьютера и текущее время и занести эти данные в один из свободных атрибутов пользователя в AD, например в описание (Description).
Задача, на первый взгляд, простая и легко решаемая с помощью PowerShell. Но, скрипт будет выполняться на клиентских рабочих станциях, где использовать PowerShell модуль для работы с AD нельзя. Ведь его там просто нет Поэтому придется использовать подручные средства.
С помощью переменных окружения получаем из локальной системы данные о пользователе и компьютере.
$user = $env:USERNAME;
$computer = $env:COMPUTERNAME;
Для получения текущего времени воспользуемся статическим .Net классом DateTime:
Все это в виде строки помещаем в переменную $string.
$string = ″Logged on $computer at $time″;
Теперь нам надо найти в AD пользователя. Для поиска воспользуемся .Net классом Directory Searcher. Создаем объект DirectorySearcher:
$Searcher = New-Object DirectoryServices.DirectorySearcher;
Искать будем по всему домену, поэтому в качестве корневой директории поиска указываем имя домена:
Дополнительно задаем поиск по всем вложенным объектам:
Теперь создаем фильтр для поиска пользователя:
Используя результаты поиска, получаем из AD объект пользователя:
Помещаем в поле Description строку с полученной информацией и сохраняем изменения:
Сохраняем скрипт и с помощью групповых политик добавляем его в Logon Scripts. Теперь скрипт будет отрабатывать при каждом входе пользователя в систему, в результате получится что то вроде этого.