PowerShell - Поиск неиспользуемых учетных записей пользователей и компьютеров в домене

Для быстрого поиска в домене давно не используемых учетных записей пользователей можно использовать оснастку ‘Active Directory Users and Computers’ (dsa.msc), создав в ней запрос.

image

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

image

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

image

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

Для того чтобы получить полную информацию воспользуемся PowerShell скриптом. Представленный скрипт имеет два режима работы, в зависимости от значения переменной $Mode. Для выборки искомых учетных записей используется значение атрибута lastLogonTimestamp. Значение этого атрибута для учетных записей компьютеров и пользователей является реплицируемым между контроллерами домена с интервалом до 14 дней, поэтому при изменении переменной $LastLogonAgeDaysLimit следует учитывать эту погрешность и не устанавливать значение этой переменной меньше этого срока. 

# Блок переменных
# $LDAPPath – ADSI путь к контейнеру с учетными записями пользователей и компьютеров (в формате LDAP://distinguishedName)
# $Mode - Режим поиска учетных записей (1 - Пользователи, 2 - Компьютеры)
# $CountDisabled – Признак необходимости обработки отключенных учетных записей (1 или 0)
# $LastLogonAgeDaysLimit - Количество дней прошедших с момента последнего входа в систему
#
$LDAPPath = 'LDAP://OU=Accounts,DC=holding,DC=com'
$Mode = 1
$CountDisabled = 0
$LastLogonAgeDaysLimit = 90
#
# Блок поиска
#
$RootDomainOU = [ADSI]$LDAPPath
$Searcher = New-Object System.DirectoryServices.DirectorySearcher($RootDomainOU)
If ($Mode -eq 1) {$Filter = '(objectCategory=person)(objectClass=user)'}
ElseIf ($Mode -eq 2) {$Filter = '(objectCategory=computer)'}
If ($CountDisabled -eq 0) {$Filter = $Filter + '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'}
$Filter = '(&' + $Filter + ')'
$Searcher.Filter = $Filter
$Searcher.PageSize = 5000
[Void]$Searcher.PropertiesToLoad.Add('cn')
[Void]$Searcher.PropertiesToLoad.Add('sAMAccountName')
[Void]$Searcher.PropertiesToLoad.Add('description')
[Void]$Searcher.PropertiesToLoad.Add('lastLogonTimestamp')
$Objects = $Searcher.findall()
#
# Блок основного вывода 
#
$LLDays = (Get-Date).AddDays(-$LastLogonAgeDaysLimit).ToFileTime()
$OldObjects = $Objects | Where-Object {$_.properties.lastlogontimestamp -le $LLDays}
$OldObjects | Select `
@{label='Object Name';expression={$_.properties.cn}},`
@{label='sAMAccountName';expression={$_.properties.samaccountname}},`
@{label='Last Logon Timestamp';expression={[datetime]::FromFileTime(($_.properties.lastlogontimestamp)[0])}},`
@{label='Description';expression={$_.properties.description}}`
| Sort -Property 'Last Logon Timestamp'`
| Format-Table –AutoSize
Write-Host '---------------------------------------------------'
write-host 'Domain accounts in OU:' $Objects.Count
write-host 'Domain accounts with old lastLogonTimestamp:' $OldObjects.Count
Write-Host '---------------------------------------------------'


Дополнительные источники информации:

MSDN Library - Active Directory Schema - Last-Logon-Timestamp Attribute
TechNet Blogs - Ask the Directory Services Team - “The LastLogonTimeStamp Attribute” – “What it was designed for and how it works”
TechNet Forums - Scripting Languages - Вывести список неактивных пользователей и ПК в одном сайте AD

Всего комментариев: 7 Комментировать

  1. Обратная ссылка: PowerShell – Аудит использования учетных записей « ИТ Блог Алексея Максимова /

  2. yurgers /

    Добавил строчки
    [Void]$Searcher.PropertiesToLoad.Add("DistinguishedName")

    и @{label=‘Name’;expression={$_.properties.DistinguishedName}},`

    а они почему то не выводятся( подскажите с чем это может быть связано?

    1. yurgers /

      разобрался)

      оказывается {$_.properties.DistinguishedName}} надо маленькими писать)

  3. foxxxmulder /

    Отличный скрипт! Спасибо! Я в PS к сожалению, мало понимаю, не подскажите как найденные аккаунты еще и отключить или переместить в отдельный юнит?

  4. foxxxmulder /

    Нашел, как решить этот вопрос с помощью запросов в оснастке Active Directory Users and Computers. Спасибо

  5. foxxxmulder /

    Точнее так, если при запросе описанном Вами в начале статьи поставить галку Disable Accounts , выставить нужный период дней и поискать, то в выборку попадают и учетные записи компьютеров.

  6. Artur /

    Подскажите, как к этому всему добавить информацию заблокирована/отключена ли учётная запись пользователя или нет?

Добавить комментарий