If you have been working in a Windows domain for any length of time, you have inherited a GPO estate that nobody has a clean list of. Open GPMC and you get an alphabetical tree — fine for browsing, useless for auditing. This script fixes that. You type a keyword, it pulls every GPO with that word in its name and dumps the results to a CSV with the metadata you actually care about.
It is the kind of script that gets used far more than you expect. Migration planning, compliance reviews, tracking down which team owns a specific policy area, identifying stale GPOs that have not been touched in years — all of it starts with a clean filtered list.
Why this is more useful than browsing GPMC
- Keyword search across your entire estate — type “Firewall” and get every GPO with that word in its name, regardless of which OU it is linked to. No scrolling, no manual hunting through nested folders in the console.
- Owner and timestamp data in one export — the output CSV includes the GPO owner, when it was created, and when it was last modified. That last-modified date is often the most useful column — GPOs that have not changed in three years are candidates for review or retirement.
- GPO status at a glance — each row shows whether the GPO is fully enabled, disabled, or has only the user or computer half enabled. Partially disabled GPOs are common artefacts of old configurations that nobody cleaned up.
- Schedulable for regular audits — because the script accepts a keyword at runtime, you can wrap it in a scheduled task to automatically export categories of GPOs on a recurring basis — useful for change tracking between snapshots.
- Intune migration planning — when moving settings from GPO to Intune configuration profiles, the first step is knowing what you have. Filter by policy area (Outlook, Edge, Defender, Firewall) and you immediately have a scoped list to work from.
What you need before running it
Get-GPO, which requires the Group Policy Management feature to be installed. On a domain controller this is already present. On a workstation or member server, install it via RSAT: Add-WindowsCapability -Online -Name Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0| # | Requirement | Detail |
|---|---|---|
| 1 | GroupPolicy PowerShell module | Run from a machine joined to the domain. A domain controller works; so does any machine with RSAT Group Policy tools installed. |
| 2 | Read access to Group Policy objects | Domain Admins have this by default. If you are not a Domain Admin, confirm with your AD team that your account has GPO read permissions. |
| 3 | No additional modules required | Get-GPO is part of the built-in GroupPolicy module — no installation step needed beyond RSAT. |
The script
Run it interactively and it prompts you for a keyword. Everything else is automatic — it queries all GPOs, filters by name, builds a clean object for each match, and exports to a CSV named after your keyword in the current directory.
View on GitHub — Imran76Awan/Daily-Tasks# Requires: GroupPolicy module (RSAT Group Policy Management Tools)
# Run on a domain-joined machine with GPO read access
# Prompt for a keyword — matches any GPO whose DisplayName contains this string
$keyword = Read-Host "Enter keyword for GPO name filter"
# Retrieve all GPOs in the domain
$gpos = Get-GPO -All
# Filter to GPOs whose DisplayName contains the keyword (case-insensitive)
$filteredGpos = $gpos | Where-Object { $_.DisplayName -like "*$keyword*" }
# Build a clean output object for each matching GPO
$output = foreach ($gpo in $filteredGpos) {
[PSCustomObject]@{
DisplayName = $gpo.DisplayName
Owner = $gpo.Owner
CreationTime = $gpo.CreationTime
ModificationTime = $gpo.ModificationTime
GPOStatus = $gpo.GPOStatus
}
}
# Export to CSV — file is named after the keyword you entered
$output | Export-Csv "GPO_list_$keyword.csv" -NoTypeInformation
Write-Host "Done. Exported $($output.Count) GPO(s) to GPO_list_$keyword.csv" -ForegroundColor Green
What the output looks like
If you enter Firewall as the keyword, the script queries every GPO in the domain, keeps only those whose name contains “Firewall”, and writes a file called GPO_list_Firewall.csv. Here is what a typical export looks like opened in Excel:
| DisplayName | Owner | CreationTime | ModificationTime | GPOStatus |
|---|---|---|---|---|
| Firewall - Workstations | DOMAIN\admin | 2019-03-12 09:41 | 2026-05-20 14:07 | AllSettingsEnabled |
| Firewall - Servers (Legacy) | DOMAIN\svc-gpo | 2017-08-03 11:22 | 2021-01-14 09:00 | UserSettingsDisabled |
| Windows Firewall - Block Inbound | DOMAIN\admin | 2022-11-07 16:55 | 2022-11-07 16:55 | AllSettingsEnabled |
The ModificationTime column is where the real insight lives. A GPO that was last modified in 2021 and has never been touched since is worth reviewing — either it is still needed and should be documented, or it is a candidate for cleanup.
Column reference
| Column | What it tells you |
|---|---|
| DisplayName | The GPO name as it appears in GPMC |
| Owner | The AD account or group that owns the GPO. Useful for identifying orphaned or service-account-owned policies |
| CreationTime | When the GPO was first created in the domain |
| ModificationTime | When the GPO was last edited. This is your primary indicator of staleness |
| GPOStatus | AllSettingsEnabled, UserSettingsDisabled, ComputerSettingsDisabled, or AllSettingsDisabled |
Practical keywords to try
The script is most useful when you know the naming convention your organisation uses. Common patterns that return immediately useful results:
-
OutlookAll email client configuration policies — useful when planning Exchange Online migrations -
FirewallWindows Firewall policies across all device categories -
DefenderAntivirus and Defender settings — compare against what you have in Intune -
BitLockerEncryption policies — check whether drive encryption is still GPO-driven or already moved to Intune -
EdgeBrowser configuration policies — useful when assessing what needs to move to Intune Settings Catalog -
LegacyIf your team labels old GPOs with “Legacy”, this finds them all instantly for retirement review
How to schedule it for regular exports
If you want a weekly snapshot of a particular GPO category without running the script manually, you can schedule it via Task Scheduler with a hardcoded keyword. To do that, convert the interactive prompt to a parameter so the script can run unattended:
param([string]$Keyword = "Firewall")
$gpos = Get-GPO -All
$filteredGpos = $gpos | Where-Object { $_.DisplayName -like "*$Keyword*" }
$output = foreach ($gpo in $filteredGpos) {
[PSCustomObject]@{
DisplayName = $gpo.DisplayName
Owner = $gpo.Owner
CreationTime = $gpo.CreationTime
ModificationTime = $gpo.ModificationTime
GPOStatus = $gpo.GPOStatus
}
}
$timestamp = Get-Date -Format 'yyyy-MM-dd'
$output | Export-Csv "C:\GPO_Reports\GPO_$Keyword_$timestamp.csv" -NoTypeInformation
Then in Task Scheduler, set the action to:
Run it weekly on a domain controller and you get a dated CSV snapshot every time it fires. Compare snapshots side by side to track which GPOs were modified, created, or had their status changed between runs.
UserSettingsDisabled status or a ModificationTime older than two years — those are your lowest-risk decommission candidates.Get-GPO cmdlet is not available on workstations unless Group Policy Management Tools (part of RSAT) have been explicitly installed. Running on a DC is the simplest option for a one-off audit.