Sending Email Alerts When Active Directory Groups Change

It’s obviously a good idea to monitor certain Active Directory groups for membership changes. An example of a group that should be monitored is the Domain Admins group. I was looking for an easy way to monitor groups for changes and to send an email alert when something has changed. I’ve written a Python script to do this. I’ve opted to hash the group members and to store this value along with the group name in a SQLite database. I chose to compare hash values to speed up the operation and to not have to worry about comparing individual group members each time. I won’t go into the details on how to set up or update SQLite databases as there are many good resources available that describe this process.
The script I wrote uses pyad to connect to Active Directory, you can click here to read up on the pyad libraby. I’m also using a template file to generate the body of the email message, I’ll post a screenshot of the simple template after the code.
For this script to be effective at alerting for changes you should set up a scheduled task to run the script frequently.

from pyad import adgroup
import hashlib
import sqlite3
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from string import Template

#get current hash values of monitored groups
def getHash(adg):
    mlist = []
    for x,y in adg:
        group = adgroup.ADGroup.from_dn("CN="+x+y+"DC=testdom,DC=com")
        gg = group.get_members()
        fhash = hashlib.sha256(repr(gg).encode('utf-8')).hexdigest()
    return mlist

#get stored hash values and compare to newly retrieved values
def compVal(newVal):
    msqll = []
    conn = sqlite3.connect('ad.sqlite')
    conn.row_factory = sqlite3.Row
    cur = conn.execute('SELECT Item, HashVal FROM adhash')
    for row in cur:
    mydiff = set(newVal) - set(msqll)
    return mydiff

#read email message template
def readTemp(filename):
    with open(filename, 'r', encoding='utf-8') as temp:
        tempContent =
    return Template(tempContent)

#send an email alert with a list of the groups that have been changed
def sendAlert(myChanges):
    msgTemp = readTemp('Temp.txt')
    s = smtplib.SMTP(host='', port=25)
    msg = MIMEMultipart()
    message = msgTemp.substitute(ChGroups=myChanges)
    msg['From'] = ''
    msg['To'] = ''
    msg['Subject'] = 'Active Directory Change Alert'
    msg.attach(MIMEText(message, 'plain'))

groupslist = [("TestSec",",CN=Users,"),("Domain Admins",",CN=Users,"),("MonMe",",OU=SecGroup,")] #include name of the group and all associated OUs
newq = getHash(groupslist)
statq = compVal(newq)

#If changes are detected an email will be sent with the list of groups that were changed
if statq:
    for x,y in statq:
    adchgstr = ', '.join(mlist)

Here is a screenshot of the simple email template text file:
Here is a screenshot of the generated email:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s