Если инфраструктурой домена Active Directory управляет несколько администраторов, бывает трудно отследить кто конкретно внес изменения, добавил или удалил пользователя из группы безопасности. В этой статье мы покажем, как с помощью политика аудита и скрипта PowerShell настроить отправку автоматических оповещений (по email или в мессенджер), когда новые пользователь был добавлен в одну их привилегированных (административных) групп AD (таких как
Domain Admins
,
Enterprise Admins
,
Schema Admins
и т.д.).
Включить политику аудита добавления пользователей в группы AD
Включите для контроллеров доменов политику аудита изменения в группах безопасности AD.
- Откройте консоль управления доменными политиками Group Policy Management (
gpmc.msc
); - ОтредактируйтеDefault Domain Controller Policy;
- ПерейдитевразделComputer Configuration -> Policies -> Windows Settings -> Security Settings -> Advanced Audit Configuration -> Account Management. Включите параметр Audit Security Group Management с логированием успешных событий (Success);
- После применения новых настроек GPO при любых изменения в группах AD (создаение, удаление, группы, добавлени/удаление пользователей в группы) в журнале Security контроллера домена будет появляться соотвествующее событие.
Так, при добавлении пользователя в группу появится событие с EventID 4732
A member was added to a security-enabled global group.
Или EventID 4728:
A member was added to a security-enabled local group.
В описании события видно:
- Какая группа была изменена:
Group Name: DnsAdmins
- Какой пользователь был добавлен в группу:
Member: Security ID:
- Кто изменил состав группы:
Subject: Account Name:
Получить список измененных групп в AD с помощью PowerShell
Получить информацию о всех последних событиях 4732 и 4728 из Event Viewer на контроллере домена за последние 24 часа можно с помощью PowerShell командлета Get-WinEvent:
$time = (get-date) - (new-timespan -hour 24) $result = Get-WinEvent -FilterHashtable @{logname='Security';id=4732,4728;StartTime=$Time} -ErrorAction SilentlyContinue| ForEach-Object { $eventXml = ([xml]$_.ToXml()).Event [PSCustomObject]@{ TimeCreated = $eventXml.System.TimeCreated.SystemTime -replace '\.\d+.*$' NewUser = $eventXml.EventData.Data[0]."#text" Group = $eventXml.EventData.Data[2]."#text" Admin = $eventXml.EventData.Data[6]."#text" Computer = $eventXml.System.Computer } } $result | Format-Table -AutoSize
В результатах скрипта будет отображаться имя группы AD, которая изменилась, какая учетная запись была добавлена и кто из администраторов добавил пользователя в группу (скрипт по примеру из статьи Получение списка пользователей AD, созданных за 24 часа).
Чтобы отфильтровать изменения только в привилегированных группах пользователей, создайте переменную:
$AdminGroups = @('Enterprise Admins', 'Domain Admins', 'DNSAdmins', 'Microsoft Exchange Servers')
Теперь нужно найти только те события, в которых были изменены привилегированные группы:
$filteredevents=$result | Where-Object { $_.Group -in $AdminGroups }
Теперь нужно отправить администраторам уведомление об изменении привилегированных групп в AD. Можно отправить email с помощью командлета Send-MailMessage
If ($filteredevents) { $mailbody= $filteredevents|ConvertTo-Html {Send-MailMessage -SmtpServer msg01 -From [email protected] -To [email protected] -Subject "Были внесены изменения в административные группы AD!" -Body $mailbody -Priority High} }
Или вы можете отправить оповещение в ваш мессенджер:
- Отправка уведомлений в Telegram из скриптов PowerShell
- Отправка сообщения в канал MS Teams с помощью PowerShell
Назначить скрипт аудита групп администратора на все контроллеры домена
Если в вашем домена несколько контроллеров домена, такой скрипт нужно запускать на каждом из них. Дело в том, что события изменение членства группы логгируется на контроллере домена, к которому подключена ваша оснастка ADUC или консоль PowerShell с командой Add-ADGroupMember (обычно это текущий Logon Server). Поэтому нужно проверить каждый DC на наличие указанных событий. Вы можете перебрать в цикле все контроллеры домена:
$DCs = Get-ADDomainController -Filter *
foreach ($DC in $DCs){
Get-WinEvent -ComputerName $DC -FilterHashtable …
…
}
Но удобнее создать на всех DC задание планировщика, которое будет запускать ваш PowerShell скрипт по расписанию.
- Скопируйте ваш PS1 файл с PowerShell скриптом в каталог NETLOGON (
\\winitpro.loc\NETLOGON
); - Назначьтена OU Domain Controllers новую GPO, которая создаст на них новое задание планировщика (Computer Configuration -> Preferences -> Control Panel Settings -> Scheduled Tasks), которое запускает ваш PowerShell скрипт;
On a schedule ->Daily
,
Action:Start a program
Program/Script:C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
Add Arguments (optional):-ExecutionPolicy Bypass -command "& \\winitpro.loc\NETLOGON\CheckADAdminsGroups.ps1"
- Таким образом состав групп администраторов будет проверяться один раз в день и в случае добавления в них новых пользователей администратор будет получать уведомление. В уведомлении будет указана группа, новые пользователь и информацию о том, кто добавил пользователя в группу AD.
В доменных инфраструктурах с большим количеством контроллеров домена и администраторов можно развернуть централизованную система сбора логов со всех DC (ELK, GrayLog, splunk, и т.д)
Не добавляется задача для отправки по почте, здесь видео
Это у меня одного или у всех так?
Отправка писем через задание планировщика является устаревшей функцией (deprecated) и не поддерживается, если я не ошибаюсь, начиная с Windows Server 2012. Для отправки писем нужно запускать внешний скрипт. Проще всего через PoSh командлет Send-MailMessage, как указано в статье.
Спасибо!
Спасибо за статью. В альтернативу хочу добавить, что описываемую задачу успешно решает связка Scom + Acl Services. С выгрузки всех событий безопасности DC&RODC в отчёты web формы sql report service.
Да, конечно SCOM/MOM в этом плане более удобные инструменты. Но для небольшой задачи мониторинга групп вполне можно обойтись и такими скриптами.
Насчет скрипта, удобнее сделать бесконечный do while и слать письмо изнутри цикла ну и там же sleep c желаемой задержкой хоть минуту хоть день. А таск запускать on startup
В общем-то да, можно и в цикле постоянно проверять. В итоге можно придти к системному PoSh сервису, который постоянно отслеживает изменения в группах AD. 🙂
В моем случае оповещения раз в день было достаточно.
Подскажите, возможен ли вариант «Сравнение текущего состава доменной группы с шаблоном» при котором задача планировщика запускалась бы от имени gMSA (https://winitpro.ru/index.php/2014/03/28/group-managed-service-accounts-v-windows-server-2012).
Я при таком варианте получаю ошибку планировщика 0x1. Надо пологать проблема в том, что у gMSA нет прав на что-то, вопрос только в том, какие права надо добавить чтобы заработало (вход в качестве пакетного задания для gMSA предоставил)
Подскажите, можно ли вариант «Сравнение текущего состава доменной группы с шаблоном» сделать так, чтобы запланированное задание запускалось от имени gMSA. У меня при запуске задания от имени gMSA появляется ошибка планировщика 0x1. Как мне кажется gMSA не хватает каких то прав.
Попробуйте создавать задание планровщика для аккаунта gMSA так. Сначала создаете и настройте новое задание через графический интерфейс Task Scheduler от имени просто пользователя, а потом меняете акканунт на gMSA командой
schtasks /change /TN \TaskName /RU DOMAIN\gMSA_account$ /RP
На запрос пароля оставляете его пустым.
подскажите пожалуйста, как создать запрос по нескольким событиям сразу, например ID=4720 (Создание пользователя) и ID=4726 (Удаление пользователя)
перечисляйте ID событий через запятую:
Get-WinEvent -ComputerName $DC -FilterHashtable @{LogName="Security";ID=4720,4726 ;StartTime=$Time}
Подскажите пожалуйста, В первом варианте скрипт нацелен на все группы в домене, а как бы првильно нацелить его только на определённую группу, допустим Domain admins.
Подскажите а как будет выглядеть скрипт ,если использовать переменную
$AdminGroups = @(‘Enterprise Admins’, ‘Domain Admins’, ‘DNSAdmins’, ‘Microsoft Exchange Servers’) и найти события
$filteredevents=$result | Where-Object { $_.Group -in $AdminGroups }
Не понял вопроса. В вашем коде ничего не поменялось, взят рабочий кусок из статьи.
В этот код куда нужно добавить эти строчки?
Какие строчки убрать из кода чтобы выводилась инфа только об Enterprise admins,domain admins?
Раз добавили 4728 и 4732 то тогда ещё надо 4756, так группа ещё бывает универсальная.
А так всё понятно и доступно.