PowerShell GPO Management with Group Policy Module

PowerShell GPO Management with Group Policy Module

PowerShell Tips Editor 3 min read
PowerShell GPO Management with Group Policy Module

Documenting Group Policy before a domain migration, auditing which GPOs are linked to sensitive OUs, or creating new policy objects for a freshly provisioned OU — all of these are tasks that take hours in the GPMC GUI and minutes with PowerShell group policy GPO management. The GroupPolicy module, installed as part of RSAT, provides full lifecycle management of Group Policy Objects: listing, reporting, creating, linking, backing up, and restoring. This post covers each operation with practical examples.

List All GPOs in Domain

Get-GPO -All returns every GPO in the domain. Import the GroupPolicy module first — it is not loaded automatically on all systems:

Import-Module GroupPolicy

Get-GPO -All | Select-Object DisplayName, Id, GpoStatus, CreationTime, ModificationTime |
    Sort-Object DisplayName | Format-Table -AutoSize
DisplayName                   Id                                   GpoStatus   CreationTime
-----------                   --                                   ---------   ------------
Default Domain Controllers Po 6ac1786c-016f-11d2-945f-00c04fb984f9 AllEnabled  1/15/2022
Default Domain Policy         31b2f340-016d-11d2-945f-00c04fb984f9 AllEnabled  1/15/2022
Workstation Security Baseline 4a7e3c1d-02aa-4f89-b12c-981234567abc AllEnabled  3/10/2024

Filter to find GPOs that have never been linked or have not been modified recently:

$staleDate = (Get-Date).AddYears(-1)
Get-GPO -All | Where-Object ModificationTime -lt $staleDate |
    Select-Object DisplayName, ModificationTime | Sort-Object ModificationTime

Get GPO Settings Report

Get-GPOReport exports the complete policy settings for a GPO to HTML or XML. The XML output is machine-parseable for automated auditing:

# HTML report for human review
Get-GPOReport -Name "Workstation Security Baseline" -ReportType HTML `
    -Path "C:\Reports\WorkstationPolicy.html"

# XML report for automated parsing
Get-GPOReport -Name "Workstation Security Baseline" -ReportType XML `
    -Path "C:\Reports\WorkstationPolicy.xml"

# Parse specific settings from XML report
[xml]$report = Get-GPOReport -Name "Default Domain Policy" -ReportType XML
$report.GPO.Computer.ExtensionData | Where-Object Name -like "*Security*"

Link a GPO to an OU

Creating a GPO and linking it to an OU are separate operations in PowerShell. Use New-GPLink to establish the link. You need the OU’s distinguished name:

$gpoName = "Workstation Security Baseline"
$ouDN    = "OU=Workstations,OU=Corporate,DC=corp,DC=local"

New-GPLink -Name $gpoName -Target $ouDN -LinkEnabled Yes -Enforced No

# Verify the link was created
Get-GPInheritance -Target $ouDN | Select-Object -ExpandProperty GpoLinks |
    Where-Object DisplayName -eq $gpoName

Create a New GPO

Use New-GPO to create a blank GPO, optionally based on the Starter GPO template. Then configure individual settings with Set-GPRegistryValue or link it to an OU with New-GPLink:

$newGPO = New-GPO -Name "Browser Lockdown - Chrome" -Comment "Restricts Chrome settings per security policy"

# Set a registry-based policy value
Set-GPRegistryValue -Name $newGPO.DisplayName `
    -Key "HKLM\Software\Policies\Google\Chrome" `
    -ValueName "DefaultBrowserSettingEnabled" `
    -Type DWord -Value 0

Write-Host "Created GPO: $($newGPO.DisplayName) with ID $($newGPO.Id)"

Back Up All GPOs

Regular GPO backups are essential before any domain changes. Backup-GPO -All exports all GPOs to a folder with individual subfolders per GPO:

$backupPath = "C:\GPOBackups\$(Get-Date -Format 'yyyyMMdd')"
New-Item -Path $backupPath -ItemType Directory -Force | Out-Null

$backupResult = Backup-GPO -All -Path $backupPath

Write-Host "Backed up $($backupResult.Count) GPOs to $backupPath"
$backupResult | Select-Object DisplayName, Id, BackupDirectory | Format-Table -AutoSize

Restore a GPO from Backup

Restore a GPO from a previous backup using its display name or GUID. The backup folder must contain the exported GPO data:

$backupRoot = "C:\GPOBackups\20260501"

# Restore by GPO name — finds the most recent backup of that name in the folder
Restore-GPO -Name "Workstation Security Baseline" -Path $backupRoot

# Restore by backup GUID (use Get-GPOBackup to find the right one)
$backupEntry = Get-GPOBackup -All -Path $backupRoot |
    Where-Object DisplayName -eq "Workstation Security Baseline" |
    Sort-Object Timestamp -Descending | Select-Object -First 1

Restore-GPO -BackupId $backupEntry.Id -Path $backupRoot
Write-Host "Restored GPO: $($backupEntry.DisplayName)"

Common Errors and Fixes

  • GroupPolicy module requires RSAT tools installed. The module ships with Remote Server Administration Tools. Install it on Windows Server with Install-WindowsFeature GPMC, or on Windows 10/11 with Add-WindowsCapability -Online -Name "Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0".
  • GPO link and GPO creation are separate operations. New-GPO creates the policy object in AD but does not apply it anywhere. You must separately call New-GPLink to attach it to an OU, site, or the domain. A GPO without any links has no effect on computers or users.

Related Cmdlets / See Also

Wrapping Up

The GroupPolicy module covers the full GPO lifecycle from creation to backup. Build regular backup jobs with Backup-GPO -All, generate HTML reports before changes, and script link creation to make new OU deployments repeatable. With GPO management in code, your Group Policy configuration becomes auditable and version-controlled.

Send-Item -To