Active Directory is a critical component of many organizations. It can also get overwhelming containing hundreds of thousands of objects changing constantly. Luckily, you can track Active Directory changes with some PowerShell expertise and a little time.
In this tutorial, you’re going to learn how to use WMI events to track Active Directory changes and keep you in the know about what’s going on with your Active Directory objects!
Prerequisites
This article will be a hands-on tutorial. If you’d like to follow along, be sure you have the following:
- An Active Directory domain – This tutorial will use Windows Server 2019 with an Active Directory and forest functional level set to 2019, but domain controllers (DCs) running Windows 2008 R2 or later should work. The tutorial will be using a domain called test.local with two DCs, DC01 and DC02.
- A domain-joined Windows PC with PowerShell installed. This tutorial will use Windows 10 with Windows PowerShell v5.1 or PowerShell 7.
- PowerShell Active Directory Module.
- A user account as a member of the Domain Admins groups in the domain.
Finding Active Directory Groups with WMI
Before you can get notified when an object changes in Active Directory, you must first know the WMI class that the WMI event will show up in and query group members. To do that, on a DC:
1. Open PowerShell.
2. Run Get-CimClass
to connect to the namespace and find all available classes in the namespace. In the CimClassName
column, you’ll see a ds_group
. This class lists all groups in Active Directory and their attributes.
Get-CimClass -Namespace 'ROOT\Directory\LDAP'
3. Now, run Get-CimInstance
to find all instances of the ds_group
class which will return the cn
property of each group.
Get-CimInstance -Namespace 'root\directory\ldap' -ClassName ds_group | Select-Object -Property DS_cn
Creating a WMI Event Subscription
Now that you know where to find the groups in WMI, the next step is set up a WMI event subscription to “listen” for changes to those WMI instances. To monitor for a specific event (like a change to an Active Directory group), you must subscribe to the WMI event.
You can subscribe to many different types of WMI events from creation, removal, and modification events. In this case, you need to know when a CIM instance (AD group) is modified. In that case, you’ll use a class named CIM_InstModification
. The CIM_InstModification
class monitors any CIM instance for modifications.
Develop the WQL Query
To set up the WMI event subscription, you must first develop a WQL query. WQL is a simple language dedicated to WMI that allows you to find WMI instances in a SQL-like syntax. In this example, the query you’re looking for looks like the below example.
The below WQL query will look for all events that modify instances matching the name of DS_group
. You’ll also notice the
within
operator. This operator is the polling interval telling Windows to check for new events every 10 seconds.
Select * from CIM_InstModification within 10 where TargetInstance ISA 'DS_group'
You can also query for changes to specific AD groups by including more conditions such as adding
AND TargetInstance.ds_cn='Enterprise Admins'
to the end of your WQL statement.
Create the WMI Subscription in PowerShell
Now that you’ve crafted the WQL query, the next step is to drop into PowerShell and use it to subscribe to the event. To do that:
1. Open PowerShell on the domain controller.
2. Create a variable called $query
assigning the query you just came up with as the value.
$query = "Select * from CIM_InstModification within 10 where TargetInstance ISA 'DS_group'"
3. Use that query to create the subscription (register the event) using the Register-CimIndicationEvent
cmdlet. The below command registers a WMI subscription called GroupMonitoring
using the query to limit results to only DS_Group
modification events within the ROOT\directory\LDAP
namespace.
Register-CimIndicationEvent -Query $query -SourceIdentifier 'GroupMonitoring' -MessageData 'Group Info Changed' -Namespace 'ROOT\directory\LDAP'
Register-CimIndicationEvent
creates a temporary WMI event subscription. When you close the PowerShell console, the subscription will no longer be active. Use a permanent event subscription to monitor AD groups long term.
4. Now, confirm you’ve successfully registered a subscription by running Get-EventSubscriber
which should return an object that looks like below.
Reading WMI Events
Windows should now be monitoring all modification events to all Active Directory groups. To test this, let’s now add a member to a group and see what happens.
Assuming you’re still in PowerShell on the DC:
1. Run the Add-ADGroupMember
cmdlet to add a user to the Enterprise Admins group. The below example is adding a user account named User2.
After 10 seconds or so, the event should have fired you set up a subscription for earlier.
Add-ADGroupMember -Identity 'Enterprise Admins' -Members User2
2. To find the event, run the Get-Event
cmdlet to search for all newly registered events. If all goes well, you should then see output similar to the below screenshot. In the screenshot, the SourceInstance
is the current value of the object attribute. The PreviousInstance
value is the previous value of the object attribute.
(Get-Event).SourceEventArgs.newevent
3. Now, narrow down the result and only display the current alert values as shown below. You will now see the current list of group members in the Enterprise Admins group.
(Get-Event).SourceEventArgs.newevent.SourceInstance | Select-Object -Property ds_member
If you’d like to get the value before the change happened, look at the PreviousInstance
object’s DS_Member
property as shown below.
(Get-Event).SourceEventArgs.newevent.PreviousInstance | select DS_member
Conclusion
Now that you know how to set up a WMI event subscription to track Active Directory changes, you can take this PowerShell code and build a monitoring script from it.
See if you can now build a monitoring tool by perhaps logging these events to the Windows event log with the New-WinEvent
cmdlet or sending an email with Send-MailMessage
!