Аудит учетных записей пользователей в Active Directory. Поиск неактивных компьютеров в Active Directory

Аудит учетных записей пользователей в Active Directory. Поиск неактивных компьютеров в Active Directory

27.04.2019

7

Возможно, я просто глуп, но я пытаюсь найти пользователя в Active Directory с C#, используя имя входа («domain \ user»).

Мой «Скелет» AD Поиск Функциональность выглядит это, как правило:

De = new DirectoryEntry(string.Format("LDAP://{0}", ADSearchBase), null, null, AuthenticationTypes.Secure); ds = new DirectorySearcher(de); ds.SearchScope = SearchScope.Subtree; ds.PropertiesToLoad.Add("directReports"); ds.PageSize = 10; ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2); SearchResult sr = ds.FindOne();

Теперь, что работает, если у меня есть полный DN пользователя (ADSearchBase обычно указывает на «наших пользователей» OU в Active Directory), но я просто понятия не имею, как искать пользователя на основе синтаксиса «domain \ user».

Любые указатели?

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

    Активность

9

Вам необходимо установить фильтр (DirectorySearcher.Filter) что-то вроде:

"(& (ObjectCategory = человек) (объектный = пользователь) (SamAccountName = {0}))"

Обратите внимание, что вы указываете только имя пользователя (без домена) для свойства sAMAccountName. Чтобы выполнить поиск домена \ пользователь, сначала найдите контекст именования для требуемого домена, затем выполните поиск там для имени sAMAccountName.

Кстати, при построении строк запроса LDAP с использованием String.Format обычно следует избегать любых специальных символов. Вероятно, это необязательно для имени учетной записи, но может быть, если вы выполняете поиск по другим свойствам, таким как первое свойство пользователя (свойство givenName) или имя последнего (sn property). У меня есть служебный метод EscapeFilterLiteral, чтобы сделать это: вы строите свою строку, как это:

String.Format("(&(objectCategory=person)(objectClass=user)(sn={0}))", EscapeFilterLiteral(lastName, false));

где EscapeFilterLiteral реализуется следующим образом:

Public static string EscapeFilterLiteral(string literal, bool escapeWildcards) { if (literal == null) throw new ArgumentNullException("literal"); literal = literal.Replace("\\", "\\5c"); literal = literal.Replace("(", "\\28"); literal = literal.Replace(")", "\\29"); literal = literal.Replace("\0", "\\00"); literal = literal.Replace("/", "\\2f"); if (escapeWildcards) literal = literal.Replace("*", "\\2a"); return literal; }

Эта реализация позволяет рассматривать символ * как часть literal (escapeWildcard = true) или как символ подстановки (escapeWildcard = false).

ОБНОВЛЕНИЕ: Это не имеет никакого отношения к вашему вопросу, но приведенный вами пример не вызывает Dispose на одноразовых объектах, которые он использует. Как и все одноразовые объекты, эти объекты (DirectoryEntry, DirectorySearcher, SearchResultCollection) всегда должны быть удалены, как правило, с помощью оператора using. См. this post для получения дополнительной информации.

0

Спасибо. Я понял, что могу получить Домен (по крайней мере, в моем AD), указав «LDAP: // {0} .somedomain.com/DC = {0}, DC = somedomain, DC = com", заменив {0} на домен, который работает, по крайней мере, в нашей моей среде.

Один вопрос, хотя: SamAccountName кажется обесценился: The logon name used to support clients and servers running older versions of the operating system, such as Windows NT 4.0, Windows 95, Windows 98, and LAN Manager. This attribute must be less than 20 characters to support older clients.

Является ли это по-прежнему лучший подход к нему? Или есть более «современное» поле для запроса? (Windows 2003 Active Directory, Windows XP или 2003 Clients, .net 3.0)

Редактировать: Еще раз спасибо. Наша структура немного сложна: у нас есть большой лес «domain.com», с несколькими доменами для региональных офисов. По существу: Login - это «что-то \ имя пользователя», полный домен us something.domain.com и почта (без чего-то), но основное имя - Я буду вручную переводить что-то \ username на , поскольку это, по-видимому, самый надежный способ. Тем более, что я хочу сохранить функцию автоматического обнаружения.

Как найти устаревшие учетные записи компьютеров

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

Через оснастку active directory пользователи и компьютеры

Через ADUC можно получить список компьютер, по такому значению как последнее время изменения, которое по дате совпадает с параметром последнего логирования компьютера в Active Directory. Открываем active directory пользователи и компьютеры. Выбираем пункт сохраненные запросы и нажимаем создать запрос.

У вас откроется поле с созданием нового запроса к Active Directory. Задаем ему название, далее через кнопку обзор выбираем организационное подразделение, на которое следует натравить запрос, можете оставить и корень. Далее нажимаете кнопку запрос.

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

Все, все параметры заданы и можно строить запрос к базе данных AD.

На выходе я получил список неактивных компьютеров в своей локальной сети, я называю их призраками. Они появляются, либо с поломкой техники, либо из-за халатности администратора. Простой пример системный администратор взял компьютер pyatilistnik01, для переустановки системы, в итоге при попытке ввода его в домен , он получает ошибку, о том, что такой компьютер уже есть и забивает на это, вводя другое имя, либо оставляет имя с генерируемое при установке системы, вида DESKTOP-4BA9AP5. В таких случаях помогает корпоративный стандарт именования компьютеров и автоматическое переименование на основании этих политик.

Зайдя в свойства любого компьютера, перейдите на вкладку объект, и посмотрите поле, изменен, оно будет совпадать по дате с полем LastLogonDate. В итоге я вижу, что данный компьютер не появлялся в сети с 14 ноября 2016 года, что дает мне мысли, о его удалении из базы NTDS.dit .

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

Через Powershell

За, что я люблю Poweshell, так это за его огромные возможности, у него для Active Directory отдельный модуль с командлетами, позволяющими производить большое количество манипуляций. Сразу приведу готовый код, который ищет компьютеры, от которых не было вестей 120 дней и выводит все это дело в тестовый файл с датой последнего обращения.

Замечательно список мы с вами научились получать, и вы можете посмотреть время последнего обращения компьютера к контроллеру домена. Идем дальше, теперь я хочу, чтобы данные компьютеры были выключены в Active Directory и были перемещены в отведенную под это дело OU. Вот пример кода.

$date_with_offset= (Get-Date).AddDays(-120)
$comps = Get-ADComputer -Properties LastLogonDate -Filter {LastLogonDate -lt $date_with_offset } | Sort LastLogonDate
foreach ($comp in $comps) {set-adcomputer $comp.name -enabled $false; move-adobject -identity $comp -targetpath «ou=Мск Л. рабочие станции на удаление,ou=Местоположение,dc=msk,dc=contoso,dc=com»}
Get-ADComputer -Properties LastLogonDate -Filter {LastLogonDate -lt $date_with_offset } | Sort LastLogonDate | FT Name, LastLogonDate -AutoSize | Out-File c:\Script\services.txt

Тут все отключенные компьютеры будут перемещаться в организационное подразделение Мск Л. рабочие станции на удаление. И далее я сделал, вывод в txt файл, чтобы видеть, какие именно учетные записи были отключены.

Полезные ключи командлета Get-ADComputer

Что вам еще может пригодиться у команды Get-ADComputer, это больше для себя подсказка. Напоминаю, чтобы им воспользоваться, нужно загрузить модуль Active Directory, через команду

Import-Module activedirectory

Теперь можно получить справку по команду Get-ADComputer, через команду:

Get-Help Get-ADComputer

Как видите, у команды очень много ключей и богатые возможности.

Я очень часто ее использую, когда мне нужно получить о компьютерной учетной записи максимальное количество данных, вот пример.

Get-ADComputer -Identity DESKTOP-2C4R0V6

В данном выводе команды вы увидите основные значения:

  • DistinguishedName
  • SID > кто не вкурсе что такое SID , то смотрите по ссылке.
  • DNSHostName

Если вам вдруг не хватает данных, то вы можете вывести все доступные поля.

Get-ADComputer -Identity DESKTOP-2C4R0V6 -Properties *

Добрый день уважаемые читатели и подписчики, продолжаем с вами изучение возможностей Powershell и Active Directory. Как вы помните у нее все учетные записи пользователей и компьютеров, находятся в базе данных NTDS.dit, все здорово и централизованно. Когда в компании больше одного системного администратора, может получиться ситуация, что в ней накапливается мусор и лишние учетные данные. Все мы люди и какие-то вещи можем забывать, а в какие-то моменты нас могут отвлечь, что приведет, так же к забыванию важной информации. И приходим, мы к тому, что в Actvie Directory накапливаются не активные пользователи (уволенные или забытые), в любом случае, хороший системный администратор должен их выявлять, отключать и дальше по желанию удалять, чем мы и займемся.

Через оснастку ADUC

В прошлый раз я вам уже приводил пример использования оснастки Active Directory Пользователи и компьютеры, через которую мы искали пропавшие компьютеры в локальной сети , которые не появлялись уже месяц. Сейчас сделаем все то же самое и с пользовательскими учетными записями. У меня AD на Windows Server 2012 R2, открываем ADUC, для этого нажмите WIN+R и введите dsa.msc.

В открывшейся форме запроса задайте:

  • Имя запроса > у меня это потерявшиеся пользователи
  • Описание при необходимости
  • Корень запроса > тут можно оставить весь домен, либо же конкретизировать на нужном OU

После чего жмем кнопку запрос.

На вкладке пользователи видим пункт "Число дней со времени последнего входа в систему" я для примера поставил 60 дней.

В итоге вы получите нужный вам список, неактивных учетных записей сотрудников.

Через оснастку powershell

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

$date_with_offset= (Get-Date).AddDays(-45)
$users = Get-ADUser -Properties LastLogonDate -Filter {LastLogonDate -lt $date_with_offset } | Sort LastLogonDate
foreach ($user in $users) {set-aduser $user -enabled $false; move-adobject -identity $user -targetpath "ou=Уволенные,ou=Мск Л. пользователи,ou=Местоположение,dc=msk,dc=contoso,dc=com"}
Get-ADUser -Properties LastLogonDate -Filter {LastLogonDate -lt $date_with_offset } | Sort LastLogonDate | FT Name, LastLogonDate -AutoSize | Out-File c:\Script\users.txt

  • В первой строке вы объявляете переменную, в которой задаете срок поиска
  • Создаем переменную и делаем выборку по последнему времени логина
  • Перемещаем пользователей

  • Делаем отчет в файл

Еще полезные вещи по работе с пользователем. Перед использованием ниже команд, нужно загрузить модуль Active Directory, через команду

Get-Help Get-ADUser

В Windows и AD есть атрибуты, позволяющие отслеживать последние события регистрации запуска сеанса, однако их анализ - процесс слишком трудоемкий. Один из вариантов предполагает извлечение событий регистрации на каждом контроллере домена (DC) и их сортировку по дате и пользователям для выявления самых последних экземпляров по каждому пользователю. Другой вариант подразумевает проверку значений атрибута пользователя AD lastlogon, которые также не реплицируются контроллерами домена. Поэтому, как и в первом случае, значения lastlogon придется извлекать с каждого DC данного домена, после чего выделить самые последние экземпляры для каждого пользователя.

В Windows Server 2003 и в других версиях, работающих на более высоких доменных функциональных уровнях, есть атрибут AD lastlogontimestamp, реплицируемый между доменными контроллерами. Значения этого атрибута сохраняются в виде длинных целых чисел (на момент написания статьи мое значение атрибута lastlogontimestamp равно 129623232699932000), неудобных для восприятия. Однако разработчики PowerShell для AD предусмотрели преобразование этого числа в наглядное значение, которое называется LastLogonDate и выглядит следующим образом: Суббота, 8 октября 2011 г., 1:07:18 PM. Доступ к этому значению открывает Get-ADUser.

Зная об этом, можно вывести список пользователей, отсортированный по дате последней регистрации в домене:

Get-aduser -f * -pr lastlogondate|sort -property lastlogondate|ft samaccountname, lastlogondate -auto

Таким образом, можно запросить любой DC и выяснить, есть ли в домене пользователи, последний раз регистрировавшиеся в домене, скажем, 22 сентября 2011 года. Однако здесь есть определенные нюансы. Атрибут lastlogontimestamp был добавлен в AD в интересах администраторов AD, которым требовался способ контроля событий регистрации запуска сеанса, однако в Редмонде беспокоились о том, что добавление какого-либо механизма отслеживания может существенно повысить трафик репликации AD.

Чтобы уменьшить трафик, связанный с репликацией значений атрибута lastlogontimestamp, контроллеры домена обновляют это значение не чаще чем через 9–14 дней. При каждой регистрации пользователя DC анализирует текущее значение lastlogontimestamp этого пользователя. Затем DC выбирает случайное число между 9 и 14. Если число дней между последним событием регистрации и текущим моментом меньше выбранного случайного числа, то DC не обновляет значение lastlogontimestamp для данного пользователя. Таким образом, значение lastlogontimestamp каждого пользователя обновляется только один раз примерно каждые 12 дней независимо от того, как часто этот пользователь запускает свой сеанс на протяжении данного периода. Такие данные не слишком точны, но это позволяет уменьшить трафик репликации.

Предположим, я регистрируюсь в полдень 20 января 2012 года, а до этого я не входил в домен начиная с 9:00 9 января текущего года. Таким образом, мой сеанс не регистрировался на протяжении 11,25 дня. Мой DC выбирает случайное число между 9 и 14 - предположим, 13,44. Это число (13,44) превышает временной интервал между двумя последними событиями регистрации (11,25), поэтому DC не меняет мое значение lastlogontimestamp после данного запуска сеанса. Таким образом, атрибут lastlogontimestamp, будучи безусловно полезным, может нести некорректную информацию на протяжении 14 дней и не позволяет выявить пользователей, не регистрировавшихся в домене на протяжении последних двух недель. Впрочем, для поиска неактивных пользователей, скажем, за последние шесть месяцев, он очень удобен.

Можно потренироваться в поиске пользователей, не регистрировавшихся в течение последних 180 дней, с помощью Get-ADUser, но разработчики PowerShell для AD облегчили нам задачу, создав команду search-adaccount, позволяющую выполнить этот запрос:

Search-adaccount -accountinactive -usersonly -timespan "195"

Запрос выглядит простым, но у команды есть два неочевидных момента. Во-первых, отметим двойные кавычки, окружающие число 195 (обязательное требование параметра -timespan). Во-вторых, обратим внимание на число 195 вместо 180. Вспомним также, что атрибут lastlogontimestamp доступен только домену с функциональным уровнем не ниже Windows 2003. Команда search-adaccount имеет особенность, согласно которой к контрольному периоду неактивности следует добавлять 15 (в действительности добавляемое число не в точности равно 15). О том, чем вызвано такое требование, как узнать точное добавляемое значение, а также об альтернативном синтаксисе поиска неактивных пользователей я расскажу в следующей статье.

Марк Минаси (www.minasi.com/gethelp) - старший редактор журнала Windows IT Pro, сертифицированный системный инженер по продуктам Microsoft



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows