Click an Ad

If you find this blog helpful, please support me by clicking an ad!

Monday, February 24, 2014

Backing Up GPOs, and Alerting for Changes

So the problems this script addresses are:
  1. Backup the group policies, on-site and off.
  2. Give me a report on which policies do what.
  3. Point out that a group policy has changed, is new, or has been deleted.
I should point out that I am using Windows Server 2008 R2, and Powershell v3 is installed on the computer that runs this script on a daily basis.

You can read about the Powershell grouppolicy module's commands at Technet.

Some prep:
  • Test that you can have the group policy module, which is new in Powershell v3. To do this, in Powershell type import-module grouppolicy.
  • Wherever you put this, make sure you have a "C:\GPOReporting\Backup" folder structure
  • The folder also uses the temp folder location to store xml output of the GPOs for comparisons. 
  • You should modify the section under "#Mirror GPO Backups to DR using robocopy" to point to your off-site DR location - also make sure the folder structure is there.

Here is the script. I went through and commented it to explain what it's doing:

#Get Date for today and yesterday
$DateToday = (get-date -Format Mdy).ToString()
$DateYesterday = (get-date).AddDays(-1)
$ReportDate = (Get-date -Format Mdy).ToString()
$OldReportDate = (Get-Date ((Get-date).AddDays(-1)) -Format Mdy).ToString()
$OldestReportDate = (Get-Date ((Get-date).AddDays(-2)) -Format Mdy).ToString()
$ChangesToGPODivider = "`r`n=================================================================`r`n"
$ChangesToGPOCounter = 0

#Import the Group Policy module for Powershell
Import-Module GroupPolicy

#Specify output Files and Paths for later use
$GPOReport = "c:\temp\GPOReport.html"
$CoreBackupLocation = "C:\GPOReporting\Backup"
$BackupLocation = "C:\GPOReporting\Backup\$DateToday"
$GPOOffsiteBackupLog = "C:\Temp\GPO_FPDR_BackupCopy.log"
$BackupReport = "C:\Temp\BackupReport_$DateToday.txt"

#Get the GPO Report
get-gporeport -all -ReportType HTML -path $GPOReport

#Get a list of all GPOs
$GPOList = get-gpo -all | select displayname | %{$_.Displayname}

#Make the new folder for backups based on the date
new-item -Path $BackupLocation -ItemType directory | out-null

#Back up the GPOs, redirecting output to the Backup Report
Foreach ($GPO in $GPOList){
Backup-GPO -Name $GPO -Path $BackupLocation >> $BackupReport
} #End Foreach

#Get Rid of GPO backups over 7 days old
$Folders = (Get-childitem $CoreBackupLocation | where {$_.PSIsContainer})
Foreach ($Folder in $Folders){
$FolderAge = (((Get-Date) - $Folder.creationtime).totalhours)
If ($FolderAge -gt 168)
{remove-item $Folder.FullName -recurse -Force}
} #End Foreach

#Mirror GPO Backups to DR using robocopy
start-process "c:\robocopy.exe" -ArgumentList 'C:\GPOReporting\Backup \\BackupServer\c$\GPOBackups /MIR /R:10 /W:5 /NP /LOG:C:\Temp\GPO_FPDR_BackupCopy.log /NS /NC /NFL /NDL' -wait

#This section Generates the Reports
Foreach ($GPO in $GPOList){
$PathToReport = "C:\Temp\" + "$GPO" + "_" + "$ReportDate" + ".xml"
Get-GPOReport -Name $GPO -ReportType XML -path $PathToReport
} #End Foreach

#This section creates variables for testing for created and deleted GPOs
$ReplacementString = "_$OldReportDate.xml"
$YesterdaysFiles = get-childitem c:\temp -Filter *$oldreportdate.xml | %{(($_.Name).replace("$ReplacementString",""))}
$SubjectAdditionCreated = ""
$SubjectAdditionDeleted = ""

#This section is for testing for created and deleted GPOs.
$GPODiff = compare-object -referenceObject $YesterdaysFiles -DifferenceObject $GPOList
$GPODiff | %{
If($_.SideIndicator -like "=>"){ #New GPO
$NewGPO = $_
$NewGPOLabel = ($NewGPO.InputObject)
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPO += "NEW GPO: $NewGPOLabel`r`n"
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPOCounter++
$SubjectAdditionCreated += " - New GPO Detected: $NewGPOLabel"
} #End if
ElseIf($_.SideIndicator -like "<="){ #Deleted GPO
$DeletedGPO = $_
$DeletedGPOLabel = ($DeletedGPO.InputObject)
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPO += "DELETED GPO: $DeletedGPOLabel`r`n"
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPOCounter++
$SubjectAdditionDeleted += " - GPO Deleted: $DeletedGPOLabel"
} #End If
Else{Break}
} #End Foreach

#This Section is for comparing GPO Settings. It takes the GPOReport XML file that was created yesterday and compares it to the GPOReport output we just created.
Foreach ($GPO in $GPOList){
$PathToReport = "C:\Temp\" + "$GPO" + "_" + "$ReportDate" + ".xml"
$PathToReportYesterday = "C:\Temp\" + "$GPO" + "_" + "$OldReportDate" + ".xml"
$PathToReportOldest = "C:\Temp\" + "$GPO" + "_" + "$OldestReportDate" + ".xml"
$Comparison = $null
#GPO Comparison Changes
$Comparison = (Compare-Object -ReferenceObject (Get-Content $PathToReportYesterday) -DifferenceObject (Get-Content $PathToReport) -CaseSensitive) | where {$_.InputObject -notlike "*<ReadTime>*"} | fl
If ($Comparison -eq $null){
$ChangesToGPO += "NO GPO CHANGES to $GPO`r`n"
} #End If
Else{
$ComparisonString = $Comparison | out-string
$ChangesToGPOCounter++
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPO += "$GPO HAS CHANGED: "
$ChangesToGPO += $ChangesToGPODivider
$ChangesToGPO += $ComparisonString
$ChangesToGPO += $ChangesToGPODivider
} #End Else
#Delete the Oldest Report, which we no longer need
Remove-Item $PathToReportOldest -EA Silent
} #End Foreach
#For Testing: $ChangesToGPO = $null

#List Any Unlinked GPOs
$UnlinkedGPOs = Get-GPO -All | %{If ($_ | Get-GPOReport -ReportType XML | Select-String -NotMatch "<LinksTo>"){Write-Output $_.DisplayName;Write-Output "<BR>"}}


#E-mail Configuration
$SMTPServer = "mailserver.contoso.com"
$From = "helpdesk@contoso.com"
$Subject = "PS Report - GPO: Backup/Change Report - $ChangesToGPOCounter Changes Detected $SubjectAdditionCreated $SubjectAdditionDeleted"

$Body = $ChangesToGPO
$Body += "`r`n`r`n"
$Body += $ChangesToGPODivider
$Body += "UNLINKED GPOs: `r`n"
$Body += $UnlinkedGPOs
$Body = ($Body.replace("`r`n","<BR>"))

Send-MailMessage -from $From -to reporting@contoso.com -subject $Subject -smtpserver $SMTPServer -body $Body -BodyAsHTML -Attachments $GPOReport,$GPOOffsiteBackupLog,$BackupReport

#Delete Unneeded Output Files
remove-item $GPOReport
remove-item $BackupReport
remove-item $GPOOffsiteBackupLog

No comments:

Post a Comment