Daily AD Report

Active Directory, Powershell

Daily AD Report

A client I have been working for wanted to monitor certain parts of their AD. They wanted to know of any new users that had been created and also any alterations to the three main admin groups (Domain, Schema and Enterprise). This is the script I came up with.

The first step adds the Quest snap in, this is required because the script will be run as a scheduled task

1
2
if (!(Get-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction Silentlycontinue)) 
  {Add-PSSnapin Quest.ActiveRoles.ADManagement}

The following section adds some variables that will be used later to achieve certain goals of the script.

1
2
3
$Date = Get-Date
$DayOfWeek = $date.DayOfWeek
$GroupsToCheck = "Domain Admins","Schema Admins","Enterprise Admins"

The email will be sent as HTML, so the following section sets the style of the email and a couple of text entries for the email

1
2
3
4
5
6
7
8
9
#HTML headers and content
$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"
 
$Text2 = "<p><b>The Domain Administrators Group was last changed on: </b></p>"
$text3 = "<p><b>The Domain Administrators Group has the following members: </b></p>"

The script now starts querying Active Directory, the first part retrieves all users that were created since the script last ran. As the script only runs Monday through Friday there is an IF statement that changes the query period if the day of the week is Monday. The second IF statement sets a variable that will be used in the body of the email, the output varies based on the search results and the day of the week the script is running.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#get users that have been created since the script last ran
If ($DayOfWeek -eq "Monday") {
$NewUserLastDay = Get-QADUser -CreatedAfter (Get-Date).AddDays(-3)
$text1 = "<p><b>The following users were created over the weekend: </b></p>"
$noNewUsers = "<p><b>There have been no new users added over the weekend.</b></p>"
}
Else {
$NewUserLastDay = Get-QADUser -CreatedAfter (Get-Date).AddDays(-1)
$text1 = "<p><b>The following users were created within the last 24 hours: </b></p>"
$noNewUsers = "<p><b>There have been no new users added within the last 24 hours.</b></p>"
}
If ($NewUserLastDay -eq $null) {
	$NUHTML = $noNewUsers
	}
Else {
	$NUHTML = $NewUserlastDay | Select-Object Name, whenCreated, DN | ConvertTo-Html -Fragment
}

The next section gets information about the groups specified in the $GroupsToCheck variable, If more groups need to be monitored you can edit this variable.
Firstly we cycle through the group list with a Foreach loop and grab the membership of the group. So that membership of the group can be checked a file will need to be created to store the group membership, this will be stored in the same location that the script is run from.

1
2
3
4
5
6
7
8
Foreach ($group in $GroupsToCheck) {
	$AdminGroupMembers = Get-QADGroupMember $group -Indirect | Select-Object name, samAccountName, DN, Description
	#Store the group membership in this file
	$GroupStateFile = $group + "-membership.csv"
	#Check if the file exists, if not create it
	If (!(Test-Path $GroupStateFile)) {
		$AdminGroupMembers | Export-Csv $GroupStateFile -NoTypeInformation
	}

The next section compares the contents of the file with the search results from Active Directory and then populates the $Changes variable with the state of the change, either removed from, or added to the group. The last section adds the results of the Compare-Object to a variable to be used in the body of the email.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	$Changes = Compare-Object -ReferenceObject $AdminGroupMembers -DifferenceObject $(Import-Csv $GroupStateFile) -Property Name, SamAccount, Name, DN | Select-Object Name, SamAccountname, DN, @{n='State';e={If ($_.SideIndicator -eq "=>") {
		"Removed"
		}
		Else {
		"Added"
		}
		}
	}
		If ($Changes) {
		$ChangesHTML += "<p><b>"
		$ChangesHTML += "<p><b>The following changes have been made to the $group group: </b></p>"
		$ChangesHTML += "</p></b>"
		$ChangesHTML += $($Changes  | ConvertTo-Html -Fragment)
	}

The next section retrieves specific information about the group, including group membership and the timestamp of the last change

1
2
3
4
5
6
7
8
9
$AdminGroupInfo = Get-QADGroup -Identity $group
$AdminGroupMembersHTML += "<p><b>"
$AdminGroupMembersHTML += $AdminGroupInfo.Name
$AdminGroupMembersHTML += "</p></b>"
$AdminGroupMembersHTML += "<br>The $($AdminGroupInfo.Name) was last changed on $(($AdminGroupInfo.whenChanged).DateTime)<br>"
$AdminGroupMembersHTML += $AdminGroupMembers | Select-object Name, Description | ConvertTo-Html -Fragment	
 
$AdminGroupMembers | Export-Csv $GroupStateFile -NoTypeInformation
}

Next all the components are concatenated into one variable for addition to the email.

1
$EmailBody = ConvertTo-Html -Head $style -Body "<h2>User Additions</h2> $Text1 $NUHTML <br> $ChangesHTML <h2>Group Membership</h2> $AdminGroupMembersHTML"

Finally the results are emailed. The IF command in here changes the subject to be more eye catching if there have been changes to the groups being monitored.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$smtpServer = "smarthost.example.com"
$smtpFrom = "[email protected]"
$smtpTo = "[email protected]"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.IsBodyHTML = $true
If ($ChangesHTML) {
$message.Subject = "!!Daily AD reports - Warning There Are Group membership Changes!!"
}
Else {
$message.Subject = "Daily AD reports"
}
$message.Body = $EmailBody
 
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

You can download the script in all its entirety here: http://www.timmy8ken.com/2012/12/script-daily-ad-report

Leave a Reply

Your email address will not be published. Required fields are marked *