GPO from zero to hero - Powershell and GPO
During my last post we talked about GPO in an Active Directory domain, today we will move on to concrete things create an managed GPO with PowerShell
1. Powershell Module
And yes there is a powershell module for GPOs and nothing easier to list the commands ;-)
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
With yes 28 cmdlets if I count correctly ;-))
1.1 List All GPO ?
For this example it’s easy you can run the cmdlet get-GPO
with the parameter -all
and you find all GPO in you AD Forest
like this :
DisplayName : Default Domain Policy
DomainName : PwSh.loc
Owner : PWSH\Domain Admins
Id : 31b2f340-016d-11d2-945f-00c04fb984f9
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 08/10/2019 13:23:27
ModificationTime : 08/10/2019 12:29:30
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 3, SysVol Version: 3
WmiFilter :
DisplayName : Default Domain Controllers Policy
DomainName : PwSh.loc
Owner : PWSH\Domain Admins
Id : 6ac1786c-016f-11d2-945f-00c04fb984f9
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 08/10/2019 13:23:27
ModificationTime : 09/10/2019 14:10:34
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 3, SysVol Version: 3
WmiFilter :
DisplayName : Blank_GPO
DomainName : PwSh.loc
Owner : PWSH\Domain Admins
Id : f9b91603-9642-4327-b07a-8699e776c907
GpoStatus : AllSettingsEnabled
Description : First GPO Blank
CreationTime : 28/12/2019 15:21:10
ModificationTime : 28/12/2019 15:21:10
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 0, SysVol Version: 0
WmiFilter :
If you want you can search them by Name or by GUID
1.2 Create GPO with Powershell
With the powershell set-GPRegistryValue
command you had the option to set up the registry keys for your GPO. Ok but how!!
The settings of the set-GPRegistryValue cmdlet
- 1. The [-Guid] parameter corresponds to the
GUID
of the group strategy. - 2. The [-Key] setting specifies the registry key for the focus policy setting based on the attention register: The key must be in one of the following two registry hives:
- 3. HKEY_LOCAL_MACHINE (
HKLM
) for a registry-based policy setting in Computer Configuration. - 4. HKEY_CURRENT_USER (
HKCU
) for a registry-based policy setting in the user’s configuration. - 5. The [-ValueName] setting specifies a value name or a value name table for the registry-based policy setting.
- 6. The [-Server] setting specifies the domain controller on which the code will be run.
- 7. The [-Type] setting specifies the type of data for the registry-based policy setting.
- 8. The acceptable values for this setting are:
Channel
,ExpandString
,Binary
,DWord
,MultiString
,QWord
To facilitate the creation of group strategies with PowerShell an open source project created by Roger Zander [MVP] is available it is based on the ADMX administration files of the version of Windows 10 1803. The address is https://pspeditor.azurewebsites.net/
We will create several GPOs:
- Windows Update for WSUS
- LAPS
- Secure computer configuration
CAUTION When you use the site becarefull all the registry Path contain HKLM:\Software\Policies…. you need to replace to HKLM\Software\Policies without the :.
Let’s only detail the GPO for WSUS
2.0 Action GPO
2.1 Windows Update GPO
For example, we’re going to create a Windows Update group policy and we’re going to set up that group policy with PowerShell:
- 1. Open a Windows PowerShell command prompt as an administrator.
- 2. In the website cited above browse the following objects Computers Configuration, Windows Components, Windows Update then Automatic Updates detection frequency.
- 3. Determine the options for settings, Enabled and DetectionFrequency with a value of 22. In the PowerShell section, we get the keys to the registry to be modified.
- 4. Create group strategy with New-GPO command
Now we can define the registry value with the command set-GPRegistryValue :
Set-GPRegistryValue -Name "Windows Update" -Key "HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" -ValueName "DetectionFrequencyEnabled" -Value 1 -Type DWord
Set-GPRegistryValue -Name "Windows Update" -Key "HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" -ValueName "De-tectionFrequency" -Value 22 -Type DWord
2.2 LAPS GPO
You need to install the Laps Admx file on your Domain Controler and becarefull if you have create a Central Store you need to copy Admx and Adml file the Central store Folder
;).
PowerShell Time :
New-GPO -Name "LAPS_IT"
# Enable local admin password management
Set-GPRegistryValue -Name "LAPS_IT" -Key "HKLM\Software\Policies\Microsoft Services\AdmPwd" -ValueName 'AdmPwdEnabled' -Value 1 -Type Dword
#Do not allow password expiration time longer than required by policy
Set-GPRegistryValue -Name "LAPS_IT" -Key "HKLM\Software\Policies\Microsoft Services\AdmPwd" -ValueName 'PwdExpirationProtectionEnabled' -Value 1 -Type Dword
2.2 Secure computer configuration
Now we add some example for configure a computer in my school
- 1. User Configuration > Control panel > personalization > Prevent changing desktop background
- 2. User Configuration > Control panel > personalization > Prevent changing desktop icons
- 3. User Configuration > Desktop > Desktop Wallpaper > Desktop Wallpaper
- 4. User Configuration > Desktop > Desktop Wallpaper > Remove Recycle Bin icon from desktop
PowerShell Time :
New-GPO -Name "Secure_computer"
# Prevent changing desktop background
Set-GPRegistryValue -Name "Secure_computer" -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop' -ValueName 'NoChangingWallPaper' -Value 1 -Type Dword
#Do Prevent changing desktop icons
Set-GPRegistryValue -Name "Secure_computer" -Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" -ValueName 'NoDispBackgroundPage' -Value 1 -Type Dword
# Desktop Wallpaper
Set-GPRegistryValue -Name "Secure_computer" -Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" -ValueName 'WallpaperStyle' -Value 0 -Type Dword
Set-GPregistryValue -Name "Secure_computer" -Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" -ValueName 'Wallpaper' -Value '\\SRV1\Share1$\wallpaper.jpg' -Type ExpandString
#Disable Remove Recycle Bin icon from desktop
Set-GPregistryValue -Name "Secure_computer" -Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\NonEnum" -ValueName '{645FF040-5081-101B-9F08-00AA002F954E}' -Value '0' -Type Binary
To verify with the Group Policy console :
3.0 Find Registry value into a GPO
The cmdlet Get-GPregistryValue
have the same paramter Like Set-GPregistryValue
how to use it.
Get-GPRegistryValue -Name "LAPS_IT" -Key "HKLM\Software\Policies\Microsoft Services\AdmPwd" -ValueName AdmPwdEnabled
But this poses us some problem we do not have the opportunity to discover the keys use in a GPO without knowing the final keys but voila everything is possible with powershell.
function Recurse-PolicyKeys{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$GPOName,
[Parameter(Mandatory=$true)]
[string]$Key
)
$current = Get-GPRegistryValue -Name $gpoName -Key $key
foreach ($item in $current){
if ($item.ValueName -ne $null){
[array]$returnVal += $item
}
else{
Recurse-PolicyKeys -Key $item.fullkeypath -gpoName $gpoName
}
}
return $returnVal
}
Let’s try this :
PS C:\Users\Administrator> Recurse-PolicyKeys -GPOName "Secure_computer" -Key "HKCU\Software"
KeyPath : Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop
FullKeyPath : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop
Hive : CurrentUser
PolicyState : Set
Value : 1
Type : DWord
ValueName : NoChangingWallPaper
HasValue : True
KeyPath : Software\Microsoft\Windows\CurrentVersion\Policies\NonEnum
FullKeyPath : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\NonEnum
Hive : CurrentUser
PolicyState : Set
Value : {0}
Type : Binary
ValueName : {645FF040-5081-101B-9F08-00AA002F954E}
HasValue : True
KeyPath : Software\Microsoft\Windows\CurrentVersion\Policies\System
FullKeyPath : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
Hive : CurrentUser
PolicyState : Set
Value : 1
Type : DWord
ValueName : NoDispBackgroundPage
HasValue : True
KeyPath : Software\Microsoft\Windows\CurrentVersion\Policies\System
FullKeyPath : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
Hive : CurrentUser
PolicyState : Set
Value : 0
Type : DWord
ValueName : WallpaperStyle
HasValue : True
KeyPath : Software\Microsoft\Windows\CurrentVersion\Policies\System
FullKeyPath : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
Hive : CurrentUser
PolicyState : Set
Value : \\SRV1\Share1$\wallpaper.jpg
Type : ExpandString
ValueName : Wallpaper
HasValue : True
Unbelievable, Powershell is really awesome 😉 ! !
4.0 Linked them to an OU or not…
Of course all GPOs must be linked to an OU that contains either Computer objects or user objects. For this nothing very difficult there is a cmdlet for doing this: New-GPLink
.
Get-GPO -Name "Secure_computer" | New-GPLink -target "OU=Lyon,OU=Sites,DC=PwSh,DC=loc" -LinkEnabled Yes
GpoId : 4ca77301-6c21-4820-acb4-2938b4488453
DisplayName : Secure_computer
Enabled : True
Enforced : False
Target : OU=Lyon,OU=Sites,DC=PwSh,DC=loc
Order : 1
In the next part, I will speak about Backup GPO and how to verify if a GPO is apply on computers ;).
Thank’s for reading.
Written by Jérôme Bezet-Torres @JM2K69.