Найти тему
WinITPro.ru - Блог админа

PowerShell скрипт, который оповещает админа при добавлении пользователя в группу Active Directory

Оглавление

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

Есть два варианта организации такого решения:

  • Можно включить аудит событий на контроллерах домена и отслеживание появление события добавления пользователя в группу безопасности (EventID 4728)
  • Хранить локальный текстовый файл со списком пользователей в определенной группе и периодически сравнивать его с текущими членами доменной группы

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

В том случае, если у вас в GPO включена политика аудита Computer Configuration -> Windows Settings -> Security Settings -> Advanced Audit Configuration -> Account Management -> Audit Security Group Management, то при добавлении пользователя в группу Active Directory в журнале Security появляется событие EventId 4728 (A member was added to a security-enabled global group).

С помощью PowerShell можно отследить появление этого события в журнале безопасности. К примеру, выведем все события с этим кодом за 24 часа на котроллере домена. Для удобства мы будем выводить имя группы AD, которая изменилась, какая учетная запись была добавлена и кто из администраторов добавил пользователя в группу (скрипт по примеру из статьи Получение списка пользователей AD, созданных за 24 часа).

$time = (get-date) - (new-timespan -hour 24)
Get-WinEvent -FilterHashtable @{LogName="Security";ID=4728;StartTime=$Time}| Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$NewUser = $event.Event.EventData.Data[0]."#text"
$ADGroup = $event.Event.EventData.Data[2]."#text"
$AdminUser = $event.Event.EventData.Data[6]."#text"
$dc = $event.Event.System.computer
$dc + “|” + $Time + “|” + “|” + $ADGroup + “|” + $NewUser + “|” + $AdminUser
}
}

-2

Теперь на контроллере домена нужно создать новое задание планировщика и привязать его запуск к появлению события 4728. При появления данного события нужно отправить пользователю письмо (как привязать скрипт к событию описано в статьях Триггеры событий Windows и Запуск PowerShell скрипта при возникновении события, не буду повторяться).

Однако проблема в том, что проверяется журнал только одного DC. Если добавление пользователя в группу выполнялось на другой контроллере домена, вы не увидите это событие. Можно, конечно создать подписку на события с нескольких DC или перебирать все контроллеры скриптом, но в том случае, если в домене большое количество DC, все это не очень удобно.

Совет. Пример цикла с переборов всех DC в домене и сбором событий с них может выглядеть так (пример из этой статьи):

$time = (get-date) - (new-timespan -hour 124)
$DCs = Get-ADDomainController -Filter *
foreach ($DC in $DCs){
Get-WinEvent -ComputerName $DC -FilterHashtable @{LogName="Security";ID=4728;StartTime=$Time}| Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$Time = Get-Date $_.TimeCreated -UFormat "%Y-%m-%d %H:%M:%S"
$NewUser = $event.Event.EventData.Data[0]."#text"
$ADGroup = $event.Event.EventData.Data[2]."#text"
$AdminUser = $event.Event.EventData.Data[6]."#text"
$dc = $event.Event.System.computer
$dc + “|” + $Time + “|” + “|” + $ADGroup + “|” + $NewUser + “|” + $AdminUser
}
}
}

Рассмотрим другой подход.

Сравнение текущего состава доменной группы с шаблоном

С помощью командлета Get-ADGroupMember выведем список пользователей в группе Domain Admin и сохраним полученный список в текстовый файл (строим рекурсивный список пользователей, с учетом вложенных групп).

(Get-ADGroupMember -Identity "Domain Admins" -recursive).Name | Out-File C:\PS\DomainAdmins.txt

Теперь добавим в группу Domain Admins нового пользователя и еще раз сохраним список пользователей, но уже во второй файл.

(Get-ADGroupMember -Identity "Domain Admins" -recursive).Name | Out-File C:\PS\DomainAdminsCurrent.txt

Теперь сравним два файла и выведем на экран отличия в списках:

$oldadm=GC C:\PS\DomainAdmins.txt
$newadm=GC C:\PS\DomainAdminsCurrent.txt
$diff=Compare-Object -ReferenceObject $oldadm -DifferenceObject $newadm | Select-Object -ExpandProperty InputObject
write-host $diff

На экран вывелась учетная запись, которого добавили в группу AD.

Можно вывести сообщение в консоль:

$result=(Compare-Object -ReferenceObject $oldadm -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{msg * "В группу Domain Admins добавлен пользователь: $result"}

-3

Или отправить письмо с помощью командлета Send-MailMessage:

If ($result)
{Send-MailMessage -SmtpServer msg01 -From ADChanges@winitpro.ru -To admin@winitpro.ru -Subject "В группу Domain Admins добавлен пользователь: $result " -Body "Сообщение создано $date" -Priority High}

Данный скрипт можно сохранить в файл admins_group_changes.ps1 и запускать регулярно с помощью планировщика (как создать задание планировщика с помощью PowerShell). Создадим новое задание планировщика, которое раз в сутки запускает наш PowerShell скрипт, коорый выполняет сверку состава группы доменных администраторов с локально сохраненным списком.

$Trigger= New-ScheduledTaskTrigger -At 10:00am -Daily
$User= "NT AUTHORITY\SYSTEM"
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "C:\PS\admins_group_changes.ps1 "
Register-ScheduledTask -TaskName "Check Admins Group" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force

Таким образом состав группы администраторов будет проверяться один раз в день и в случае наличия изменений администартор будет получать уведомление (всплывающим сообщением или письмом).