Export Group Policy Links with PowerShell

Hi All,
I’ve come across a Domain, where there are a ton of Group Policies. So i was looking for a way to figure out if the Group Policy is still used. One way to figure out is to check if the Group Policy is linked to an Active Directory OU or Site. There might be still some Group Policys that are not Linked that might be used from time to Time to Test things or used for diffrent Szenarios. But even identifying such not “actively” used Group Policys could help to decrease the amount of Group Policies in that Domain.
- Windows 11 22H2 Install Remote Server Administration Tool (RSAT) Feature
- Windows 10 20H2 Install Remote Server Administration Tool (RSAT) Feature
PowerShell
As a PowerShell and Scripting Guy i had a look into the GroupPolicy PowerShell Module that comes with the Remote Server Administation Tools (RSAT)
Get-Command -Module GroupPolicy
Let’s get the GPO
$GPO = Get-GPO -Name <GPOName>
$GPO
And use the GPO Object and pipe it to Get-GPOReport commandlet. Now you can find if and where it’s linked.
[xml]$Report = $GPO | Get-GPOReport -ReportType XML
$Report.GPO.LinksTo
Script
I’ve created a Script where you can export a Single or all GPO with the Links.
If a GPO has multiple Links it will create a Line for each Link.
The Script contains a nice Synopsis that creates the Help.
Get-Command .\Export-GPLinks.ps1 -Full
###############################################################################
# Export-GPLinks.ps1
# Version: 1.0
# Date: 2025-05-15
# Author: Andres Bohren
# Description: This script will export all GPO links to a CSV file.
# Some Source code from here https://www.easy365manager.com/get-gpo-links-with-powershell/
###############################################################################
<#
.SYNOPSIS
This script will export all GPO links to a CSV file.
.DESCRIPTION
This script will export all GPO links to a CSV file.
.PARAMETER GPOName
[string]GPOName specifies the name of the GPO to export. If not provided, all GPOs will be exported.
.LINK
https://github.com/BohrenAn/GitHub_PowerShellScripts/tree/main/ActiveDirectory/Export-GPLinks.ps1
.EXAMPLE
.\Export-GPLinks.ps1 -GPOName <GPOName>
This will export the GPO links for the specified GPO to a CSV file.
.\Export-GPLinks.ps1
This will export all GPO links to a CSV file.
#>
#Parameter
[CmdletBinding()]
Param (
[parameter(mandatory = $false)][string]$GPOName
)
#Check if the Parameter GPOName is provided
If ($GPOName -ne "")
{
[Array]$GPOs = Get-GPO -Name $GPOName
If ($null -eq $GPO)
{
Write-Host "GPO not found: $GPOName" -ForegroundColor Red
Exit
}
} else {
Write-Host "No GPO name provided, exporting all GPOs." -ForegroundColor Yellow
#Get all GPOs
[Array]$GPOs = Get-GPO -All
}
#Loop through the GPOs and create the CSV Export
#Create the CSV file
$OutputFile = ".\GPLinks.csv"
"Name;LinkPath;ComputerEnabled;UserEnabled;WmiFilter" | Out-File $OutputFile
$TotalGPO = $GPOs.Count
$INT = 0
#Loop through the GPOs
Foreach ($GPO in $GPOs)
{
$Int = $INT + 1
$GPODisplayName = $GPO.DisplayName
Write-Host "Working on: $GPODisplayName [$INT/$TotalGPO]" -ForegroundColor Green
[xml]$Report = $GPO | Get-GPOReport -ReportType XML
$Links = $Report.GPO.LinksTo
If ($Null -ne $Links)
{
ForEach($Link In $Links)
{
#A Line for each Link
$Output = $Report.GPO.Name + ";" + $Link.SOMPath + ";" + $Report.GPO.Computer.Enabled + ";" + $Report.GPO.User.Enabled + ";" + $_.WmiFilter.Name
$Output | Out-File $OutputFile -Append
}
} else {
#No Links
$Output = $Report.GPO.Name + ";;" + $Report.GPO.Computer.Enabled + ";" + $Report.GPO.User.Enabled + ";" + $_.WmiFilter.Name
$Output | Out-File $OutputFile -Append
}
}
Examples
Export all GPOLinks
#Export all GPO Links
.\Export-GPLinks.ps1
Here’s how the Export looks like
#Export a specific GPO with the Links
.\Export-GPLinks.ps1
Here’s how the Export looks like
Summary
In my case i had about 700 GPO’s and it turned out that over 250 are not linked and therefore could be deleted. Hope this helps.
Regards
Andres Bohren