Ghetto GPO Change-Audit Powershell Emailing script
Problem:
What AD GPO’s changed yesterday?
Solution:
Ultra ghetto. May or may not need special Security policy Audit rights enabled on DC’s, i don’t remember 2021.
Modify $testing = true to $testing = false for production.
######################################################################### | |
############ Ghetto GPO Change Audit ############## | |
############ DRAFT / WIP in-progress ############## | |
############ Lists/Emails modified GPO's only, not linking ############## | |
######################################################################### | |
############ script by NJD 2021-03-08, edited Oct 2024 ############## | |
######################################################################### | |
############# Programmatically set variables ################ | |
$MyDomain = (Get-ADDomain).DNSRoot # AD Domain root in plain-text format | |
$MyDomainDN = (Get-ADDomain).DistinguishedName # AD Domain root distinguishedName | |
$today = Get-Date '0:00' # today at minute 0 | |
$yesterday = $Today.AddDays(-1) # yesterday | |
$hostname=$Env:COMPUTERNAME | |
########### End Programmatically set variables ############## | |
########## REQUIRED USER VARIABLES ################### | |
$adminEmailAddr = "email1$MyDomain"#,"email2@$MyDomain","email3@$MyDomain" | |
$hostname=$Env:COMPUTERNAME | |
$smtpServer="mgate.$MyDomain" | |
$from = "$hostname <noreply@$MyDomain>" | |
$subject = "Automated script: GPO Change Audit" | |
########### END REQUIRED USER VARIABLES ############## | |
########### TESTING VARIABLES ############ | |
$testing = $true | |
if ($testing) { | |
$today = Get-Date #change this for testing some other day/time | |
$yesterday = $Today.AddDays(-8) #change this for testing some other time period | |
$subject+=" (TESTING)" | |
} | |
########## END TESTING VARIABLES ######### | |
############ sendEmail ############### | |
function sendEmail { | |
param($body) | |
if ($body) { | |
Write-host -NoNewline "Emailing $adminEmailAddr : " | |
$textEncoding = [System.Text.Encoding]::UTF8 | |
try { | |
Send-Mailmessage -smtpServer $smtpServer -from $from -to $adminEmailAddr -subject $subject -body $body -bodyashtml -priority High -Encoding $textEncoding -ErrorAction Stop | |
if (!($SendErr)) { | |
write-host "Successfully emailed $adminEmailAddr" | |
} | |
} catch { | |
write-host "FAILED to email $adminEmailAddr via $smtpServer" | |
throw $_ | |
} | |
} else { | |
Write-Host "Nothing to email." | |
} | |
} | |
########## end sendEmail ############### | |
############# MAIN ############## | |
$body = '' # init | |
$count = 0 # init | |
$summary = '' # init | |
Try { | |
Write-Host "Gathering GPO Policy Changes ...`r`n" | |
### Get all the required Security Events ### | |
$List = Get-ADObject -SearchBase "CN=Policies,CN=System,$MyDomainDN" -Filter 'WhenChanged -ge $yesterday' -Properties * -ErrorAction stop -ErrorVariable Err | |
} catch { | |
write-host -fore Red "GPO Policy Changes not found for $yesterday" | |
throw $_ | |
} finally { ### email the GPO/results | |
ForEach ($object in $List) { | |
if ($object.Displayname) { | |
$count++ | |
$changedTime = ($object.whenChanged).ToString() | |
$changedGPO = ($object.Displayname).ToString() | |
# I wish to print [$object.] AddedProperties, RemovedProperties and ModifiedProperties , but continuously fail at such. | |
foreach ($h in ($object.AddedProperties)) { | |
Write-Host "${h}: $($object.AddedProperties.$h)" | |
} | |
$summary += "GPO Changed: $changedTime $changedGPO`r`n" | |
$body += "GPO Changed: $changedTime $changedGPO<br><br>" | |
$body += '<b>Details</b>' | |
$body += ($object | convertto-html -as list) | |
$body += '<br><b>Report</b>' | |
$body += (Get-GPOReport -Name $object.DisplayName -ReportType Html) | |
} | |
$body += "<br><br>" | |
} | |
$summary = "$count GPO's changed.`r`n" + $summary | |
} | |
write-host $summary | |
if ($body) { sendEmail($body) } | |
############ END MAIN ############# |