<# .SYNOPSIS Reports on Group Policy Object status and replication. .DESCRIPTION This script checks all GPOs in the domain and reports their status, including version information, links, and replication status between AD and SYSVOL. .PARAMETER OutputPath Optional. Path to export CSV report. If not specified, outputs to console. .PARAMETER CheckReplication Switch to perform detailed replication check between AD and SYSVOL. .EXAMPLE .\Get-GPOStatus.ps1 Lists all GPOs with basic status. .EXAMPLE .\Get-GPOStatus.ps1 -CheckReplication -OutputPath "C:\ClaudeTools\Logs\gpo-status.csv" Full replication check with CSV export. .NOTES Author: ClaudeTools Automation Version: 1.0 Requires: GroupPolicy PowerShell module #> [CmdletBinding()] param( [Parameter(Mandatory=$false)] [string]$OutputPath, [Parameter(Mandatory=$false)] [switch]$CheckReplication ) # Import required modules Import-Module GroupPolicy -ErrorAction Stop Import-Module ActiveDirectory -ErrorAction Stop Write-Host "Querying Group Policy Objects..." -ForegroundColor Cyan # Get all GPOs $gpos = Get-GPO -All | Select-Object ` @{N='Name';E={$_.DisplayName}}, @{N='ID';E={$_.Id}}, @{N='Status';E={$_.GpoStatus}}, @{N='CreationTime';E={$_.CreationTime}}, @{N='ModificationTime';E={$_.ModificationTime}}, @{N='UserVersion';E={$_.User.DSVersion}}, @{N='ComputerVersion';E={$_.Computer.DSVersion}}, @{N='WMIFilter';E={$_.WmiFilter.Name}} $gpoCount = ($gpos | Measure-Object).Count Write-Host "Found $gpoCount GPOs." -ForegroundColor Green # Check GPO links Write-Host "`nChecking GPO links..." -ForegroundColor Cyan $gpoLinks = @() foreach ($gpo in (Get-GPO -All)) { $report = [xml](Get-GPOReport -Guid $gpo.Id -ReportType Xml) $links = $report.GPO.LinksTo.SOMPath $gpoLinks += [PSCustomObject]@{ Name = $gpo.DisplayName LinkCount = if ($links) { ($links | Measure-Object).Count } else { 0 } Links = if ($links) { $links -join "; " } else { "Not Linked" } } } if ($CheckReplication) { Write-Host "`nChecking SYSVOL replication status..." -ForegroundColor Cyan $domain = (Get-ADDomain).DNSRoot $dcs = Get-ADDomainController -Filter * foreach ($dc in $dcs) { Write-Host " Checking $($dc.HostName)..." -ForegroundColor Gray $sysvolPath = "\\$($dc.HostName)\SYSVOL\$domain\Policies" if (Test-Path $sysvolPath) { $sysvolGPOs = Get-ChildItem $sysvolPath -Directory | Where-Object { $_.Name -match '^{' } Write-Host " SYSVOL GPO count: $($sysvolGPOs.Count)" -ForegroundColor Green } else { Write-Host " Unable to access SYSVOL" -ForegroundColor Red } } } # Output results if ($OutputPath) { $gpos | Export-Csv -Path $OutputPath -NoTypeInformation Write-Host "`nReport exported to: $OutputPath" -ForegroundColor Green } else { Write-Host "`n--- GPO List ---" -ForegroundColor Yellow $gpos | Format-Table Name, Status, ModificationTime, UserVersion, ComputerVersion -AutoSize Write-Host "`n--- GPO Links ---" -ForegroundColor Yellow $gpoLinks | Format-Table Name, LinkCount, Links -AutoSize } # Summary Write-Host "`n--- Summary ---" -ForegroundColor Yellow Write-Host "Total GPOs: $gpoCount" $unlinked = ($gpoLinks | Where-Object { $_.LinkCount -eq 0 } | Measure-Object).Count Write-Host "Unlinked GPOs: $unlinked" -ForegroundColor $(if ($unlinked -gt 0) { 'Yellow' } else { 'Green' }) $disabled = ($gpos | Where-Object { $_.Status -ne 'AllSettingsEnabled' } | Measure-Object).Count Write-Host "Disabled/Partial GPOs: $disabled" -ForegroundColor $(if ($disabled -gt 0) { 'Yellow' } else { 'Green' })