PowerShell · 31.01.2025

Сошли с дистанции

Пару постов назад я оставлял где-то здесь скрипт для формирования отчёта со списком созданных пользователей в Active Directory. Сегодня пойдём от обратного и сформируем таблицу со списком отключенных пользователей за последние 30 дней с помощью PowerShell:

## Начало периода отбора ##
$days = ((Get-Date).AddDays(-30))

## Формат вывода ##
$formatdays = $days.ToString("dd.MM.yyyy")

## Данные для заголовка ##
$phrase = "Отключённые пользователи с $formatdays"

## Заголовок окна консоли  ##
[System.Console]::Title = $phrase

## Оформление вывода в HTML ##
$header = @"
<title>Отчёт об отключенных пользователях с $formatdays</title>
<style>
  TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse; width: 100%;}
  TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #87cefa;} 
  TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
  H1 {text-align: center;}
  H2 {text-align: right;}
</style>
"@

$getusers = Get-ADUser -Filter {(WhenChanged -ge $days -and Enabled -eq $false)}`
            -Properties Enabled, Name, mail, SamAccountName, SID, WhenCreated, WhenChanged |
            Select-Object `
            @{Label="Дата изменения"; Expression={$_.WhenChanged}},` 
            @{Label="Дата создания"; Expression={$_.WhenCreated}},`
            @{Label="Статус"; Expression={$_.Enabled}},`
            @{Label="Имя пользователя"; Expression={$_.Name}},`
            @{Label="Электронная почта"; Expression={$_.mail}},`
            @{Label="Логин"; Expression={$_.SamAccountName}},`
            @{Label="SID"; Expression={$_.SID}} |
            Sort-Object "Дата изменения"

## Подсчёт количества пользователей ##
$count = ($getusers).count

## Вывод отчёта в HTML ##
$getusers | ConvertTo-Html -Head $header `
            -PreContent "<H1>$phrase</H1>" `
            -PostContent "<H2>Итого пользователей: $count</H2>" |
            Out-File disableuserreport.html -Verbose

По факту успешного выполнения скрипта будет сформирован html-документ с табличкой.

Примечательно: по какой-то причине в структуре Active Directory не хранится дата отключения, но хранится дата изменения объекта. Таким образом, можно понять когда объект был изменён и если его статус Enabled равен False — будем считать, что последнее изменение — это отключение учётной записи. Конечно, этот показатель очень условен, но альтернативы среди просторов Active Directory я найти не смог. К сожалению.

А ещё можно попробовать собрать данные из журнала операционной системы по идентификатору события 4725. Такой метод будет куда точнее и информативнее.

$server = "DC01"
$date = ((Get-Date).AddDays(-30))
$log = @{ LogName='Security'; ProviderName='Microsoft-Windows-Security-Auditing'; ID=4725; }
Get-WinEvent -ComputerName $server -FilterHashtable $log | Where-Object {($_.TimeCreated -ge $date )} | Select-Object TimeCreated, Message | Format-Table -Wrap
Read-Host

Только не забудьте заменить значение в переменной $server на имя своего контроллера домена.

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