Windows OS Hub
  • Windows Server
    • Windows Server 2022
    • Windows Server 2019
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Active Directory Domain Services (AD DS)
    • Group Policies
  • Windows Clients
    • Windows 11
    • Windows 10
    • Windows 8
    • Windows 7
    • Windows XP
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
    • KVM
  • PowerShell
  • Exchange
  • Cloud
    • Azure
    • Microsoft 365
    • Office 365
  • Linux
    • CentOS
    • RHEL
    • Ubuntu
  • Home
  • About

Windows OS Hub

  • Windows Server
    • Windows Server 2022
    • Windows Server 2019
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Active Directory Domain Services (AD DS)
    • Group Policies
  • Windows Clients
    • Windows 11
    • Windows 10
    • Windows 8
    • Windows 7
    • Windows XP
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
    • KVM
  • PowerShell
  • Exchange
  • Cloud
    • Azure
    • Microsoft 365
    • Office 365
  • Linux
    • CentOS
    • RHEL
    • Ubuntu

 Windows OS Hub / PowerShell / How To Monitor AD Group Changes Using PowerShell

May 10, 2023 Active DirectoryPowerShell

How To Monitor AD Group Changes Using PowerShell

Let’s look at how to create a simple administrator notification system when someone adds a new user to the important Active Directory security group. For example you want to track the changes of domain administrator group, and if a new user is added to it, you want to get the corresponding notification (by e-mail or in a pop-up alert message).

There are to ways to implement it:

  1. You can enable the event audit on the domain controllers and track the event of adding a new user to the security group (EventID 4728);
  2. You can store a local text file with the list of users of a certain group and regularly compare it to the current members list of the domain group.

Contents:
  • Audit of Adding a User to a Group on the Domain Controller
  • Comparing the Current Members of the Domain Group with the Saved Template

Audit of Adding a User to a Group on the Domain Controller

If the audit policy is enabled in the GPO section Computer Configuration -> Windows Settings -> Security Settings -> Advanced Audit Configuration -> Account Management -> Audit Security Group Management, the event with the EventID 4732 (A member was added to a security-enabled global group) appears in the Security log after adding a new user to any Active Directory group.

Audit Security Group Management - domain controller policy

Using PowerShell, you can track this event in the Security log. For example, let’s display all events with this ID on the domain controller for the last 24 hours. To make it more convenient, we’ll display the name of the AD group that has changed, the name of the added account and the administrator who has added this user to the group. The script is similar to the one given in the article How to Get all Active Directory Users Created in the Last 24 Hours.

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

check ad group changes by event on a DC

Then create a new scheduler task on the domain controller to be triggered by the event with the ID 4732. When this event occurs, a message will be sent to the user. ( use the Windows Event Triggers to attach a script to event).

However, the problem is that the security log of only one DC is checked. If a user has been added to a group on another domain controller, you won’t see this event. Of course, you can subscribe to the events of several DCs or run the script on each controller, but if there are a lot of DCs in the domain, it is not very convenient.

Tip. The example of checking all DCs in the domain in a loop and collecting events from them can looks like this (the code example is taken from the article How to Track Who Reset Password of a User in Active Directory):

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

Let’s consider another approach.

Comparing the Current Members of the Domain Group with the Saved Template

Let’s display the list of users in the “Domain Admin” group using the Get-ADGroupMember cmdlet and save the resulting list to a text file (we are building a recursive list of users including nested groups):

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

Then add a new user to the “Domain Admins” group and save the list of users again to another file:

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

Now compare two files and display the difference in the lists:

$old_adgroup_members=GC C:\PS\DomainAdmins.txt
$new_adgroup_members=GC C:\PS\DomainAdminsActual.txt
$diff=Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $new_adgroup_members | Select-Object -ExpandProperty InputObject
write-host $diff

The new account added to the AD group is displayed.

You can also display the message in the console:

$result=(Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{msg * "A user $result has been added to Domain the Admins group"}

alert then user is add to the ad admins group

Or send an email using Send-MailMessage cmdlet:

If ($result)
{Send-MailMessage -SmtpServer war-msg01 -From [email protected] -To [email protected] -Subject "A user $result has been added to the Domain Admins group" -Body "Created on $date" -Priority High}

You can save this script to a file admins_group_changes.ps1 and run it regularly using Task Scheduler (you can create scheduled task using PowerShell ). Create a new Scheduler job that will run your PowerShell script every 24 hours. It will compare the members of the Domain Admins group with the list saved locally.

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

Thus, the members of the Domain administrator group will be checked once a day, and if there are any changes, an administrator will get an alert (in a pop-up window or by email).

3 comments
0
Facebook Twitter Google + Pinterest
previous post
Error 0x80073CFA: Can’t Uninstall Apps using Remove-AppxPackage in Windows 10
next post
How to Enable Access-Based Enumeration (ABE) on Windows Server?

Related Reading

Zabbix: How to Get Data from PowerShell Scripts

October 27, 2023

Tracking Printer Usage with Windows Event Viewer Logs

October 19, 2023

PowerShell: Configure Certificate-Based Authentication for Exchange Online (Azure)

October 15, 2023

How to Query and Change Teams User Presence...

October 8, 2023

Installing Language Pack in Windows 10/11 with PowerShell

September 15, 2023

3 comments

visitor February 7, 2020 - 1:43 pm

I tried the ‘Comparing the Current Members of the Domain Group with the Saved Template’ part but it doesn’t work. It writes the files with the correct content but something in diff goes wrong.

(Get-ADGroupMember -Identity “Domain Admins” -recursive).Name | Out-File C:\PS\DomainAdmins.txt
(Get-ADGroupMember -Identity “Domain Admins” -recursive).Name | Out-File C:\PS\DomainAdminsActual.txt
$old_adgroup_members=GC C:\PS\DomainAdmins.txt
$new_adgroup_members=GC C:\PS\DomainAdminsActual.txt
$diff=Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $new_adgroup_members | Select-Object -ExpandProperty InputObject
write-host $diff
$result=(Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq “=>”} | Select-Object -ExpandProperty InputObject) -join “, ”
If ($result)
{msg * “A user $result has been added to Domain the Admins group”}

Compare-Object : Cannot bind argument to parameter ‘DifferenceObject’ because it is null.
At C:\ps\da2.ps1:7 char:81
+ … -ReferenceObject $old_adgroup_members -DifferenceObject $diff | Where …
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Compare-Object], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObje
ctCommand

Reply
admin February 11, 2020 - 7:36 am

Please, make sure that your DomainAdmins.txt and DomainAdminsActual.txt files are not empty.

Reply
Visitor January 27, 2021 - 3:58 pm

This only seems to work if you add users to security groups on the domain controller itself, not if someone adds a user on their workstation — it won’t generate an event on the DC. I’m only getting event ID 4728 when the user is added locally on the DC. If I add a user to a security group on my workstation via AD, I generate event ID 4732 on my local workstation, but nothing on the DC.

Reply

Leave a Comment Cancel Reply

Categories

  • Active Directory
  • Group Policies
  • Exchange Server
  • Microsoft 365
  • Azure
  • Windows 11
  • Windows 10
  • Windows Server 2022
  • Windows Server 2019
  • Windows Server 2016
  • PowerShell
  • VMWare
  • Hyper-V
  • Linux
  • MS Office

Recent Posts

  • Zabbix: How to Get Data from PowerShell Scripts

    October 27, 2023
  • Tracking Printer Usage with Windows Event Viewer Logs

    October 19, 2023
  • PowerShell: Configure Certificate-Based Authentication for Exchange Online (Azure)

    October 15, 2023
  • Reset Root Password in VMware ESXi

    October 12, 2023
  • How to Query and Change Teams User Presence Status with PowerShell

    October 8, 2023
  • How to Increase Size of Disk Partition in Ubuntu

    October 5, 2023
  • How to Use Ansible to Manage Windows Machines

    September 25, 2023
  • Installing Language Pack in Windows 10/11 with PowerShell

    September 15, 2023
  • Configure Email Forwarding for Mailbox on Exchange Server/Microsoft 365

    September 14, 2023
  • How to View and Change BIOS (UEFI) Settings with PowerShell

    September 13, 2023

Follow us

  • Facebook
  • Twitter
  • Telegram
Popular Posts
  • Changing Desktop Background Wallpaper in Windows through GPO
  • Active Directory Dynamic User Groups with PowerShell
  • Restricting Group Policy with WMI Filtering
  • How to Check Who Reset the Password of a User in Active Directory
  • How to Deploy SSL Certificate on a Computers Using GPO?
  • Configuring Kerberos Authentication in Different Browsers
Footer Logo

@2014 - 2023 - Windows OS Hub. All about operating systems for sysadmins


Back To Top