######################################################################### ############ 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 #############