Are your GPOs applying? Use this PowerShell script to find out

Group Policy Objects must be applied to correct objects in order to apply policy settings configured in the GPOs. For example, if you intended to apply settings from a GPO to finance team and if you forgot to add finance users or security groups to the permissions tab of the GPO, then the GPO settings will not apply. If you have hundreds of Group Policy Objects configured in your environment it will take a considerable amount of time to check all GPOs one by one to ensure they apply to the required objects. We can check GPO permissions by using PowerShell. Though the script provided in this article does not check to ensure the GPOs apply to the correct objects, the script checks to ensure that the GPO is at least applying to objects. The object can be a user, computer object, or a security group.

Checking GPOs

PowerShell comes in very handy when it comes to checking GPO permissions for all Group Policy Objects in a specified Active Directory domain. The PowerShell script provided in this article performs the following operations:

  • Collects all Group Policy Objects from an Active Directory domain specified in the “$ThisDomain” variable. You must be changing the domain name before executing the script.
  • Collects security objects for each GPO and checks to see how many objects have been configured. If the value returned is 0 that means the GPO is not applying and that GPO is reported in the report file.
  • The report file by name C:\Temp\GPOApplicationReport.CSV is created that contains the name of the GPO, GPO status, and the domain name of the GPO.

PowerShell script

Executing this PowerShell script will generate a report in CSV format. The script requires that the Group Policy PowerShell modules are installed on a Windows Server 2012 or later operating system.

$ReportFile = "C:\Temp\GPOApplicationReport.CSV"
$STR = "GPO Name, GPO Status, Domain"
Add-Content $ReportFile $STR
$ThisDomain = ""
$TotNotAppliedGPO=Get-GPO -All -Domain $ThisDomain -Server $PDCServerToConnect | %{
$gpoName = $_.displayName
$GPOStatusNow = $_.GPOStatus
[int]$counter = 0
$security = $_.GetSecurityInfo()
$security | where{ $_.Permission -eq "GpoApply" } | %{
$counter += 1
if ($counter -eq 0)
Add-Content $ReportFile $FinalVal
IF ($TotNo -eq 0)
$TestText = "All GPOs have been configured to apply to required objects."
$TestText = "Some GPOs are NOT applying to any objects. Please check why these GPOs are not applying to any objects. These GPOs might have some policy settings that you are expecting to apply to users and computers."

Once the PowerShell script has finished executing you can see a report under “C:\Temp\GPOApplicationReport.CSV,” which contains the name of the Group Policy Object, message and the domain to which GPO belongs to. This is also shown in the screenshot below:

As you can see in the above output, the script reported four Group Policy Objects that are not applying to any objects. Any GPO that does not apply to any objects does not have any function in the domain. The script also reports the GPO status. If a GPO is enabled and if it is not applying then you must check the GPO as to know why an enabled GPO is not applying to objects. The script reported that TestGPO1 and TestGPO4 are enabled but they are not applying to any objects.

The above script was retrieved from “Domain GPO Not Applied Test” Dynamic Pack from Active Directory Health Profiler. Active Directory Health Profiler is capable of reporting the Group Policy Objects that are not applying to any objects and can also be used to perform several other Active Directory health checks. All you need to do is just select the “Domain GPO Not Applied Test” Dynamic Pack from the Dynamic Packs Window and then execute it to get the GPO data as shown in the screenshot below:

Final thought

You can use the PowerShell script to check all GPOs against any domain. But don’t forget: You need to change the domain name in $ThisDomain variable.

Featured image: Shutterstock

Nirmal Sharma

Nirmal Sharma is a MCSEx3, MCITP and was awarded the Microsoft MVP award in Directory Services and Windows Networking. He specializes in Microsoft Azure, Office 365, Directory Services, Failover Clusters, Hyper-V, PowerShell Scripting and System Center products. Nirmal has been involved with Microsoft Technologies since 1994. In his spare time, he likes to help others and share some of his knowledge by writing tips and articles on various sites.

Published by
Nirmal Sharma
Tags Powershell

Recent Posts

How to manage and automate Azure DevOps using Azure CLI

Azure DevOps is fast becoming the next big thing. This Azure DevOps Quick Tip shows…

2 days ago

Trench Tales: When you really need to retire that messaging platform

That old messaging platform has served you well, but maybe it’s time to move on.…

2 days ago

Customize PowerShell with default parameters and save time

Microsoft makes it easy to set up default parameters for PowerShell. And while they may…

2 days ago

Secret Manager security service now available for Google Cloud

Secret Manager, new from Google Cloud, is out in in beta. It provides a secure…

3 days ago

Postman API platform surpasses 10 million registered users

API development platform Postman said it has surpassed 10 million active users, a clear signal…

3 days ago

SOS for SSDs: How to avoid solid-state drives firmware failure

Solid-state drives are great. They're terrific. They're blazing fast. Except when all SSDs suddenly fail…

3 days ago