Розглянемо на прикладах процес створення простої системи оповіщення Администартор про додавання нового користувача в групу безпеки 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
Тепер на контролері домену потрібно створити нове завдання планувальника і прив'язати його запуск до появи події 4728. При появи даної події потрібно відправити користувачеві лист (як прив'язати скрипт до події описано в статтях Тригери подій Windows і Запуск PowerShell скрипта при виникненні події, не буду повторюватися).
Однак проблема в тому, що перевіряється журнал тільки одного DC. Якщо додавання користувача в групу виконувалося на інший контролері домену, ви не побачите цю подію. Можна, звичайно створити підписку на події з кількох DC або перебирати всі контролери скриптом, але в тому випадку, якщо в домені велика кількість DC, все це не дуже зручно.
Порада. Приклад циклу з переборовши всіх DC в домені за допомогою Get-ADDomainController і збором подій з них може виглядати так (приклад з цієї статті):$ 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"
Або відправити лист за допомогою командлета Send-MailMessage:
If ($ result)
Send-MailMessage -SmtpServer msg01 -From [email protected] -To [email protected] -Subject "До групи Domain Admins доданий користувач: $ result" -Body "Повідомлення створено $ date" -Priority High
Даний скрипт можна зберегти в файл admins_group_changes.ps1 і запускати регулярно за допомогою планувальника (як створити завдання планувальника з допомогою PowerShell). Створимо нове завдання планувальника, яке раз на добу запускає наш PowerShell скрипт, координує виконує звірку складу групи доменних адміністраторів з локально збереженим списком.
$ Trigger = New-ScheduledTaskTrigger -At 10:00 am -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
Таким чином склад групи адміністраторів буде перевірятися один раз в день і в разі наявності змін Администартор буде отримувати повідомлення (спливаючих повідомленням або листом).