Search Domain GPOs for Any Text String with PowerShell
Search every Group Policy Object in an Active Directory domain for a setting name, registry path, or other text string with PowerShell, and optionally export all GPO XML reports for offline review.
Overview
When troubleshooting domain policy behavior, one of the most frustrating steps is figuring out which Group Policy Object (GPO) contains a specific setting, registry reference, or text string.
In domains with dozens or hundreds of GPOs, checking each policy manually in Group Policy Management Console (gpmc.msc) is slow. This post includes two PowerShell scripts to speed that up:
Search-Domain-GPOs.ps1exports each GPO to XML, searches the report for your target text, and prints matching GPOs.Export-Domain-GPO-Xml.ps1exports every GPO in the domain to XML files so you can review them offline.
Requirements
- PowerShell on a domain-joined system
- The
GroupPolicyPowerShell module - Permission to read GPOs in the domain
- RSAT, a domain controller, or another administrative workstation with Group Policy tools installed
Key Capabilities
- Searches every GPO in the current domain for a setting name, keyword, or registry reference
- Lets you match either friendly policy text or registry path/value combinations
- Exports every GPO to XML for offline review or archival
- Sanitizes GPO display names when writing XML files to disk
- Helps you identify candidate GPOs before doing deeper precedence analysis
Download
This script generates a temporary XML report for each GPO, searches the report for your target text, and prints the GPOs that contain a match.
File: Search-Domain-GPOs.ps1
This companion script exports every GPO in the current domain to XML files under C:\Temp\GPO_XML_Exports.
File: Export-Domain-GPO-Xml.ps1
The Scripts
Search Domain GPOs For Text
# Import the Group Policy module (usually loads automatically, but good practice)
Import-Module GroupPolicy
# Get all GPOs in the current domain
$allGPOs = Get-GPO -All
# Define a text target to search for (example: Remote Desktop policy name)
$settingName = "Allow users to connect remotely by using Remote Desktop Services"
# Optional secondary target (example: related registry path/value)
$registryKeyPath = "Software\Policies\Microsoft\Windows NT\Terminal Services"
$registryValueName = "fDenyTSConnections"
Write-Host "Searching all GPOs for text target(s)..."
# Loop through each GPO
foreach ($gpo in $allGPOs) {
try {
# Generate the GPO report as XML
$reportPath = "$env:TEMP\$($gpo.Id).xml"
Get-GPOReport -Guid $gpo.Id -ReportType Xml -Path $reportPath -ErrorAction Stop
# Read the XML report content
$reportContent = Get-Content -Path $reportPath -Raw
# Check whether the report contains either example target
if (($reportContent -match [regex]::Escape($settingName)) -or
($reportContent -match [regex]::Escape($registryKeyPath) -and
$reportContent -match [regex]::Escape($registryValueName))) {
Write-Host "Found in GPO: $($gpo.DisplayName) (ID: $($gpo.Id))"
}
# Clean up the temporary report file
Remove-Item -Path $reportPath -Force
}
catch {
Write-Warning "Could not process GPO: $($gpo.DisplayName) (ID: $($gpo.Id)). Error: $($_.Exception.Message)"
}
}
Write-Host "Search complete."
Export All Domain GPOs To XML
Import-Module GroupPolicy
# Output folder for all XML reports
$ExportPath = "C:\Temp\GPO_XML_Exports"
# Create folder if it does not exist
if (-not (Test-Path -Path $ExportPath)) {
New-Item -Path $ExportPath -ItemType Directory -Force | Out-Null
}
# Get all GPOs in the current domain
$AllGPOs = Get-GPO -All
Write-Host "Exporting $($AllGPOs.Count) GPO(s) to XML..." -ForegroundColor Cyan
foreach ($GPO in $AllGPOs) {
try {
# Sanitize display name for filename safety
$SafeName = $GPO.DisplayName -replace '[\\/:*?"<>|]', '_'
# Build output file path
$ReportPath = Join-Path $ExportPath "$SafeName - $($GPO.Id).xml"
# Export GPO report as XML
Get-GPOReport -Guid $GPO.Id -ReportType Xml -Path $ReportPath -ErrorAction Stop
Write-Host "Exported: $($GPO.DisplayName)" -ForegroundColor Green
}
catch {
Write-Warning "Failed to export GPO: $($GPO.DisplayName) (ID: $($GPO.Id)) - $($_.Exception.Message)"
}
}
Write-Host "Done. XML reports saved to: $ExportPath" -ForegroundColor Cyan
How to Use
Search For A Setting Or String
- Download
Search-Domain-GPOs.ps1to a domain-joined administrative workstation. - Edit
$settingNameto the policy text you want to find. - Optionally set
$registryKeyPathand$registryValueNameif you want to search for a related registry-backed policy. - Run the script:
.\Search-Domain-GPOs.ps1
- Review the matching GPO names, then open
gpmc.mscto inspect the policy configuration and link scope.
Export Every GPO To XML
- Download
Export-Domain-GPO-Xml.ps1. - Change
$ExportPathif you want the XML files written somewhere other thanC:\Temp\GPO_XML_Exports. - Run the script:
.\Export-Domain-GPO-Xml.ps1
- Open the exported XML files to review settings offline or search them with your own tooling.
Example Output
Search Script
Searching all GPOs for text target(s)...
Found in GPO: Default Domain Policy (ID: 31b2f340-016d-11d2-945f-00c04fb984f9)
Found in GPO: Workstation RDP Policy (ID: 8c1a5c4e-6a2e-4c8c-9d9a-7e7eaa2c8f51)
Search complete.
Export Script
Exporting 42 GPO(s) to XML...
Exported: Default Domain Policy
Exported: Workstation RDP Policy
Done. XML reports saved to: C:\Temp\GPO_XML_Exports
Notes
- The search script performs text matching against GPO XML reports instead of parsing the XML structure directly.
- A match tells you which GPO contains the text, but it does not tell you which policy wins after Group Policy precedence is evaluated.
- To confirm effective policy on a specific machine, run
gpresult /ror openrsop.msc. - In large environments, both scripts can take several minutes because they generate a report for every GPO.