- Backup the group policies, on-site and off.
- Give me a report on which policies do what.
- Point out that a group policy has changed, is new, or has been deleted.
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