Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # === Configuration ===
- $gpoBackupDir = "C:\GPOBackup"
- $todayDir = "$gpoBackupDir\today"
- $yesterdayDir = "$gpoBackupDir\yesterday"
- $archiveDir = "$gpoBackupDir\archive"
- $logFile = "$gpoBackupDir\gpo_diff.log"
- $smtpServer = "smtp.yourdomain.com"
- $from = "[email protected]"
- $to = "[email protected]"
- $subject = "Daily GPO Change Report"
- # === Ensure Directories Exist ===
- New-Item -ItemType Directory -Path $gpoBackupDir -Force | Out-Null
- New-Item -ItemType Directory -Path $archiveDir -Force | Out-Null
- # === Function: Extract Summarized Settings ===
- function Get-PolicySummary {
- param ([string]$path)
- if (-not (Test-Path $path)) {
- return @()
- }
- try {
- [xml]$xml = Get-Content -Path $path -Raw
- } catch {
- return @()
- }
- $xml.SelectNodes("//*[local-name()='ReadTime' or local-name()='SDDL']") | ForEach-Object {
- $_.ParentNode.RemoveChild($_) | Out-Null
- }
- $policyNodes = $xml.SelectNodes("//*[local-name()='Policy']")
- if (-not $policyNodes) {
- return @()
- }
- $summaries = @()
- foreach ($policy in $policyNodes) {
- $nameNode = $policy.SelectSingleNode("*[local-name()='Name']")
- $stateNode = $policy.SelectSingleNode("*[local-name()='State']")
- $valueNode = $policy.SelectSingleNode("*[local-name()='Value']/*[local-name()='Name']")
- $name = if ($nameNode) { $nameNode.InnerText } else { "" }
- $state = if ($stateNode) { $stateNode.InnerText } else { "" }
- $value = if ($valueNode) { $valueNode.InnerText } else { "" }
- $summary = "$name|$state|$value"
- $summaries += $summary
- }
- return $summaries | Sort-Object
- }
- # === Step 1: Archive Yesterday ===
- if (Test-Path $yesterdayDir) {
- $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
- $archivePath = Join-Path $archiveDir $timestamp
- Move-Item -Path $yesterdayDir -Destination $archivePath
- }
- # === Step 2: Copy Today to Yesterday ===
- if (Test-Path $todayDir) {
- Copy-Item -Path $todayDir -Destination $yesterdayDir -Recurse -Force
- Remove-Item -Path $todayDir -Recurse -Force
- }
- # === Step 3: Export Current GPOs to Today ===
- New-Item -ItemType Directory -Path $todayDir -Force | Out-Null
- $allGPOs = Get-GPO -All
- foreach ($gpo in $allGPOs) {
- $safeName = $gpo.DisplayName -replace '[\\/:*?"<>|]', '_'
- $xmlPath = Join-Path $todayDir "$safeName.xml"
- Backup-GPO -Name $gpo.DisplayName -Path $todayDir -Comment "Daily GPO Backup" | Out-Null
- Get-GPOReport -Name $gpo.DisplayName -ReportType XML -Path $xmlPath
- }
- # === Step 4: Compare Summarized Settings ===
- $differences = @()
- $todayFiles = Get-ChildItem $todayDir -Filter *.xml
- foreach ($file in $todayFiles) {
- $yesterdayPath = Join-Path $yesterdayDir $file.Name
- $todaySummary = Get-PolicySummary -path $file.FullName
- $yesterdaySummary = Get-PolicySummary -path $yesterdayPath
- if ($todaySummary.Count -eq 0 -and $yesterdaySummary.Count -eq 0) {
- continue
- }
- # Compare and remove "moved but unchanged" settings
- $diffs = Compare-Object `
- -ReferenceObject $yesterdaySummary `
- -DifferenceObject $todaySummary `
- -IncludeEqual:$false
- $added = @{}
- $removed = @{}
- foreach ($d in $diffs) {
- if ($d.SideIndicator -eq '=>') {
- $added[$d.InputObject] = $true
- } elseif ($d.SideIndicator -eq '<=') {
- $removed[$d.InputObject] = $true
- }
- }
- $falsePositives = $added.Keys | Where-Object { $removed.ContainsKey($_) }
- foreach ($fp in $falsePositives) {
- $added.Remove($fp)
- $removed.Remove($fp)
- }
- # Report final differences
- if ($added.Count -gt 0 -or $removed.Count -gt 0) {
- $differences += "Changes in GPO: $($file.BaseName)"
- foreach ($entry in $removed.Keys) {
- $details = $entry -replace '\|', ' -> '
- $differences += " • Removed: $details"
- }
- foreach ($entry in $added.Keys) {
- $details = $entry -replace '\|', ' -> '
- $differences += " • Added: $details"
- }
- $differences += "`n"
- }
- }
- # === Step 5: Log + Email Results ===
- if ($differences.Count -gt 0) {
- $report = $differences -join "`n"
- $report | Out-File -FilePath $logFile -Encoding UTF8
- Send-MailMessage -From $from -To $to -Subject $subject -Body $report -SmtpServer $smtpServer
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement