PowerShell How-To

How To Get Notified When a User Is Added to Active Directory

Adam walks through how to proactively monitor an AD group for changes and execute a PowerShell script to take action when that happens.

Every IT professional person needs to monitor their environment for changes. One of those important changes that could greatly affect the security of an organization is unwanted group members in highly privileged Active Directory (AD) groups.

Even though an organization may feel that no one unauthorized is capable of adding members to sensitive AD groups, that doesn't mean it can't happen. IT pros must diligently monitor these AD groups and get proactively notified when new members get added.

In this article, we're going to cover how to proactively monitor an AD group for changes, and then execute a PowerShell script of your choosing to notify or take action when that happens. We'll do this via five stages:

  • Figure out how to determine group membership.
  • Store the current group members somehow.
  • Compare the current membership with the previous value.
  • Execute PowerShell code if the membership changed.
  • Schedule this monitor via a scheduled task.

First, we need to figure out how to pull AD group membership. We can do this with the Get-AdGroupMembership cmdlet that comes with the ActiveDirectory PowerShell module. Below, I'm finding all members that are part of the Domain Admins group.

$currentMembers = Get-AdGroupMember -Identity 'Domain Admins' | Select-Object -ExpandProperty name

Next, we need to store that state somehow. For me, I'll store the date and current group members in a .CSV file.

$monitorStateFilePath = 'C:\GroupMonitor.csv'
$now = Get-Date -UFormat '%m-%d-%y %H:%M'
[pscustomobject]@{
    'Time'    = $now
    'Members' = $currentMembers -join ','
} | Export-Csv -Path $monitorStateFilePath -NoTypeInformation -Append

Next, I need to query the previous reading of group members.

$previousMembers = $null
$previousMembers = Import-Csv -Path $monitorStateFilePath | Sort-Object -Property {[datetime]$_.Time} -Descending | Select-Object -First 1 | Select-Object -ExpandProperty Members

Now I can compare the two group memberships and take some kind of action. Here is where you can insert whatever kind of PowerShell code you'd like.

if (Compare-Object -ReferenceObject $previousMembers -DifferenceObject $currentMembers) {
    ## Insert PowerShell code you'd like to execute here if a change occurred
}

At this point, you have all the code you need to build the monitor. Wrap up the above code in a .PS1 script and it'll execute that PowerShell code every time there's a change found in the Domain Admins group membership. I don't know about you, but I'd rather not be forced to run this script over and over myself. Instead, we can create a scheduled task.

We can create a PowerShell script and a scheduled task in one if we wrap some code into a reusable function I'm calling New-AdGroupMembershipMonitor. With this function, I'm able to quickly create monitors for a particular AD group in no time.

Rather than building this function yourself, go ahead and download a copy from my GitHub repo. This will save you a ton of time.

This function works by rolling up the code I just mentioned above, creating a PowerShell script on a server and then creating a scheduled task executing that PowerShell script as its action. The script includes a function for creating a schedule monitor, which is essentially an easy way to pass parameters to the scheduled task and a function to create the scheduled task itself.

To use the script, you'll first create a schedule object using the Get-MonitorSchedule function. Below, I'm creating a schedule to execute every day at 12 P.M.

$schedule = Get-MonitorSchedule -Interval Daily -Time '12:00'

Once I have the schedule, I just need to specify which AD group I want to monitor and provide the PowerShell code to execute if a change is detected via the Action parameter and the schedule I want to execute the script on.

New-AdGroupMembershipMonitor -GroupName 'Domain Admins' -Action { Send-Email ..... } -Schedule $schedule

Once this is run, you'll notice a scheduled task and a script located on the server you specified as the $script:monitorServer in the script. That's it! Now you can be sure that your PowerShell code will execute every time a membership change is detected in the Domain Admins group.

About the Author

Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.


comments powered by Disqus
Most   Popular