Поиск неактивных пользователей в Active Directory. Использование Get-ADUser для получения разной информации о пользователях домена AD

  • 23.07.2019

Скрипты выгрузки всех пользователей из MS Active Directory (ITGC)

Иван Пискунов

Одной из стандартных процедур проведения аудита ITGC для каталога Active Directory является получение выгрузки всех пользователей домена. На основании полученных данных далее формируются процедуры тестирования, к примеру изучение списка администраторов или выявление пользователей с истекшим паролем. Наиболее эффективным для формирования такой выгрузки будет использование стандартного интерфейса PowerShell , примеры которого мы и рассмотрим в данной статье

1. Экспресс выгрузка скриптом на PowerShell

Ниже представлен скрипт PowerShell, как один из наиболее простых и быстрых способов получить список всех пользователей домена AD в формате CSV, который без проблем открывается тем же Excel"ем.

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = "LDAP://ou=Users,ou=Departmets,dc=test,dc=ru" $objSearcher.Filter = "(&(objectCategory=person)(!userAccountControl:1.2.840.113556.1.4.803:=2))" $users = $objSearcher.FindAll() # Количество учетных записей $users.Count $users | ForEach-Object { $user = $_.Properties New-Object PsObject -Property @{ Должность = $user.description Отдел = $user.department Логин = $user.userprincipalname Телефон = $user.telephonenumber Комната = $user.physicaldeliveryofficename ФИО = $user.cn } } | Export-Csv -NoClobber -Encoding utf8 -Path С:list_domen_users.csv

Для того что бы скрипт отработал на вашей системе, необходимо его чуть подкорректировать, а именно вписать необходимые параметры, т.е. как в данном примере это параметры Users в подразделении Departments в домене Test.ru. А так же указать путь к месту сохранения файла list_domen_users.csv

После выгрузки, если сразу открыть list_domen_users.csv , будет выглядеть в не читабельном виде, однако, станалртыми средствами мы легко его приведем в нужный нам формат. Открываем в Excel list_domen_users.csv , выделяем первый столбец, затем заходим во вкладку "Данные" и нажимаем "Текст по столбцам". Выбираем "с разделителями" и нажимаем "Далее". Готово!

!Необходимо заметить , что данный скрипт не отобразит более 1000 пользователей. Для небольшой компании вполне подойдет, а тем же у кого в домене огромное количество пользователей стоит прибегнуть к методам описанным ниже.

2. Продвинутый командлет PowerShell для получения выгрузки пользователей Active Directory

Инструмент Active Directory Module for Windows PowerShell (представлен в Windows Server 2008 R2 и выше), позволяет формировать командлеты которые выполняют различные манипуляции с объектами каталога AD. Для получения информации о пользователях и их свойствах предназначен командлет Get-ADUser.

Для начала запускаем окно Powershell с правами администратора и импортируем модуль Active Directory для дальнейших действия:
Import-Module activedirectory

Чтобы вывести список всех учетных записей домен а, выполним команду:

Get-ADUser -filter *

Чтобы вывести полную информации обо всех доступных атрибутах пользователя tuser, выполним команду

Get-ADUser -identity tuser -properties *


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

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires > C:tempusers.txt

Или сразу выгрузить в CSV , который в дальнейшем будет удобно экспортировать в Excel (дополнительно с помощью sort-object отсортируем таблицу по столбцу PasswordLastSet , а также добавим условие where – имя пользователя должно содержать строку «Dmitry»)

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | where {$_.name –like “*Dmitry*”} | sort-object PasswordLastSet | select-object Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires | Export-csv -path c:tempuser-password-expires-2015.csv

Не секрет, что начиная с первой версии PowerShell, Microsoft пытается сделать из него основной инструмент администрирования Windows. И во многом это получается! Сегодня на простых примерах, мы покажем возможности PowerShell, которые можно использовать для получения различной информации о пользователях Active Directory и их атрибутах.

Примечание . Ранее для получения информации об атрибутах учетных записей пользователей AD приходилось использовать различные инструменты: консоль ADUC (в том числе ), утилиту и т.п. Выбор инструмента обычно основывался на поставленной задачи и способностях администратора в программировании.

В PowerShell 2.0 появился специальный модуль для работы с Active Directory - (представлен в Windows Server 2008 R2), командлеты которого позволяют выполнять различные манипуляции с объектами каталога AD. Для получения информации о пользователях домена Active Directory и их свойствах предназначен командлет Get-ADUser . С помощью командлета Get-ADUser можно получить значение любого атрибута существующей учетной записи пользователя в AD. Кроме того, можно указывать различные критерии выборки и формировать списки пользователей домена и их атрибутов.

В этом примере мы покажем, как с помощью командлета PowerShell Get-ADUser получить информацию, о том, когда последний раз менялся пароля пользователя и когда истекает срок его действия.

Запускаем окно Powershll с правами администратора и импортируем модуль Active Directory командой:

Import-Module activedirectory

Совет . В Windows Server 2012 и выше этот пункт можно пропустить, так как модуль PowerShell Active Directory подключен по-умолчанию.

В клиентских ОС (в той же Windows 10) для работы коммандера Get-AdUser нужно установить соответствующую версию RSAT и включить в панели управления компонент Active Directory Module for Windows PowerShell (Remote Server Administration Tools -> Role Administration Tools -> AD DS and AD LDS Tools -> AD DS Tools).

Полный список всех аргументов командлета Get-ADUser можно получить так:

Help Get-ADUser

Чтобы вывести список всех учетных записей домена, выполним команду:

Get-ADUser -filter *

Формат возвращаемого списка не очень удобен для использования, выводится только некоторые основные 10 из более 120 атрибутов и свойств учетных записей пользователей (DN, SamAccountName, Name, UPN и т.д) кроме того, мы видим, что информация о времени последней смены пароля отсутствует.

Чтобы вывести полную информации обо всех доступных атрибутах пользователя tuser, выполним команду:

Get-ADUser -identity tuser -properties *

Итак, мы видим полный список атрибутов пользователя AD и их значений, ассоциированных с учетной записью пользователя. Далее мы перейдем к форматированию вывода командлета Get-ADUser, так, чтобы отображались нужные нам поля. Нас интересуют атрибуты:

  • PasswordExpired
  • PasswordLastSet
  • PasswordNeverExpires

Выполним команду:

Get-ADUser tuser -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires

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

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires

Чтобы вывести данные пользователей из определенной OU, воспользуемся параметром SearchBase :

Get-ADUser -SearchBase ‘OU=Moscow,DC=winitpro,DC=loc’ -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires

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

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires > C:\temp\users.txt

Или в CSV, который в дальнейшем будет удобно экспортировать в Excel (дополнительно с помощью sort-object отсортируем таблицу по столбцу PasswordLastSet , а также добавим условие where – имя пользователя должно содержать строку «Dmitry»):

Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | where {$_.name –like “*Dmitry*”} | sort-object PasswordLastSet | select-object Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires | Export-csv -path c:\temp\user-password-expires-2015.csv

Таким образом, можно построить таблицу с любыми необходимыми атрибутами пользователей Active Directory.

Для получения списка учетных записей пользователей AD по определенному признаку используется параметр –Filter. В качестве аргументов этого параметра можно указать значение определённых атрибутов пользователей Active Directory, в результате командлет Get-ADUser будет применятся для пользователей, которые попадают под критерии фильтра.

Вывод пользователей AD, имя которых начинается с Roman:

Get-ADUser -filter {name -like "Roman*"}

Get-ADUser -Filter {SamAccountName -like "*"} | Measure-Object

Список всех активных (не заблокированных) учетных записей в AD:

Get-ADUser -Filter {Enabled -eq "True"} | Select-Object SamAccountName,Name,Surname,GivenName | Format-Table

Список учетных записей с истекшим сроком действия пароля:

Get-ADUser -filter {Enabled -eq $True} -properties passwordExpired | where {$_.PasswordExpired}

Список активных учеток с почтовыми адресами:

Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Format-Table

Задача: для списка учетных записей, которые хранятся в текстовом файле (по одной учетке в строке) нужно получить телефон пользователя в AD и выгрузить информацию в текстовый csv файл (можно легко импортировать в Esxel).

Import-Csv c:\ps\usernsme_list.csv | ForEach { Get-ADUser -identity $_.user -Properties Name, telephoneNumber | Select Name, telephoneNumber | Export-CSV c:\ps\export_ad_list.csv -Append -Encoding UTF8 }

Следующий пример позволяет выгрузить адресную книгу предприятия в виде csv файла, который в дальнейшем можно импортировать в Outlook или Mozilla Thunderbird:

Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Export-Csv -NoTypeInformation -Encoding utf8 -delimiter "," $env:temp\mail_list.csv

Пользователи, которые не меняли свой пароль в течении последних 90 дней:

$90_Days = (Get-Date).adddays(-90) Get-ADUser -filter {(passwordlastset -le $90_days)}

$user = Get-ADUser winadmin -Properties thumbnailPhoto $user.thumbnailPhoto | Set-Content winadmin.jpg -Encoding byte

Список групп, в которых состоит учетная запись пользователя

Get-AdUser winadmin -Properties memberof | Select memberof -expandproperty memberof

Используется для создания, изменения и удаления объектов каталога. Пользователь может также использовать команду ldifde для расширения схемы, экспорта сведений Active Directory о пользователе и группе в другие приложения или службы, а также для заполнения службы ADAM (Active Directory Application Mode) данными из других служб каталогов.

Синтаксис

ldifde [-i ] [-f имя_файла ] [-s имя_сервера ] [-c строка1 строка2 ] [-v ] [-j путь ] [-t номер_порта ] [-d DN_базы ] [-r фильтр_LDAP ] [-p область ] [-l список_атрибутов_LDAP ] [-o список_атрибутов_LDAP ] [-g ] [-m ] [-n ] [-k ] [-a ] [-b ] [-? ]

Параметры

-i Определяет режим импорта. Если параметр не определен, по умолчанию используется режим экспорта. -f имя_файла Указывает имя файла импорта или экспорта. -s имя_сервера Указывает компьютер, на котором должна выполняться операция импорта или экспорта. По умолчанию программа ldifde будет выполняться на компьютере, на котором ldifde установлена. -c строка1 строка2 Заменяет все вхождения строки1 содержимым строки2 . Обычно используется в случае, когда производится импорт данных из одного домена в другой, и при этом необходимо заменить различающееся имя домена, производящего экспорт (строка1 ), именем импортирующего домена (строка2 ). -v Включает режим подробного протоколирования. -j путь Задает местоположение файла журнала. По умолчанию используется текущий путь. -t номер_порта Указывает номер порта протокола LDAP (Lightweight Directory Access Protocol). По умолчанию используется порт LDAP 389. Портом глобального каталога является 3268. -d DN_базы Задает различающееся имя базы поиска для экспорта данных. -r фильтр LDAP Создает фильтр поиска LDAP для экспорта данных. Например, с помощью следующего фильтра выполняется экспорт всех пользователей с определенным отчеством: csvde -r (и(objectClass= Пользователь )(sn= Отчество )) -p область Задает область поиска. Параметрами области поиска являются Base , OneLevel и SubTree . -l список_атрибутов_LDAP Задает список атрибутов, возвращаемых в результатах запроса экспорта. Если данный параметр пропущен, возвращаются все атрибуты. -o список_атрибутов_LDAP Задает список атрибутов, опускаемых из результатов запроса экспорта. Обычно этот параметр используется при экспорте объектов из Active Directory с последующим импортом в другой LDAP-совместимый каталог. Если какие-либо атрибуты не поддерживаются другим каталогом, их можно исключить из набора результатов с помощью данного параметра. -g Исключает постраничные поиски. -m Опускает атрибуты, которые не могут быть записаны, такие как ObjectGUID и objectSID . -n Опускает экспорт двоичных значений. -k Игнорирует ошибки во время операции импорта и продолжает обработку. Ниже приводится полный список игнорируемых ошибок:

  • объект уже является членом группы;
  • нарушение класса объекта (означающее, что указанный класс объекта не существует), если импортируемый объект не имеет других атрибутов;
  • объект уже существует;
  • нарушение ограничения;
  • атрибут или значение уже существует;
  • такого объекта не существует.
-a различающееся_имя_пользователя пароль Задает выполнение команды с использованием указанных различающегося_имени_пользователя и пароля -b . -b имя_пользователя домен пароль Задает команду, выполняемую с использованием указанных имени_пользователя, домена и пароля . По умолчанию команда будет выполняться, используя учетные данные пользователя, который в текущий момент зарегистрирован в сети. Не может использоваться с параметром -a . -? Отображает меню команд.

Замечания

  • С параметром -c можно использовать константы #schemaNamingContext и #configurationNamingContext вместо различающихся имен раздела каталога схемы и раздела каталога конфигурации.
  • При создании файла импорта для команды ldifde , используйте значение changeType , чтобы определить тип изменений, содержащихся в файле импорта. Значения changeType приведены в таблице ниже.

Ниже приведен пример файла импорта LDAP формата LDIF, в котором используется значение add :
DN: CN= выбранный_пользователь ,DC= имя_домена
changetype: add
CN: выбранный_пользователь
description: описание_файла
objectClass: пользователь
objectClass: выбранный_пользователь

Примеры

Чтобы извлечь только различающееся имя, общее имя, имя, фамилию и номер телефона возвращенных объектов, введите:
-l различающееся_имя , CN, имя , SN, телефон
Чтобы исключить глобальный уникальный идентификатор (GUID) для объекта, введите:
-o когда_создан , когда_изменен , GUID_объекта

0

У меня есть следующий рабочий скрипт, который проверяет, является ли большой список пользователей в CSV-файле членом группы AD и записывает результаты в results.csv.

Не знаете, как преобразовать сценарий, чтобы я мог изменить $group = "InfraLite" на $group = DC .\List_Of_AD_Groups.CSV .

Таким образом, сценарий не просто возвращает совпадения для одной группы AD, но так что он возвращает совпадения для групп 80 AD, содержащихся в List_of_AD_groups.csv. Написание YES/NO для каждой группы AD в новом столбце CSV (или, если это невозможно, создание отдельного CSV-файла для каждой группы с результатами будет также.

Я мог бы сделать это вручную, изменив значение из $group и имя файла экспорта и повторного запуска скрипта в 80 раз, но должен быть быстрым был с PS, чтобы сделать это

например results.csv ?:

NAME AD_GROUP1 AD_GROUP2 AD_GROUP80 etc etc. user1 yes no yes user2 no no yes user3 no yes no echo "UserName`InfraLite" >> results.csv $users = GC .\user_list.csv $group = "InfraLite" $members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SAMAccountName foreach ($user in $users) { if ($members -contains $user) { echo "$user $group`tYes" >> results.csv } else { echo "$user`tNo" >> results.csv } }

  • 2 ответа
  • Сортировка:

    Активность

0

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

$groups = Get-Content "C:\groups.txt" foreach ($group in $groups) { $members = Get-ADGroupMember ... ... }

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

$template = @{} Get-Content "C:\groups.txt" | ForEach-Object { $template[$_] = $false } $groups = @{} Get-ADGroup -Filter * | ForEach-Object { $groups[$_.DistinguishedName] = $_.Name } Get-ADUser -Filter * -Properties MemberOf | ForEach-Object { $groupmap = $template.Clone() $_.MemberOf | ForEach-Object { $groups[$_] } | Where-Object { $groupmap.ContainsKey($_) } | ForEach-Object { $groupmap[$_] = $true } New-Object -Type PSObject -Property $groupmap } | Export-Csv "C:\user_group_mapping.csv" -NoType

0

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

Я думаю, что Ansgar был на правильном пути, но я не мог заставить его делать то, что было после. Он упомянул, что на момент написания статьи он не имел доступа к среде AD.

Вот что я придумал:

$UserArray = Get-Content "C:\Temp\Users.txt" $GroupArray = Get-Content "C:\Temp\Groups.txt" $OutputFile = "C:\Temp\Something.csv" # Setting up a hashtable for later use $UserHash = New-Object -TypeName System.Collections.Hashtable # Outer loop to add users and membership to UserHash $UserArray | ForEach-Object{ $UserInfo = Get-ADUser $_ -Properties MemberOf # Strips the LPAP syntax to just the SAMAccountName of the group $Memberships = $UserInfo.MemberOf | ForEach-Object{ ($_.Split(",")).replace("CN=","") } #Adding the User=Membership pair to the Hash $UserHash.Add($_,$Memberships) } # Outer loop to create an object per user $Results = $UserArray | ForEach-Object{ # First create a simple object $User = New-Object -TypeName PSCustomObject -Property @{ Name = $_ } # Dynamically add members to the object, based on the $GroupArray $GroupArray | ForEach-Object { #Checking $UserHash to see if group shows up in user"s membership list $UserIsMember = $UserHash.($User.Name) -contains $_ #Adding property to object, and value $User | Add-Member -MemberType NoteProperty -Name $_ -Value $UserIsMember } #Returning the object to the variable Return $User } #Convert the objects to a CSV, then output them $Results | ConvertTo-CSV -NoTypeInformation | Out-File $OutputFile

Будем надеяться, что все имеет смысл. Я прокомментировал столько, сколько мог. Было бы очень просто преобразовать в ADSI, если у вас не было RSAT, установленного на любой машине, на которой вы запускаете это. Если вам это нужно, дайте мне знать, и я сделаю некоторые быстрые изменения.