Cyber Security

PowerShell: Notify me when someone is added to the Administrator Group

Will you be notified when there are changes to group memberships? No? Memberships in groups are particularly interesting. Especially if it is the group of the domain administrators. The following article shows how to recognize changes and then check them at regular intervals. The administrator should be notified of any changes. This can be done by message or e-mail. Instead of configuring Audit Policies we do everything in PowerShell and then we put our script into a scheduled task.

The Goal

We want to achieve the following.

Unbenannt

If there are membership changes in the Domain Admins Group, then notifiy me by E-Mail or Message or whatever. It could be look like this:

6.PNG

Or this:

1.JPG

Introduction

First we have to retrieve all Domain Admin group members.

Get-ADGroupMember -Identity "Domain Admins").Name

1.PNG

Alternatively, we could save it in a file Admins.txt:

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

I now add a new user to the group. His name is Arnold Schwarzenberg. Similarities to famous persons are purely coincidental. 😉

Then I save the result in another file Admins2.txt

(Get-ADGroupMember -Identity "Domain Admins").Name | Out-File C:\Temp\Admins2.txt

Now let’s have a look at both files.

3.PNG

Our next step is to compare the content of both files. In order to do that I use Compare-Object.

$a=Get-Content C:\Temp\Admins.txt
$b=Get-Content C:\Temp\Admins2.txt
$differ=Compare-Object -ReferenceObject $a -DifferenceObject $b | Select-Object -ExpandProperty InputObject

4.PNG

Fine. We’ve got him!

Another method is to save the group members in a variable. This is my preferred way. I don’t like those text files 😉

$ref=(Get-ADGroupMember -Identity "Domain Admins").Name
$diff=(Get-ADGroupMember -Identity "Domain Admins").Name

Create a Script to compare membership on a regular basis once per day

Open PowerShell ISE. Let’s put it all together in a script. The first script initiates a Message on the Administrator’s desktop. It checks the members and then waits for about an hour. Then the script checks again and compares the result. Now we use the SideIndicator. This indicator could be helpful if you only want to query changes of values in one direction. The valid values are => and <=

$ref=(Get-ADGroupMember -Identity "Domain Admins").Name
Start-Sleep -Seconds 86398
$diff=(Get-ADGroupMember -Identity "Domain Admins").Name
$result=(Compare-Object -ReferenceObject $ref -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{msg * "The following user was added to the Domain Admins Group: $result"}

The second one sends an alert E-Mail.

$ref=(Get-ADGroupMember -Identity "Domain Admins").Name
Start-Sleep -Seconds 86398
$diff=(Get-ADGroupMember -Identity "Domain Admins").Name
$date=Get-Date -Format F
$result=(Compare-Object -ReferenceObject $ref -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{Send-MailMessage -From SecurityAlert@domain.com -To p.gruenauer@domain.com -SmtpServer EX01 -Subject "Domain Admin Membership Changes | $result was added to the Group" -Body "This alert was generated at $date" -Priority High}

Note the last line. You must fill in these values. Make sure your Mailserver accepts E-Mails from your computer.

The Test

For testing, I’ve simplified the script and sent PowerShell to sleep for only 20 seconds. In this period I quickly add a user to the domain admins group. That was stressful 😉

5.PNG

We’ve got him again!

Now save your script as PowerShell file. (ps1)

Put it into a Scheduled Task

No matter which notification you prefer, you should put it all into a scheduled task that will run every 60 minutes, for example. Watch the Argument in the first line (location of your script), the RepititionInterval in the second line and the UserId in the 4th line. You have to modify this values, especially the UserId.

$Action=New-ScheduledTaskAction -Execute "powershell" -Argument "C:\Alerts\domain_admins.ps1"
$Trigger=New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Seconds 86400) -RepetitionDuration ([timespan]::MaxValue)
$Set=New-ScheduledTaskSettingsSet
$Principal=New-ScheduledTaskPrincipal -UserId "sid-500\administrator" -LogonType S4U
$Task=New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Set -Principal $Principal
Register-ScheduledTask -TaskName "Domain Admins Check" -InputObject $Task -Force

Create a script based on a baseline

The disadvantage of the method above is that we have a time gap of 2 seconds per day.

If the administrator group membership changes very rarely, I recommend creating a baseline. First save your baseline to a file.

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

Then create a script which compares the group membership against your baseline.

$base=Get-Content C:\Temp\Admins.txt
$diff=(Get-ADGroupMember -Identity "Domain Admins").Name
$result=(Compare-Object -ReferenceObject $base -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{msg * "The following user was added to the Domain Admins Group: $result"}

Unbenannt.PNG

Now put this script into a Scheduled Task and run it as often as you like.

Adaption

A further idea would be creating two Scheduled Tasks. (One for the reference, the second for the differences). Another possibility would be to configure audit logging in combination with event log subscriptions.

Anyway: Take the opportunity to use the ideas shown above and adapt it.

See also

See also my other article in which I created a small script which informs you if a Domain Controller is down: PowerShell: Alert me, if a Domain-Controller is down (Try + Catch)

29 replies »

  1. Great stuff – thank you! From a security perspective though, wouldn’t the long sleep time leave the credentials vulnerable to be read from memory using a mimi-katz-type of attack?

    Like

    • Hi Onur!

      To archive this I think you have to enable auditing on Active Directory level, but I think you should get some more information.

      All the best,
      P

      Like

      • Hi,

        I have a request to get an mail notification if a new user is added in to Distributions lists. Please help me by providing a powershell script for it and i need to crate a runbook in SCOM orchestrator for it.

        Like

      • Have you done any of your own research or are you just looking for people to do your job for you?

        Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.