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

Обновлено: 04.07.2024

Добрый день, хабр!
Наверное, у всех системных администраторов была проблема определения имени компьютера пользователя. То есть мы знаем имя сотрудника, но какой у него компьютер, без понятия. И, зачастую, попытка заставить пользователя определить имя компьютера вызывает мучение. Они вместо этого называют имя пользователя, mail, номер телефона, все что угодно, только не имя компьютера. А попытка объяснить пользователю где находится информация о системе вызывает баттхерт сотрудника и лютую ненависть. Можно, конечно, было бы написать какую-нибудь утилитку, позволяющая отображать имя компьютера на рабочем столе или где-нибудь еще на видном месте, но для этого надо каждый раз объяснять где находится эта информация. Немного упрощает задачу, но не решает ее полностью. Тем более что я склоняюсь к тому, что пользователю и во все положено не знать имя компьютера, на котором он сидит. В результате было решено сделать определение имени компьютера современным, удобным, правильным и, главное, автоматическим.

image


Примерно так может выглядеть подключение к компьютеру. При чем оснастку даже не обязательно открывать с помощью административной учетной записи. Для тех, кому интересно как все это работает и как это сделать в вашей инфраструктуре, добро пожаловать под кат.
Для выполнения описанного, вы должны понимать что такое AD, понимать хотя бы примерно структуру объектов в AD, понимать работу скриптов, а также любить котиков.

Общий принцип

Скрипт, запущенный из под пользователя определяет имя компьютера, на котором он работает, и от своего имени текущего пользователя записывает значение атрибута в самом себе в каталоге AD. Далее администратор уже волен сам решать что делать с этим значением атрибута. Я в этой статье приведу пример PowerShell скриптов и пример добавления пункта контекстного меню в оснастку Active Directory Users and Computers (далее ADUC).

Создаем атрибут

Маркировка

В итоге мы создали атрибут, права назначили. Переходим к рабочему этапу, нужно добавить имя компьютера в значение атрибута.
Для этого используется VBscript. Как показывает практика, Microsoft не пытается делать PowerShell заменой VBS. А жаль. Для таких задач VBS оказывается быстрее и универсальнее.
Скрипт, записывающий данные в текущего пользователя:

image

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

В этом случае, даже если логин был выполнен на нескольких компьютерах, актуальным будет записан тот компьютер который был разблокирован последним. Есть только одно разочарование. Этот метод работает исключительно на Vista+ компьютерах. То есть в XP нельзя в планировщике поставить такой триггер. И к великому сожалению, VBS тоже не позволяет определить, заблокирован ли компьютер или нет. Иначе можно было бы запускать скрипт раз в 15 минут с проверкой заблокирован ли компьютер или нет. В VBS можно только по субъективным признакам определять, например, по записям в евент логе Security, но тогда, как минимум, потребуется дать обычному пользователю права на просмотр этого журнала. Это неудобно, плохо применимо да и вообще XP становится все меньше, эту группу компьютеров можно игнорировать, для них будет достаточно Logon скрипта.
Т.к. нам хочется помечать не каждый вход, а только тот, который локальный, нам нужно исключить запуск Logon скрипта на терминальных и других серверах, не относящихся к локальным компьютерам. Я этого достигал включением замыкании групповой политики в режиме слияние и применением объекта групповой политики к области персональных компьютеров, серверов, в которой, нет. Метод, соглашусь, достаточно плохой и растрачивающий ресурсы, лучше использовать замыкание групповой политики только тогда, когда это точно надо, а не для всех компьютеров. Но, возможно, это будет следующим этапом улучшения. Тем не менее, таким образом мы четко ограничиваем на каких именно компьютерах будет выполняться нужная нам групповая политики с Logon скриптом и настройками планировщика.

Пример PowerShell скрипта для сбора данных

image

Главная задача выполнена. Мы начинаем видеть, что в пользователях начинает появляться информация о текущем компьютере.

Теперь нам надо что-то с этими данными сделать. Например, сделать удобную табличку с тем, какие пользователи на каких компьютерах сидят. Или увидеть у каких пользователей нет значения в атрибуте, несмотря на недавний вход в систему, чтобы проследить, выполняются ли групповые политки в системе, например, либо в пользователе почему-то не хватает прав для записи значения атрибута в своего пользователя. Такое бывает, если у пользователя отключено наследование прав, к примеру.

Я написал 3 PowerShell скрипта, помогающих работе.

Поиск пользователей без значений


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

Все компьютеры с метками

Этот скрипт похож на предыдущий, но показывает список помеченных пользователей. Позволяет прикинуть относительное количество помеченных пользователей.

Поиск имя компьютера по пользователю


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

По всем скриптам, вывод можно делать не в Format-Table, а в Export-CSV и создавать сразу CSV файл и анализировать его уже в каком-нибудь табличном редакторе.
>

Добавление пункта в оснастку

image

Скрипты это красиво, но хочется большей автоматизации. И захотелось, чтобы при нажатии в контекстном меню происходило автоматическое подключение к компьютеру программой для удаленного управления DameWare. Безусловно, можно запускать любую удобную программу, можно таким образом удаленно перезагружать, например, машину, если надо. Тем не менее рассмотрим пример с DameWare.
Настройки контекстного меню оснастки ADUC находятся не локально, как может сначала показаться, а, опять же, в каталоге AD. Для того, чтобы добавить новый пункт, необходимо воспользоваться редактором конфигурации AD, утилитой ADSI Edit. Необходимо подключиться к конфигурации AD.

image

Требуемый атрибут для изменения находится в объекте
CN=user-Display,CN=419,CN=DisplaySpecifiers,CN=Configuration,DC=contoso,DC=com. При том CN=419 это, как не сложно догадаться, язык. Если нужно поменять параметр для англоязычной оснастки ADUC, то CN=419 нужно поменять на CN=409.

Добавляем в adminContextMenu пункт. Первое это, на сколько я понимаю, сортировочный номер, второе это непосредственно имя и третье это, собственно, адрес объекта для выполнения. Параметры разделяются запятыми. После перезапуска ADUC для объектов user в контекстном меню появится новосозданный пункт. Скрипт будет запускаться от прав пользователя, от имени которого оснастка и была запущена. Всего при запуске программы из контекстного меню ADUC скрипту или программе передается 2 значения в параметрах, это DN объекти и типа объекта. Нам интересен только первый параметр, по которому мы находим имя пользователя в скрипте.

Этот скрипт запускает программу Damware с учетными данными contoso\LocalAdmin. Этот пользователь заранее был добавлен в список локальных администраторов на компьютерах пользователей. По сути, параметры -u:, -p: и -d: можно исключить и тогда DameWare будет запускаться от имени текущего пользователя. Если у вас есть права локального администратора на компьютерах пользователя, то так будет проще.

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

Несмотря на то, что никакие уникальные знания здесь не описаны, надеюсь, что как минимум, примеры скриптов помогут начинающим админам в понимании этой области :) Все это можно продолжать улучшать, добавить новые атрибуты, добавлять метку не только пользователю, но и компьютеру добавлять Timestamp, сохранять последние компьютеры и т.п. В каждой компании могут найтись свои потребности.

На каком компьютере залогинился пользователь?

В какой ситуации нам может понадобиться узнать, на каком компьютере залогинился (выполнил вход) пользователь?

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

На просторах интернета я нашел различные варианты, в которых предлагаю писать скрипты, однако мы с вами рассмотрим метод куда проще.

Использую стандартные средства серверной операционной системы, в моем примере будет рассматриваться Windows Server 2008 R2.

Рассмотрим примерный сценарий задачи по поиску компьютера, на котором залоигнился (выполнил вход) пользователь.

Пользователь звонит вам в поисках решения определенного вопроса, и первым делом мы узнаем (если не знаем) фамилию и имя сотрудника. Далее, для подключения к компьютеру нам нужно, по полученным данным, выяснить за каким компьютером сидит данный сотрудник. Для этого заходим в (Пуск \ Администрирование \ Диспетчер сервера \ Роли \ Доменные службы Active Directory \ Active Directory – пользователи и компьютеры \ ваш домен.local \ ПКМ \ Найти)

na kakom kompyutere zaloginilsya polzovatel 1

Вводим имя сотрудника, которое нас интересует и жмем кнопку «Найти»

na kakom kompyutere zaloginilsya polzovatel 2

Из полученных данных нам нужно узнать логин пользователя, под которым он выполняет вход (залогинивается) в систему. Нужен именно логин, так как имя не является логином, по этому открываем свойства учетной записи и переходим во вкладку «Учетная запись». Где узнаем имя входа пользователя.

na kakom kompyutere zaloginilsya polzovatel 3

Теперь нам потребуется проверить, на какой компьютер последний раз выполнялся вход под данной учетной записью? Для этого запустим «Журнал событий» (Пуск \ Администрирование \ Просмотр событий \ Журналы Windows \ Безопасность)

na kakom kompyutere zaloginilsya polzovatel 4

na kakom kompyutere zaloginilsya polzovatel 5

Заходим в свойства записи и смотрим, чтобы «Имя учетной записи» совпадало с нашим, если все совпадает, то смотрим «Сетевой адрес источника» это и есть IP адрес машины, на которую последний раз выполнял вход (залогинивался) наш пользователь.

na kakom kompyutere zaloginilsya polzovatel 6

Теперь можем узнать доменное имя машины, по её IP адресу через команду в командной строке (Пуск \ Выполнить \ cmd) ping –a 192.168.0.97

na kakom kompyutere zaloginilsya polzovatel 7

Вот и все, теперь мы знаем, что пользователь Севостьянов Антон последний раз был залогинен на компьютере admins. Скорее всего, он за ним и сидит.

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

В качестве альтернативы, можно вывести на рабочий стол IP адрес компьютера и спрашивать его у пользователя. Об этом я рассказывал в уроке по программе BGinfo для обычной сети и в домене.

Постановка задачи

В компаниях, где есть техническая поддержка пользователей, ее инженеры очень часто подключаются удаленно к компьютерам сотрудников для устранения всевозможных проблем. Чаще всего используются программы TeamViewer, встроенный помощник Windows или Dameware. Но для того, чтобы подключиться вам необходимо знать имя компьютера. Понятно, что можно каждый раз просить пользователя посмотреть его либо в окне системы или же на рабочем столе, если у вас выводится информация с помощью BGinfo. Но проще и правильнее всегда эту информацию иметь в базе Active Directory.

Поэтому мы сделаем так, что при локальном входе в компьютер, информация, о его DNS-имени будет автоматически записана в нужное нам поле. Это удобно и можно легко эту информацию выдергивать в любую программу, которая умеет работать с Active Directory, например SCCM.

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

Реализация задачи

Делать мы все будет с помощью вот такого простенького скрипта.

Set objSysInfo = CreateObject("ADSystemInfo")

Set objUser = GetObject("LDAP://" & strUserDN)

Давайте с вами пробежимся по каждой из строчек кода.

Вы вместо атрибута "Pager" можете подставлять любой, посмотреть атрибуты можно через редактор в Active Directory. Далее создаете текстовый документ и сохраняете его с расширением vbs.

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

Создание политики во время входа в систему

Файл со скриптом у меня готов. Открываем оснастку "Управление групповой политикой". Выбираем нужное организационное подразделение к которому мы будем применять политику, в моем случае, это контейнер "Users", поэтому политику я буду применять на самый корень домена root.pyatilistnik.org. Кликаем по нему правым кликом и из контекстного меню выбираем пункт "Создать объект групповой политики в этом домене и связать его".

Создаем политику для запуска скрипта при логине пользователя

Задаем имя для нашей политики.

Узнать компьютер пользователя в AD-02


Далее нам необходимо изменить и настроить нашу политику. Для этого щелкаем по ней правым кликом и выбираем "Изменить".

Настройка GPO для запуска скрипта узнающего имя компьютера у пользователя

Переходим по пути:

У вас откроется окно с вкладкой "Сценарии" и "Сценарии PowerShell". Нас будет интересовать первая вкладка, нажимаем кнопку "Добавить".

Узнать компьютер пользователя в AD-04

Через кнопку "Обзор" вам нужно будет выбрать ваш файл vbs. Я вам советую его скопировать в сетевую папку с политикой, либо в сетевую шару, где файл будет доступен для всех.

выбор vbs скрипта для входа пользователя на компьютер

В итоге у вас должно появиться вот так, если скриптов более одного, то можно выставлять их позиции при применении. Начинаем тестирование. У меня есть тестовая учетная запись Барбоскина Геннадия, в оснастке ADUC она у меня лежит в контейнере "Users". Поле пейджер пустое.

Тестовый пользователь в оснастке ADUC

Пробуем залогиниться Геннадием на рабочей станции с Windows 10 с именем W10-CL01. После входа на компьютер, проверяем свойство "Пейджер" у данного пользователя. Как видим, все прописалось.

Узнать компьютер пользователя в AD-07

Пробуем подключиться к еще одному компьютеру с Windows 10 под именем W10-CL02. Видим, что атрибут в AD изменил свое значение на имя второго компьютера.

date

22.09.2021

directory

PowerShell

comments

комментария 42

Допустим, ваша задача – найти в Active Directory все неактивные компьютеры, которые не регистрировались в домене более 120 дней и заблокировать учетные записи этих компьютеров.

Прежде чем приступить к работе с командлетом Get-ADComputer, необходимо подключить модуль Active Directory Module for Windows PowerShell.

Совет. В PowerShell 3.0 (представлен в Windows Server 2012) и выше этот модуль подключается по умолчанию при установке компонента Remote Server Administration Tools -> Role Administration Tools -> AD DS and AD LDS Tools -> Active Directory модуль для Windows PowerShell. Чтобы использовать командлет Get-ADComputer в клиентских Windows 10,8.1 и Windows 7 нужно скачать и установить RSAT для вашей версии ОС и включить модуль AD-PowerShell из панели управления или командой:
Enable-WindowsOptionalFeature -Online -FeatureName RSATClient-Roles-AD-Powershell

Модуль Active Directory для Windows PowerShell

Основы синтаксиса и использование командлета Get-ADComputer

Справка о параметрах командлета Get-ADComputer вызывается стандартно с помощью Get-Help:

синтаксис командлета Get-ADComputer

Для получения информации из AD с помощью командлетов модуля AD for Powershell не обязательно иметь права администратора домена, достаточно чтобы учетная запись под которой запускается командлет входила в группу пользователей домена (Authenticated Users / Domain Users).

Чтобы получить информацию о доменной учетной записи конкретного компьютера или сервера, укажите его имя в качестве аргумента параметра —Identity:

Get-ADComputer -Identity SRV-DB01

Get-ADComputer -Identity

Командлет вернул только базовые свойства объекта Computer из AD. Нас интересует время последней регистрации компьютера в домене AD, но этой информация в выводе команды нет. Выведем все доступные свойства данного компьютера из Active Directory:

Get-ADComputer все параметры компьютера в Active Directory

Get-ADComputer -Identity SRV-DB01 -Properties *

С помощью Get-Member можно получить список всех свойств класса Computer в AD:

Get-ADComputer -Filter * -Properties * | Get-Member

Как вы видите, время последнего входа данного компьютера в сеть указано в атрибуте компьютера LastLogonDate – 21.09.2015 0:20:17.

Командлет Get-ADComputer позволяет вывести в результатах команды любые из свойств компьютера. Уберем всю лишнюю информацию, оставив в выводе только значения полей Name и LastLogonDate.

Get-ADComputer -identity SRV-DB01 -Properties * | FT Name, LastLogonDate -Autosize

Табличное представление Get-ADComputer

Итак, мы получили данные о последнем времени регистрации в домене для одного компьютера. Теперь нам нужно изменить команду так, чтобы она возвращала информацию о времени последней регистрации в сети для всех компьютеров домена. Для этого заменим параметр –Identity на —Filter:

Получаем время входа для всех компьютеров домена

Get-ADComputer -Filter * -Properties * | FT Name, LastLogonDate -Autosize

Мы получили таблицу, которая содержит только 2 поля: имя компьютера и дата LastLogonData. Вы можете добавить в эту таблицу другие поля объекта Computer из AD. Чтобы вывести данные о компьютерах в определенном контейнере домена (OU), воспользуйтесь параметром SearchBase:
Get-ADComputer -SearchBase ‘OU=Moscow,DC=winitpro,DC=loc’ -Filter * -Properties * | FT Name, LastLogonDate -Autosize

Отсортируем результаты запроса по времени последнего логина в сеть (поле LastLogonDate) с помощью команды Sort:

Get-ADComputer -Filter * -Properties * | Sort LastLogonDate | FT Name, LastLogonDate -Autosize

Итак, мы получили список компьютеров домена и время их последнего входа в сеть Active Directory. Теперь мы хотим заблокировать учетные записи компьютеров, которые не использовались более 120 дней.

С помощью Get-Date получим в переменной значение текущей даты и вычтем из текущей даты 120 дней:

Get-Date adddays

Полученную переменную с датой можно использовать в качестве фильтра запроса Get-ADComputer по полю LastLogonDate

Get-ADComputer -Properties LastLogonDate -Filter | Sort LastLogonDate | FT Name, LastLogonDate -Autosize

Таким образом, мы получили список неактивных компьютеров, не регистрировавшихся в сети более 120 дней. С помощью командлета Set-ADComputer или Disable-ADAccount вы можете отключить эти учетные записи.

Совет. В первый раз лучше протестировать результаты команды с помощью переключателя –WhatIf, благодаря которому команда не вносит никаких изменений, показывая, что произойдет при ее выполнении.

Get-ADComputer -Properties LastLogonDate -Filter | Set-ADComputer -Enabled $false -whatif

Теперь можно заблокировать все полученные учетные записи компьютеров:

Get-ADComputer -Properties LastLogonDate -Filter | Set-ADComputer -Enabled $false

Совет. Список заблокированных, отключенных и неактивных компьютеров и пользователей домена можно получить также с помощью отдельного командлета Search-ADAccount.

Примеры использования командлета Get-ADComputer

Ниже представлены еще несколько полезных примеров команд с использованием командлета Get-ADComputer, которые можно использовать для выборки и поиска компьютеров домена по определенными критериям.

Получить общее количество активных (незаблокированных) компьютеров в Active Directory:

Посчитать количество серверов с Windows Server в домене:

посчитать количество компьютеров и серверов в AD

Получить список компьютеров в определенном OU, имена которых начинаются с BuhPC:

Get-ADComputer -Filter -SearchBase ‘OU=Moscow,DC=winitpro,DC=loc’ -Properties IPv4Address | Format-table Name,DNSHostName,IPv4Address | ft -Wrap –Auto

При поиске по OU вы можете использовать дополнительный параметр -SearchScope 1, который означает, что нужно искать только в корневом разделе. Параметр -SearchScope 2 означает рекурсивный поиск компьютеров во всех вложенных OU.

Выбрать все рабочие станции с ОС Windows 10:

Получить список серверов в домене с версией ОС, IP адресом и установленным Service Pack:
Get-ADComputer -Filter 'operatingsystem -like "*Windows server*" -and enabled -eq "true"' -Properties Name,Operatingsystem, OperatingSystemVersion, OperatingSystemServicePack,IPv4Address | Sort-Object -Property Operatingsystem | Select-Object -Property Name,Operatingsystem, OperatingSystemVersion, OperatingSystemServicePack, IPv4Address| ft -Wrap –Auto

На выходе получили такую красивую таблицу со списком Windows Server в AD.

get-adcomputer информации о версии windows на компьютерах домена

Атрибут -LDAPFilter позволяет использовать в качестве параметра командлета Get-ADComputer различные LDAP запросы, например:

Get-ADComputer -LDAPFilter "(name=*db*)"|ft

Выбрать заблокированные компьютеры в определенном OU:

Get-ADComputer -filter * -SearchBase ‘OU=Computers, dc=winitpro,dc=loc’ | Where-Object

Чтобы удалить все аккаунты компьютеров в домене, не авторизовавшиеся в домене более 6 месяцев, можете воспользоваться командой:

get-adcomputer -properties lastLogonDate -filter * | where < $_.lastLogonDate -lt (get-date).addmonths(-6) >| Remove-ADComputer

Результат выполнения команды Get-ADComputer можно выгрузить в текстовый файл:

Get-ADComputer -Filter < OperatingSystem -Like '*Windows Server 2008*' >-Properties OperatingSystem | Select DNSHostName, OperatingSystem | Format-Table -AutoSize C:\Script\server_system.txt

Также вы можете получить выборку компьютеров и экспортировать его в CSV файл:

Get-ADComputer -Filter * -Property * | Select-Object Name,OperatingSystem,OperatingSystemServicePack | Export-CSV All-Windows.csv -NoTypeInformation -Encoding UTF8

Или получить HTML файл отчета со списком компьютеров и нужных атрибутов компьютера:

Get-ADComputer -Filter -Properties * | Select-Object Name,OperatingSystem | ConvertTo-Html | Out-File C:\ps\ad_computer.html

html отчеи по компьютерам в домене active directory

Чтобы выполнить определенной действие со всеми компьютерами из полученного списка нужно использовать цикл Foreach. В этом примере мы хотим получить список серверов в домене с моделью и производителем:

$Computers = Get-ADComputer -Filter
Foreach ($Computer in $Computers)
$Hostname = $Computer.Name
$ComputerInfo = (Get-WmiObject -Computername $Hostname Win32_ComputerSystem)
$Manufacturer = $Computer.Manufacturer
$Model = $Computer.Model
Write-Host "Name: $Hostname"
Write-Host "Manufacturer: $Manufacturer"
Write-Host "Model: $Model"
Write-Host " "
$Content = "$Hostname;$Manufacturer;$Model"
Add-Content -Value $Content -Path "C:\PS\ServersInfo.txt"
>

Либо можно использовать более короткий синтаксис цикла. Допустим нам нужно выполнить определенную команду на всех компьютерах в определенном OU (в этом примере мы хотим запустить на всех серверах команду обновления настроек групповых политик):

Затем с помощью следующей команды я могу найти компьютеры, на которых отсутствует или не запушена служба CCMExec:

get-adcomputer -filter -SearchBase “OU=Computers,OU=MSK,DC=winitpro,DC=ru” -properties dNSHostName,extensionAttribute10,LastLogonDate |select-object dNSHostName,extensionAttribute10,LastLogonDate

Получение списка залогиненных пользователей AD и их компьютеров в Powershell

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

Навигация по посту

Как получить список залогиненных пользователей

В Powershell есть несколько методов возврата списка активных пользователей. Каждый из способов имеет свои минусы и поэтому, в зависимости от цели, какой-то способ будет удобнее использовать локально (при входе пользователя), а какой-то удаленно. В случае с WMI это так и не получилось сделать, так нет класса, который бы хранил все нужные значение и работал бы везде.

Локально при входе пользователя

Самый простой способ - это поместить скрипт в планировщик задач, который будет выполняться при входе пользователя в систему. Этот способ не подразумевает удаленной работы. Почти полный скрипт выглядит так:

Получение имени залогинившегося пользователя и его времени в Powershell

Можно создать политику, которая будет запускать скрипт при входе и экспортировать в CSV. Сам файл CSV может находится на удаленном компьютере. Следующая команда сделает это записав данные в конец существующий файл (т.е. не перезапишет файл):

Получится примерно следующий вид файла:

Получение имени залогинившегося пользователя и его времени в Powershell в CSV

Как создавать команды и функции в Powershell вызывать их и передавать параметры

Системная утилита quser.exe

Мы можем использовать системную программу quser, которая возвращает имя текущего пользователя и время его входа. Выглядит это так:

Выполнение программы quser

Quser так же может работать удаленно используя следующий синтаксис:

Выполнение программы quser удаленно

Первая проблема этого способа - это то, что quser работает через RPC. Если вы выполняете команду удаленно, а порты не открыты, вы получите ошибки:

  • Error 0x000006BA enumerating sessionnames
  • Error [1722]:The RPC server is unavailable.

Для примера, следующие команды исправят эти проблемы на одном компьютере, но скорее всего вы будете менять настройки через политики. Так же обратите внимание, что правило устанавливается на "Any", а не только "Domain":

Вторая проблема - если вы будете выполнять команду через Invoke-Command, то могут быть проблемы с кодировками:

Проблема с кодировками quser в Powershell

И третья проблема - у нас возвращается строка, а не объект. Что бы мы могли все эти данные, в дальнейшем, экспортировать (например в CSV), мы должны ее парсить. Это можно сделать так:

Форматирование quser в Powershell

Далее нам нужно преобразовать все в специальный массив - PSCustomObject, т.к. только он может быть экспортирован в CSV и представляет собой более удобный вывод:

Форматирование quser в Powershell

Метод substring убирает первый символ, так как программа возвращает имя пользователя либо с пробелом начали или символом ">".

Такой скрипт мы можем объединить в один командлет, который сможет работать локально и удаленно:

В функцию добавлено несколько деталей:

Мы можем вызывать скрипт несколькими приемами:

Получение и форматирование списка вошедших пользователей с quser в Powershell

Отмечу, что в случаях выключенных компьютеров запросы идут очень долго (около 2-3 секунд на компьютер). Способа снизить конкретно таймаут - я не знаю. Один из вариантов ускорить работу - фильтровать вывод с Get-ADComputer исключая отключенные учетные записи компьютеров. Так же можно попробовать использовать параллелизм.

Легче всего такой скрипт запускать на компьютерах пользователей, по событию входа в систему. На примере ниже я экспортирую эти данные в единый, для всех пользователей, файл CSV расположенный в доступности для пользователей:

Сам файл будет выглядеть так:

Результат работы quser с Powershell

Отмечу следующие моменты:

Через файл ntuser.dat

В этом примере вернутся все каталоги пользователей:

Получение списка вошедших пользователей с Powershell

Получение списка вошедших пользователей с ntuser.dat в Powershell

Извлечем из пути имя пользователя и уберем лишние колонки:

Форматирование списка залогиненных пользователей в Powershell с ntuser.dat

Как вы знаете к большинству компьютеров можно подключится используя следующие пути:

Это же мы можем использовать с командой Get-ChildItem. Соединим все это в функцию:

Далее мы можем использовать команду в таких вариациях:

Функция получения пользователей с ntuser.dat в Powershell

Отмечу несколько моментов:

Представим, что мы захотим сформировать список из тех пользователей, которые выполнили выход за последний час. Это можно сделать так:

Получении списка вошедших пользователей с Powershell

Исключить пользователей мы можем так же:

Исключение из списка вошедших пользователей с Powershell

Экспорт для Excel аналогичен предыдущему примеру:

Результат получения залогиненных пользователей в Powershell с ntuser.dat

Через WMI

Я пробовал и другие классы, но каждый со своими проблемами. Решения так и не нашел.

Читайте также: