Find orphaned GPOs via PowerShell before migrating to Intune

The estimated reading time 2 minutes

Many companies have already fully transitioned to Endpoint Management Intune and no longer need GPOs (Group Policy Objects). Others are in the preparatory stages. Therefore, I would like to provide some assistance for identifying orphaned Group Policy Objects. These can be relatively easily found and, if necessary, removed using PowerShell.

I’ve written a small script that exports all GPOs that are not linked to any OU (Organizational Unit) or Site to a CSV file. Typically, such GPOs are not applied. Especially in larger environments with many GPOs, it’s easy to lose track, and this script helps to at least remove old objects without a significant impact.

You only need PowerShell with the “GroupPolicy” module for this. For more details, refer to the official link:
https://learn.microsoft.com/en-us/powershell/module/grouppolicy/?view=windowsserver2022-ps

If the mentioned PowerShell Module is not available you may need to install it within the ServerManager.

The script itself only needs to specify a path where the generated CSV File is exported.

Import-Module GroupPolicy -Verbose
$csvpath = "C:\temp\2024-07-04-GPOs-notlinked.csv"
$gpos = (get-gpo -All | Sort-Object displayName)
"Name;ID;Created;LastModified;GpoStatus" | Out-File -FilePath $csvpath -Encoding utf8 -Force
foreach($gpo in $gpos){
$gpoid = ($gpo).id
$gpodisplayname = ($gpo).Displayname
$gpocreat = ($gpo).CreationTime
$gpomod = ($gpo).ModificationTime
$gpostatus = ($gpo).GpoStatus
$report = Get-GPOReport -Guid $gpoid -ReportType Xml
if ($report | Select-String -notmatch "<LinksTo>"){
            Write-Host "$gpodisplayname not linked"
            "$gpodisplayname;$gpoid;$gpocreat;$gpomod;$gpostatus" | Out-File -FilePath $csvpath -Encoding utf8 -Append
        }
}

CSV export should look like this one:

The CSV file can also be used to delete the GPOs from Active Directory. I’ve created a small script for this purpose. You just need to insert the FQDN of your domain in the second-to-last line. Once you are sure, remove the -WhatIf parameter to actually delete the GPOs.

$impgpos = Import-Csv -Delimiter ";" -Path $csvpath -Encoding UTF8
foreach($impgpo in $impgpos){
    $impgponame = ($impgpo).Name
    $impgpoid = ($impgpo).id
    Write-Host "Removing GPO: $impgponame" -ForegroundColor Yellow
    Remove-GPO -Guid $impgpoid -Domain XXXXX.local -Confirm:$false -WhatIf
}

Good luck with finding orphaned entries and objects. If you liked this article, please click “Helpful.” Otherwise, feel free to leave a comment.

Was this article helpful?
YesNo
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments