Group Policy Objects (GPOs) are the primary mechanism for managing Windows environments at scale. GPOs let you configure security settings, deploy software, map drives, set desktop configurations, and enforce compliance across all domain-joined computers and users. This guide covers creating and managing GPOs on your Windows Server VPS.
Understanding Group Policy
- Computer Configuration: Applied at startup, affects the machine regardless of who logs in
- User Configuration: Applied at logon, follows the user regardless of which machine they use
- GPO Processing Order: Local → Site → Domain → OU (LSDOU) — later policies override earlier ones
- Inheritance: GPOs applied to parent OUs are inherited by child OUs unless blocked
Create and Link GPOs with PowerShell
# Import Group Policy module
Import-Module GroupPolicy
# Create a new GPO
$GPO = New-GPO -Name "Security Baseline" -Comment "Corporate security settings"
# Link GPO to an OU
New-GPLink -Guid $GPO.Id `
-Target "OU=Company,DC=corp,DC=example,DC=com" `
-LinkEnabled Yes
# Create and link in one step
New-GPO -Name "Desktop Settings" | `
New-GPLink -Target "OU=Users,OU=Company,DC=corp,DC=example,DC=com"
# List all GPOs
Get-GPO -All | Select-Object DisplayName, GpoStatus, CreationTime | Format-Table
# Get GPO report
Get-GPOReport -Name "Security Baseline" -ReportType Html -Path "C:\Reports\SecurityBaseline.html"
Configure Security Policies
# Password Policy (must be at domain level)
# Set via Default Domain Policy or Fine-Grained Password Policy
# Account Lockout Policy
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" `
-ValueName "MaxDevicePasswordFailedAttempts" `
-Type DWord -Value 5
# Windows Firewall — enable on all profiles
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" `
-ValueName "EnableFirewall" `
-Type DWord -Value 1
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile" `
-ValueName "EnableFirewall" `
-Type DWord -Value 1
# Disable USB storage
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR" `
-ValueName "Start" `
-Type DWord -Value 4
# Require NTLMv2
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" `
-ValueName "LmCompatibilityLevel" `
-Type DWord -Value 5
# Enable Windows Defender
Set-GPRegistryValue -Name "Security Baseline" `
-Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" `
-ValueName "DisableAntiSpyware" `
-Type DWord -Value 0
User Configuration Policies
# Map network drives via Group Policy Preferences
# This is typically done via GPMC GUI, but can be scripted:
# Restrict Control Panel access
Set-GPRegistryValue -Name "Desktop Settings" `
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" `
-ValueName "NoControlPanel" `
-Type DWord -Value 1
# Set wallpaper
Set-GPRegistryValue -Name "Desktop Settings" `
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
-ValueName "Wallpaper" `
-Type String -Value "\\corp.example.com\SYSVOL\corp.example.com\wallpaper\corporate.jpg"
# Disable command prompt
Set-GPRegistryValue -Name "Desktop Settings" `
-Key "HKCU\Software\Policies\Microsoft\Windows\System" `
-ValueName "DisableCMD" `
-Type DWord -Value 1
# Configure browser homepage
Set-GPRegistryValue -Name "Desktop Settings" `
-Key "HKCU\Software\Policies\Microsoft\Edge" `
-ValueName "HomepageLocation" `
-Type String -Value "https://intranet.corp.example.com"
Software Deployment via GPO
# Place MSI packages on a network share
# \\corp.example.com\Software\packages\
# Deploy software to computers using PowerShell
# Note: Software deployment GPOs typically use the GPMC GUI
# But you can configure the registry-based approach:
# Startup script to install software
Set-GPRegistryValue -Name "Software Deployment" `
-Key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0" `
-ValueName "Script" `
-Type String -Value "\\corp.example.com\SYSVOL\corp.example.com\scripts\install-software.ps1"
GPO Backup and Restore
# Backup all GPOs
$BackupPath = "C:\GPOBackups\$(Get-Date -Format 'yyyyMMdd')"
New-Item -ItemType Directory -Path $BackupPath -Force
Get-GPO -All | ForEach-Object {
Backup-GPO -Guid $_.Id -Path $BackupPath
Write-Host "Backed up: $($_.DisplayName)"
}
# Restore a specific GPO
Restore-GPO -Name "Security Baseline" -Path $BackupPath
# Import GPO settings from backup to a new GPO
Import-GPO -BackupGpoName "Security Baseline" `
-Path $BackupPath `
-TargetName "Security Baseline v2" `
-CreateIfNeeded
Troubleshooting GPO
# Force Group Policy update on a client
gpupdate /force
# View applied GPOs for current user/computer
gpresult /r
# Detailed RSoP (Resultant Set of Policy)
gpresult /h C:\Reports\gpresult.html
# Check GPO replication status
Get-GPO -All | ForEach-Object {
$gpo = $_
$status = Get-GPOReport -Guid $gpo.Id -ReportType Xml
[PSCustomObject]@{
Name = $gpo.DisplayName
UserVersion = $gpo.User.DSVersion
ComputerVersion = $gpo.Computer.DSVersion
}
} | Format-Table
Best Practices
- Name GPOs descriptively: Include purpose and scope (e.g., "Security-AllComputers-Baseline")
- Don't modify Default Domain Policy except for password/account lockout policies
- Use OU structure for targeting: Link GPOs to OUs rather than using security filtering when possible
- Test in a lab OU first: Create a test OU and verify GPO behavior before applying broadly
- Document all GPOs: Use the Comment field and maintain external documentation
- Back up GPOs regularly: Before making changes and on a scheduled basis
- Minimize the number of GPOs: Fewer, well-organized GPOs are easier to troubleshoot