Contents

Manage group policies with PowerShell

Despite Intune, DSC and Entra ID (Azure AD); group policies are still a widely used method to manage Windows clients and servers in many companies. However, the MMC is not really suitable for managing several hundred GPOs. But that’s what PowerShell is designed for.

Most people will have already used Get-GPO, but Microsoft provides 25 more cmdlets and two aliases in the GroupPolicy module.

PS C:\Users\Fabian> Get-Command -Module GroupPolicy
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           Get-GPPermissions                                  1.0.0.0    GroupPolicy
Alias           Set-GPPermissions                                  1.0.0.0    GroupPolicy
Cmdlet          Backup-GPO                                         1.0.0.0    GroupPolicy
Cmdlet          Copy-GPO                                           1.0.0.0    GroupPolicy
Cmdlet          Get-GPInheritance                                  1.0.0.0    GroupPolicy
Cmdlet          Get-GPO                                            1.0.0.0    GroupPolicy
Cmdlet          Get-GPOReport                                      1.0.0.0    GroupPolicy
Cmdlet          Get-GPPermission                                   1.0.0.0    GroupPolicy
Cmdlet          Get-GPPrefRegistryValue                            1.0.0.0    GroupPolicy
Cmdlet          Get-GPRegistryValue                                1.0.0.0    GroupPolicy
Cmdlet          Get-GPResultantSetOfPolicy                         1.0.0.0    GroupPolicy
Cmdlet          Get-GPStarterGPO                                   1.0.0.0    GroupPolicy
Cmdlet          Import-GPO                                         1.0.0.0    GroupPolicy
Cmdlet          Invoke-GPUpdate                                    1.0.0.0    GroupPolicy
Cmdlet          New-GPLink                                         1.0.0.0    GroupPolicy
Cmdlet          New-GPO                                            1.0.0.0    GroupPolicy
Cmdlet          New-GPStarterGPO                                   1.0.0.0    GroupPolicy
Cmdlet          Remove-GPLink                                      1.0.0.0    GroupPolicy
Cmdlet          Remove-GPO                                         1.0.0.0    GroupPolicy
Cmdlet          Remove-GPPrefRegistryValue                         1.0.0.0    GroupPolicy
Cmdlet          Remove-GPRegistryValue                             1.0.0.0    GroupPolicy
Cmdlet          Rename-GPO                                         1.0.0.0    GroupPolicy
Cmdlet          Restore-GPO                                        1.0.0.0    GroupPolicy
Cmdlet          Set-GPInheritance                                  1.0.0.0    GroupPolicy
Cmdlet          Set-GPLink                                         1.0.0.0    GroupPolicy
Cmdlet          Set-GPPermission                                   1.0.0.0    GroupPolicy
Cmdlet          Set-GPPrefRegistryValue                            1.0.0.0    GroupPolicy
Cmdlet          Set-GPRegistryValue                                1.0.0.0    GroupPolicy

Find group policies

Unfortunately Get-Gpo does not support any search filter but can only output all or one GPO. You can specify individual group policies via -Id or -Name, but you must know the exact values. With the parameter -All a list of all GPOs is output.

A filter can therefore always be applied only afterwards.

# Default Domain Policy
Get-Gpo -Id 31b2f340-016d-11d2-945f-00c04fb984f9

# Default Domain Controllers Policy
Get-Gpo -Id 6ac1786c-016f-11d2-945f-00c04fb984f9

# List all GPOs
Get-Gpo -All

# Filter by name
Get-Gpo -All | Where-Object DisplayName -match "Default Domain"
Info
The Default Domain Policy and the Default Domain Controller Policy always have these exact GUIDs.

Create a group policy

To create a new, empty group policy you do not need to provide much information. A descriptive name is sufficient, a descriptive comment is desirable.

PS C:\Users\Fabian> New-GPO -Name "MSFT Windows Server 2022 - Member Server" -Comment "Microsoft Security Baseline"
DisplayName      : MSFT Windows Server 2022 - Member Server
DomainName       : lab.bader.cloud
Owner            : LAB\Domain Admins
Id               : 0ef52ff6-0ef0-42e1-9273-508463a69a44
GpoStatus        : AllSettingsEnabled
Description      : Microsoft Security Baseline
CreationTime     : 11/15/2021 8:07:55 PM
ModificationTime : 11/15/2021 8:07:55 PM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :

Import settings

In the case of security baselines, for example, exports of group policies are often supplied as templates. Microsoft also does this with its Microsoft Security Compliance Toolkit. This contains the Microsoft recommended settings for all common operating systems and browsers.

To import these templates Import-GPO can be used. This cmdlet overwrites all existing settings in the group policy.

$GPO = Get-Gpo -Name "MSFT Windows Server 2022 - Member Server"
Import-GPO -Path "C:\Users\Fabian\Downloads\Windows Server-2022-Security-Baseline-FINAL\GPOs" -BackupGpoName "MSFT Windows Server 2022 - Member Server" -TargetGuid $GPO.id

Instead of creating the GPO beforehand, this can be done in one step with the -CreateIfNeeded parameter.

Import-GPO -Path "C:\Users\Fabian\Downloads\Windows Server-2022-Security-Baseline-FINAL\GPOs" -BackupGpoName "MSFT Windows Server 2022 - Domain Controller" -TargetName "MSFT Windows Server 2022 - Domain Controller" -CreateIfNeeded

When importing a GPO, a mapping file can also be provided. This translates e.g. SIDs from one domain to the other.

Import-GPO -Path "C:\Users\Fabian\Downloads\Windows Server-2022-Security-Baseline-FINAL\GPOs" -BackupGpoName "MSFT Windows Server 2022 - Domain Controller" -TargetName "MSFT Windows Server 2022 - Domain Controller" -CreateIfNeeded -MigrationTable C:\Users\Fabian\Documents\DomainA2DomainB.migtable

The required .migtable file must be created manually. It is recommended to use the GUI and save the mapping for future use. If you don’t want to do this you can easily create the file by hand. It is an XML file as shown in this example.

<?xml version="1.0" encoding="utf-16"?>
<MigrationTable xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.microsoft.com/GroupPolicy/GPOOperations/MigrationTable">
  <Mapping>
    <Type>Computer</Type>
    <Source>COMPUTER01</Source>
    <Destination>COMPUTER02</Destination>
  </Mapping>
  <Mapping>
    <Type>User</Type>
    <Source>Administrator</Source>
    <Destination>SuperAdmin</Destination>
  </Mapping>
</MigrationTable>

Create a report

Similar to the GUI, the configuration settings of a group policy can be exported. However, different formats can be selected.

  • HTML = The report known from the MMC that can be viewed in the browser.
  • XML = Output in XML format. This makes it possible e.g. to process the information with PowerShell.
Get-GPOReport -Name "MSFT Windows Server 2022 - Member Server" -ReportType Html -Path .\Desktop\Report.html
Get-GPOReport -Name "MSFT Windows Server 2022 - Member Server" -ReportType Xml -Path .\Desktop\Report.xml
Info
Get-GPOReport is unfortunately not very performant, so I can’t recommend the cmdlet for reports over many group policies.

For a GPO to be applied in the first place, it must be linked to one or more OUs, domains or sites. New-GPLink does this reliably. If you want to adjust this link afterwards, this is easily possible with Set-GPLink. This makes e.g. the adjustment of the link order much easier.

$GPO = Get-Gpo -Name "MSFT Windows Server 2022 - Member Server"
# Create a new link
New-GPLink -Guid $GPO.Id -Target "OU=DemoOU,$((Get-ADDomain).DistinguishedName)" -LinkEnabled Yes -Order 1
# Change existing link
Set-GPLink -Guid $GPO.Id -Target "OU=DemoOU,$((Get-ADDomain).DistinguishedName)" -LinkEnabled No
Info
With the Enforced parameter the settings of this group policy will always be applied regardless of the “Link Order” or interrupted inheritance.
Set-GPLink -Guid $GPO.Id -Target "OU=DemoOU,$((Get-ADDomain).DistinguishedName)" -Enforced Yes

It is just as easy to remove such a link again.

Remove-GPLink -Guid $GPO.Id -Target "OU=DemoOU,$((Get-ADDomain).DistinguishedName)"

Determine assigned group policies

In order to find out which GPOs are effective at a certain OU, Get-GPInheritance is used.

Get-GPInheritance "OU=DemoOU,$((Get-ADDomain).DistinguishedName)"
Name                  : demoou
ContainerType         : OU
Path                  : ou=demoou,dc=lab,dc=bader,dc=cloud
GpoInheritanceBlocked : No
GpoLinks              : {}
InheritedGpoLinks     : {Default Domain Policy}

Block inheritance

Set-GPInheritance "OU=DemoOU,$((Get-ADDomain).DistinguishedName)" -IsBlocked Yes
Name                  : demoou
ContainerType         : OU
Path                  : ou=demoou,dc=lab,dc=bader,dc=cloud
GpoInheritanceBlocked : Yes
GpoLinks              : {}
InheritedGpoLinks     : {}
Info
A GPO linked higher in the hierarchy with the Enforced flag enabled also affects the objects below this OU regardless if inheritance is blocked.

Assign WMI filters

The creation of WMI filters is unfortunately not possible via PowerShell with native cmdlets. Of course, the community has stepped up and provided a corresponding module. GPWmiFilter by Friedrich Weinmann.

What is natively possible, however, is if a WMI is already in use, to assign it to another GPO.

# Get WMI filter from existing GPO
$WMIFilter = Get-GPO -Name "SourceGPO" | Select-Object -ExpandProperty WmiFilter
# Get target GPO ...
$GPO = Get-GPO -Name "MSFT Windows Server 2022 - Member Server"
# ... an apply the WMI filter
$GPO.WmiFilter = $WMIFilter

Read permissions

To retrieve the permissions assigned to a group policy, Get-GPPermission is used. It is possible to read all permissions, or only for a named group or AD object.

Get-GPPermission -Name "MSFT Windows Server 2022 - Member Server" -All
Trustee     : Authenticated Users
TrusteeType : WellKnownGroup
Permission  : GpoApply
Inherited   : False

Trustee     : Domain Admins
TrusteeType : Group
Permission  : GpoEditDeleteModifySecurity
Inherited   : False

Trustee     : Enterprise Admins
TrusteeType : Group
Permission  : GpoEditDeleteModifySecurity
Inherited   : False

Trustee     : ENTERPRISE DOMAIN CONTROLLERS
TrusteeType : WellKnownGroup
Permission  : GpoRead
Inherited   : False

Trustee     : SYSTEM
TrusteeType : WellKnownGroup
Permission  : GpoEditDeleteModifySecurity
Inherited   : False
Get-GPPermission -Name "MSFT Windows Server 2022 - Member Server" -TargetType Group
Trustee     : Authenticated Users
TrusteeType : WellKnownGroup
Permission  : GpoApply
Inherited   : False

Set permissions

If a group policy is only to be assigned to a specific group of people, for example, the authorization of the Authenticated Users must always be changed. This group must not be removed under any circumstances.

The default mode of the cmdlet Set-GPPermission is additive, the named permissions are appended. If higher permissions already exist, they will remain. Therefore the correct use of the -Replace parameter is important.

$GPO = Get-Gpo -Name "MSFT Windows 11 - User"
Set-GPPermission -Guid $GPO.Id -PermissionLevel GpoApply -TargetType Group -TargetName "Windows 11 Users"
Set-GPPermission -Name $GPO.Id -PermissionLevel GpoRead -TargetType Group -TargetName "Authenticated Users" -Replace

The same cmdlet is also used when permissions are to be removed. Here the PermissionLevel is set to None and the parameter -Replace is used.

Set-GPPermission -Guid $GPO.Id -PermissionLevel None -TargetName "Windows 11 Users" -TargetType Group -Replace

Backup

A backup of the group policies is very simple with Backup-GPO. A new directory with a GUID is created for each backup and all relevant data is stored in this directory. A regular backup of all GPOs is thus no problem.

Get-GPO -All | Backup-GPO -Path C:\GPOBackup\ -Comment "$(Get-Date)"

Get values

To retrieve individual values from a GPO there are two cmdlets: Get-GPPrefRegistryValue and Get-GPRegistryValue.

The difference between the two cmdlets is the type of registry value they read from the group policy.

Get-GPPrefRegistryValue reads values created under Computer -> Preferences -> Windows Settings -> Registry. These are not the values that are controlled in the GUI via ADMX files, but values that are added manually. They are not limited to HKEY_LOCAL_(MACHINE|USER)\SOFTWARE\Policies\.

Get-GPRegistryValue is everything that is stored in the registry.pol via an ADMX file. In most cases this is the area you want to edit.

By specifying the registry -Key all values in this key can be retrieved.

Get-GPRegistryValue -Guid $GPO.Id -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\"
KeyPath     : SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
FullKeyPath : HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
Hive        : LocalMachine
PolicyState : Set
Value       : 0
Type        : DWord
ValueName   : AllowBasic
HasValue    : True

KeyPath     : SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
FullKeyPath : HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
Hive        : LocalMachine
PolicyState : Set
Value       : 0
Type        : DWord
ValueName   : AllowUnencryptedTraffic
HasValue    : True

KeyPath     : SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
FullKeyPath : HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
Hive        : LocalMachine
PolicyState : Set
Value       : 1
Type        : DWord
ValueName   : DisableRunAs
HasValue    : True
Get-GPRegistryValue -Guid $GPO.Id -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service\" -ValueName AllowBasic
KeyPath     : SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
FullKeyPath : HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service
Hive        : LocalMachine
PolicyState : Set
Value       : 0
Type        : DWord
ValueName   : AllowBasic
HasValue    : True
Info
Audit and SecEdit are two areas of the group policies that cannot be read or edited via native cmdlets. However, since these are text files, this is possible in principle.

Set values

By using Set-GPRegistryValue single values in the GPO can also be changed. Thus for setting new preferences the MMC is no longer necessary, but only the knowledge in which registry key which setting is hidden.

For this the web page admx.help is a big help. For nearly all ADMX files the appropriate values are available and the necessary information about “Registry Path " and Value Name/Type and possible values are broken down.

The following is an example of the setting Turn off real-time protection

Set-GPRegistryValue -Name 'MSFT Windows Server 2022 - Member Server' -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection' -ValueName 'DisableRealtimeMonitoring' -Type DWord -Value 0

Get values recursive

Since it is not possible to read more than one level with the native cmdlet Get-GPRegistryValue, I created a function inspired by this Snippet that enables you to do this. This way all settings of a group policy can be output as PolicyRegistrySetting objects and processed directly. This is much faster than the cmdlet Get-GPOReport.

function Get-GPRegistryValueRecurse {
    [CmdletBinding()]
    param (
        [Alias('DisplayName')]
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [string]$Name,

        [Parameter(Mandatory = $true)]
        [string]$Key
    )

    # Remove trailing backslash
    $Key = $Key -replace '\\$'
    $RegistryItems = Get-GPRegistryValue -Name $Name -Key $key
    Write-Verbose "Found $($RegistryItems.Count) items"
    foreach ($RegistryItem in $RegistryItems) {
        if ( $RegistryItem -is [Microsoft.GroupPolicy.PolicyRegistrySetting] ) {
            # Output the registry item
            $RegistryItem
            Write-Verbose "Found registry item: $($RegistryItem.Name)"
        } elseif ( $RegistryItem -is [Microsoft.GroupPolicy.RegistryItem]) {
            Write-Verbose "Found registry key: $($RegistryItem.FullKeyPath)"
            # Go deeper
            Get-GPRegistryValueRecurse -Key $RegistryItem.FullKeyPath -Name $Name
        }
    }
}

Example application with pipelining

$GPO | Get-GPRegistryValueRecurse -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client\"

Merge group policies

With what we have just learned, another problem can be easily solved: How to merge two group policies into one?

Since the GUI only offers the import, but this function overwrites all existing settings, the only solution is to use the PowerShell.

In the following example I first recursively read all values below the registry key HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\ to then transfer them via Set-GPRegistryValue into the already existing GPO “MSFT Windows Server 2022 - Member Server”.

# Retrieve all settings from a specific registry key
$SourceSettings = Get-GPRegistryValueRecurse -Name "MSFT Windows Server 2022 - Defender Antivirus" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\"
# Define target GPO name
$TargetGPOName = "MSFT Windows Server 2022 - Member Server"
foreach ($Setting in $SourceSettings) {
    if (-not [string]::isNullOrWhitespace($Setting ) ) {
        # Replace double backslash if present
        $TargetKey = $Setting.FullKeyPath -replace '\\\\', '\'
        if ($Setting.PolicyState -eq "Delete") {
            Set-GPRegistryValue -Name $TargetGPOName -Key $TargetKey -ValueName $($Setting.ValueName) -Disable
        } else {
            Set-GPRegistryValue -Name $TargetGPOName -Key $TargetKey -ValueName $($Setting.ValueName) -Type $($Setting.Type) -Value $($Setting.Value)
        }
    }
}
Warning
In this szenario the source GPO also overwrites existing values in the target GPO.
However, not all values, but only values that conflict with the source GPO.

This example can be very easily customized to include all “computer” values.

$SourceSettings = Get-GPRegistryValueRecurse -Name "MSFT Windows Server 2022 - Defender Antivirus" -Key "HKLM\SOFTWARE\"

Edit firewall settings

To edit the Windows Defender firewall settings, none of the above mentioned commands are suitable. However, Microsoft has two more cmdlets, or rather functions, up its sleeve.

PS C:\Users\Fabian> Get-Command *gpo*  | ? Source -ne GroupPolicy
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Open-NetGPO                                        2.0.0.0    NetSecurity
Function        Save-NetGPO                                        2.0.0.0    NetSecurity
Application     chgport.exe                                        10.0.22... C:\Windows\system32\chgport.exe

Open-NetGPO creates a WMI session to an existing group policy and then allows to use this session with the normal cmdlets to manage firewall rules. The WMI session must always be passed using the -GPOSession parameter.

Info
For reasons unknown to me, the parameter -GPOSession is no longer available in the Windows 11 version of Get-NetFirewallRule. -PolicyStore can be used alternatively.
New-GPO -Name "GPO_Server_Windows_Firewall"
$gpoSession = Open-NetGPO -PolicyStore lab.bader.cloud\GPO_Server_Windows_Firewall
# Windows until 11
Get-NetFirewallRule -GPOSession $gpoSession
# Windows 11
Get-NetFirewallRule -PolicyStore $gpoSession

# Add outbound DNS queries to 8.8.8.8
New-NetFirewallRule -GPOSession $gpoSession -DisplayName "Allow traffic to Google" -Action Allow  -Direction Outbound -RemoteAddress 8.8.8.8 -Protocol Udp -RemotePort 53
# Save changes to GPO
Save-NetGPO -GPOSession $gpoSession

# Check if changes where made correctly
$gpoSession = Open-NetGPO -PolicyStore lab.bader.cloud\GPO_Server_Windows_Firewall
Get-NetFirewallRule -PolicyStore $gpoSession

Analyze all group policies

I kept encountering the following problem: In which group policy is one or more settings set and if so with which value.

The only answer I found so far on the Internet was to use Get-GPOReport with the conversion to XML and subsequent evaluation of the XML files. Unfortunately this is very very slow, with several hundred, maybe even thousands of GPOs in the environment this is not a real solution.

Therefore I created the script CheckGPOSettings.ps1.

This script analyzes all group policies in one or more domains for one or more values using a passed hashtable and returns the results as PowerShell objects. This makes it very easy to process them further. And best of all, it searches all typical locations within the GPO. No matter if Get-GPRegistryValue, GptTmpl.inf or Get-GPPrefRegistryValue, the script finds them all.

Info
In the current version, audit settings from audit.csv are not supported.

Query Hashtable

The hashtable used for the search consists of two nested hashtables. The outer one uses a freely selectable name for the searched value as key. Here, for example, the meaningful name of the setting should be used.

As value another Hashtable is used, this describes the value to be searched. As Key the Registry Key is used and as Value the Value Name of the Registry Item.

    $CheckSettings = @{
        "Unique setting name for the report. Choose something you can remember like the display name of the setting" = @{
            # Key = The path to the registry key
            "Key"       = "HKLM\SOFTWARE\Policies\Microsoft\PassportForWork"
            # ValueName = The name of the registry value
            "ValueName" = "Enabled"
        }
    }

In the following example I am looking for two different registry settings. The first one is the LAN Manager Authentication Level (hopefully set to 5) and the second one is the value for the service MrxSmb10 better known as SMBv1. A value of 4 is desired (= Disabled).

$CheckSettings = @{
    "Network security: LAN Manager authentication level" = @{
        "Key"       = "HKLM\System\CurrentControlSet\Control\Lsa"
        "ValueName" = "LmCompatibilityLevel"
    }
    "SMBv1 service state" = @{
        "Key"       = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MrxSmb10"
        "ValueName" = "Start"
    }

}

Now I can start the function Get-SettingsFromGPOs using the domain and the created hashtable.

C:\Users\Fabian> Get-SettingsFromGPOs -Domain "lab.bader.cloud" -CheckSetting $CheckSettings

As a result I get the following information:

  • In which domain does the group policy exist
  • What is the name of the group policy
  • Where is this group policy linked
  • Is a WMI filter applied
  • The path to the GPO
  • Current status of the GPO (Enabled/Disabled)
  • The custom name for the setting
  • The registry key
  • The name of the RegistryItem
  • The value of the RegistryItem
  • The type of the RegistryItem
DomainName  : lab.bader.cloud
GPO         : MSFT Windows Server 2022 - Domain Controller
GPOLinks    :
Setting     : Network security: LAN Manager authentication level
ValueName   : LmCompatibilityLevel
Hive        : HKLM\System\CurrentControlSet\Control\Lsa
WmiFilter   :
PolicyState :
Value       : 5
Type        : REG_DWORD
Path        : cn={1C09EB8B-1EB0-488B-A92C-34030213F58B},cn=policies,cn=system,DC=lab,DC=bader,DC=cloud

DomainName  : lab.bader.cloud
GPO         : MSFT Windows Server 2022 - Domain Controller
GPOLinks    :
Setting     : SMBv1 service state
ValueName   : Start
Hive        : HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MrxSmb10
WmiFilter   :
PolicyState : Set
Value       : 4
Type        : DWord
Path        : cn={1C09EB8B-1EB0-488B-A92C-34030213F58B},cn=policies,cn=system,DC=lab,DC=bader,DC=cloud

* Currently I can only find out the GPLinks by using the cmdlet Get-GPReport. But this is only started if the searched value is found in the group policy. For additional performance I added the switch -NoGPLink. This improved the execution time from 776ms to 568ms in my small demo environment. So in particularly large environments, this can be worthwhile.

In this GitHub Repository you can find more examples and the repository is open for pull requests. So over time a collection of search parameters can be gathered.

Summary

With PowerShell, group policies can be manipulated very extensively. Unfortunately, it is not as easy to get started as with other cmdlets, but once you understand the basic concept, you can do a lot of things, fast.

If you have been paying attention, you will notice that some cmdlets did not make it into the blog article. This is either because they are self-explanatory (Copy-GPO), the counterpart was introduced (Remove-GPRegistryValue) or I just don’t use them (*-GPStarterGPO).

Therefore examples for the following cmdlets are missing

  • Copy-GPO
  • Get-GPStarterGPO
  • Invoke-GPUpdate
  • New-GPStarterGPO
  • Remove-GPPrefRegistryValue
  • Remove-GPRegistryValue
  • Rename-GPO
  • Restore-GPO