In this article I want to look at ways you can manage Group Policy with PowerShell and the Group Policy Module and CIM/WMI.
Latest posts by Graham Beer (see all)

Group Policy is a Windows feature for controlling user and computer accounts which relies on Active Directory. GUI tools are available to do various aspects of Group Policy, but when it comes to automating and dealing with several computers or users then you need a better solution. In the past and still today, the executables of gpupdate.exe and gpresult.exe are heavily used. But with PowerShell comes Group Policy cmdlets!

If you are working on Windows Server 2012 or later, you can install the Group Policy Management Console via PowerShell by:

Install-WindowsFeature –Name GPMC

To be able to use the Group Policy module on a Windows client you will need Remote Server Administration Tools (RSAT) installed. Alternatively, you can use areas of CIM/WMI to retrieve computer specific Group Policy information, which I will come on to later.

Common PowerShell Group Policy cmdlets

Once you have installed the Group Policy module you will find there are many cmdlets to work with. Using Get-Command shows 26 cmdlets available to use:

Get-Command -Module GroupPolicy

I won’t go through all of these, but a few you might commonly use in place of the older executable solutions.


The Invoke-GPUpdate cmdlet is the same as using the gpupdate.exe. Instead of doing gpupdate /force you can use the Invoke-GPUpdate cmdlet to schedule a Group Policy refresh. The computer parameter allows you to schedule a Group Policy update on a remote machine:

Invoke-GPUpdate -Computer "DOMAIN\COMP01"

Depending if you are looking to refresh just a computer or user policy, the target parameter will allow you to choose:

Invoke-GPUpdate -Computer "DOMAIN\COMP01" -Target User

A handy parameter called RandomDelayInMinutes allows the option to specify a time window with a random factor added to lower the network load. Using the integer of 0 will set the Group Policy to update as soon as possible.

"COMP01","COMP02","COMP03" |
    Foreach-Object { Invoke-GPUpdate -Computer $_ -RandomDelayInMinutes 20 }

Parameters boot and logoff will before the action of either rebooting or logging off when the update has finished applying:

Invoke-GPUpdate -Computer "DOMAIN\COMP01" -Boot
Invoke-GPUpdate -Computer "DOMAIN\COMP01" -Logoff


Using the Get-GPOReport cmdlet adds extra flexibility over the executable, GPResult.exe. Using this cmdlet, you can generate a report in XML or HTML for a certain Group Policy or all in a domain. The information generated in the report has details on properties and policy settings.

Get-GPOReport allows you to pass a name or guild when generating a report or an individual Group Policy.

Get-GPOReport -Name "TimeZone" -ReportType HTML -Path "C:\tmp\GPOtimezoneReport.html"

Should you want to run a report on all Group Polices in the domain, use the All switch:

Get-GPOReport -All -ReportType HTML -Path "C:\tmp\AllGPOs.html"

The ReportType parameter allows you to switch to XML if required:

 Get-GPOReport -Name "TimeZone" -ReportType XML -Path "C:\tmp\GPOtimezoneReport.html"

If you find that a domain controller closer to you has better network performance, then using the Server parameter allows you to set this.

Get-GPOReport -Name "TimeZone" -ReportType XML -Server 'DC1'

You have the option to choose the domain or by not using this parameter the default domain is used. The default domain is the current network resource in the current session.


The Get-GPResultantSetofPolicy cmdlet, much like the RSoP.msc command, gets and writes the Resultant Set of Policy (RSoP) information for a user, a computer, or both to a file. As with the Get-GPOReport cmdlet you can either generate the report in XML or HTML. A nice feature of this cmdlet is as well as generate a report for a remote computer you can also specify the user as well:

Get-GPResultantSetOfPolicy -user Person01 -computer 'DOMAIN\COMP01' -reporttype html -path c:\tmp\Person01Report.html


The last cmdlet I will look at in this article is Get-GPO. The Get-GPO cmdlet as you might expect returns a specified Group Policy or all from the domain. Get-GPO displays some extra detail that some of the other cmdlets don't, like Owner, Id, GpoStatus, CreationTime and ModificationTime.

There is not too much to this cmdlet to use. If you know the name of the GPO you want to display, type this after the name parameter:

Get-GPO -Name "screenaver"
Get GPO cmdlet displaying a group policy

Get GPO cmdlet displaying a group policy

The parameters Domain, Server and All which are featured on the other Group Policy cmdlets are also available on Get-GPO. They are used in the same way, so I won’t add any additional examples. Something worth noting with Get-GPO is you can pipe the output to other Group Policy cmdlets in the module.

Working with WMI to retrieve Group Policy information

Should you be using a computer which does not have the RSAT (Remote Server Administration Tools) tools installed you can make use of the Resultant Set of Policy WMI classes. Microsoft details these classes. I came to work with RSOP_GPO class recently to find if certain Group Policies had applied. The RSOP_GPO class Represents a Group Policy Object.

The instances in this class are separated into three areas:

  • Applied Group Police
  • Group Policies that have read-access but not applyGroupPolicy access
  • Disabled Group Polices

The area I was most interested in was if a certain policy had applied. Depending on the target of the Group Policy, computer or user, will influence the chosen namespace. The namespace for computer is root\rsop\computer and for the user you will need to replace ‘computer’ with ‘user’ plus the user's Security Identifier (SID).

A computer example looks like:

$instanceParams = @{
    ClassName    = 'RSOP_GPO'
    Namespace   = 'root\rsop\computer'
    Filter               = 'name LIKE "Screen%"'
Get-CimInstance @instanceParams
Using CIM to look at Group Policy

Using CIM to look at Group Policy

Note the % after test in the filter parameter – This is the wildcard operator in WMI/CIM as opposed to the normal ‘*’ used in other areas.

To check for a user policy will require getting the user’s SID. To do this dynamically through PowerShell you can use the .NET class, Security.Principal.WindowsIdentity. A small amount of string manipulation is required to work with the CIM class:

$user = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value -replace '-', '_'

Now we can query the user:

$instanceParams = @{
    ClassName    = 'RSOP_GPO'
    Namespace    = "root\rsop\user\$user"
    Filter       = 'name LIKE "Test%"'
Get-CimInstance @instanceParams


PowerShell provides many ways to work and query group policy with the module GroupPolicy from the RSAT tools. Also, the added bonus to look through CIM/WMI natively to retrieve information. A lot of information is in the CIM/WMI database and I recommended reading the article attached from Microsoft to delve deeper. I’ve only scratched the surface on the cmdlets and CIM/WMI database, but I hope this shown the potential available to you when working with Group Policy.

  1. Amit 3 years ago


    I have created on GP on user based. how can I validate that it applies to all the user? I need this as some users are login via VPN. I have read that every 90 min client search for new GP but how can I make sure that it applies to all my users? I need to get this report from my AD server and not from individual client.


  2. Malathi 2 years ago

    Hi Team,

    Could you please tell me how to create GPO policy for SQL server Service Account 

    Kindly help me



Leave a reply

Please enclose code in pre tags

Your email address will not be published.


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account