Advertisement
Guest User

Untitled

a guest
May 22nd, 2025
14
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.43 KB | Source Code | 0 0
  1. # === Configuration ===
  2. $gpoBackupDir = "C:\GPOBackup"
  3. $todayDir = "$gpoBackupDir\today"
  4. $yesterdayDir = "$gpoBackupDir\yesterday"
  5. $archiveDir = "$gpoBackupDir\archive"
  6. $logFile = "$gpoBackupDir\gpo_diff.log"
  7.  
  8. $smtpServer = "smtp.yourdomain.com"
  9. $subject = "Daily GPO Change Report"
  10.  
  11. # === Ensure Directories Exist ===
  12. New-Item -ItemType Directory -Path $gpoBackupDir -Force | Out-Null
  13. New-Item -ItemType Directory -Path $archiveDir -Force | Out-Null
  14.  
  15. # === Function: Extract Summarized Settings ===
  16. function Get-PolicySummary {
  17. param ([string]$path)
  18.  
  19. if (-not (Test-Path $path)) {
  20. return @()
  21. }
  22.  
  23. try {
  24. [xml]$xml = Get-Content -Path $path -Raw
  25. } catch {
  26. return @()
  27. }
  28.  
  29. $xml.SelectNodes("//*[local-name()='ReadTime' or local-name()='SDDL']") | ForEach-Object {
  30. $_.ParentNode.RemoveChild($_) | Out-Null
  31. }
  32.  
  33. $policyNodes = $xml.SelectNodes("//*[local-name()='Policy']")
  34. if (-not $policyNodes) {
  35. return @()
  36. }
  37.  
  38. $summaries = @()
  39.  
  40. foreach ($policy in $policyNodes) {
  41. $nameNode = $policy.SelectSingleNode("*[local-name()='Name']")
  42. $stateNode = $policy.SelectSingleNode("*[local-name()='State']")
  43. $valueNode = $policy.SelectSingleNode("*[local-name()='Value']/*[local-name()='Name']")
  44.  
  45. $name = if ($nameNode) { $nameNode.InnerText } else { "" }
  46. $state = if ($stateNode) { $stateNode.InnerText } else { "" }
  47. $value = if ($valueNode) { $valueNode.InnerText } else { "" }
  48.  
  49. $summary = "$name|$state|$value"
  50. $summaries += $summary
  51. }
  52.  
  53. return $summaries | Sort-Object
  54. }
  55.  
  56. # === Step 1: Archive Yesterday ===
  57. if (Test-Path $yesterdayDir) {
  58. $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
  59. $archivePath = Join-Path $archiveDir $timestamp
  60. Move-Item -Path $yesterdayDir -Destination $archivePath
  61. }
  62.  
  63. # === Step 2: Copy Today to Yesterday ===
  64. if (Test-Path $todayDir) {
  65. Copy-Item -Path $todayDir -Destination $yesterdayDir -Recurse -Force
  66. Remove-Item -Path $todayDir -Recurse -Force
  67. }
  68.  
  69. # === Step 3: Export Current GPOs to Today ===
  70. New-Item -ItemType Directory -Path $todayDir -Force | Out-Null
  71. $allGPOs = Get-GPO -All
  72.  
  73. foreach ($gpo in $allGPOs) {
  74. $safeName = $gpo.DisplayName -replace '[\\/:*?"<>|]', '_'
  75. $xmlPath = Join-Path $todayDir "$safeName.xml"
  76.  
  77. Backup-GPO -Name $gpo.DisplayName -Path $todayDir -Comment "Daily GPO Backup" | Out-Null
  78. Get-GPOReport -Name $gpo.DisplayName -ReportType XML -Path $xmlPath
  79. }
  80.  
  81. # === Step 4: Compare Summarized Settings ===
  82. $differences = @()
  83. $todayFiles = Get-ChildItem $todayDir -Filter *.xml
  84.  
  85. foreach ($file in $todayFiles) {
  86. $yesterdayPath = Join-Path $yesterdayDir $file.Name
  87.  
  88. $todaySummary = Get-PolicySummary -path $file.FullName
  89. $yesterdaySummary = Get-PolicySummary -path $yesterdayPath
  90.  
  91. if ($todaySummary.Count -eq 0 -and $yesterdaySummary.Count -eq 0) {
  92. continue
  93. }
  94.  
  95. # Compare and remove "moved but unchanged" settings
  96. $diffs = Compare-Object `
  97. -ReferenceObject $yesterdaySummary `
  98. -DifferenceObject $todaySummary `
  99. -IncludeEqual:$false
  100.  
  101. $added = @{}
  102. $removed = @{}
  103.  
  104. foreach ($d in $diffs) {
  105. if ($d.SideIndicator -eq '=>') {
  106. $added[$d.InputObject] = $true
  107. } elseif ($d.SideIndicator -eq '<=') {
  108. $removed[$d.InputObject] = $true
  109. }
  110. }
  111.  
  112. $falsePositives = $added.Keys | Where-Object { $removed.ContainsKey($_) }
  113. foreach ($fp in $falsePositives) {
  114. $added.Remove($fp)
  115. $removed.Remove($fp)
  116. }
  117.  
  118. # Report final differences
  119. if ($added.Count -gt 0 -or $removed.Count -gt 0) {
  120. $differences += "Changes in GPO: $($file.BaseName)"
  121. foreach ($entry in $removed.Keys) {
  122. $details = $entry -replace '\|', ' -> '
  123. $differences += " • Removed: $details"
  124. }
  125. foreach ($entry in $added.Keys) {
  126. $details = $entry -replace '\|', ' -> '
  127. $differences += " • Added: $details"
  128. }
  129. $differences += "`n"
  130. }
  131. }
  132.  
  133. # === Step 5: Log + Email Results ===
  134. if ($differences.Count -gt 0) {
  135. $report = $differences -join "`n"
  136. $report | Out-File -FilePath $logFile -Encoding UTF8
  137. Send-MailMessage -From $from -To $to -Subject $subject -Body $report -SmtpServer $smtpServer
  138. }
  139.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement