How to Configure Windows Security Baselines with Group Policy on Windows Server 2025
Manually configuring hundreds of Group Policy settings across an enterprise is neither reproducible nor auditable. Microsoft’s Security Compliance Toolkit (SCT) solves this by shipping pre-built security baselines — curated sets of Group Policy Object (GPO) settings that represent Microsoft’s recommended configuration for each Windows Server release. For Windows Server 2025, the toolkit includes baselines for the OS itself, Microsoft Edge, and Microsoft Defender Antivirus. This tutorial walks through downloading and importing the baselines, deploying them to Active Directory, identifying deviations with Policy Analyzer, and creating targeted exception GPOs for settings your organisation legitimately needs to override.
Prerequisites
- Windows Server 2025 domain controller running Active Directory Domain Services
- An account with Domain Admin or Group Policy Creator Owners membership
- Group Policy Management Console (GPMC) — installed via
Install-WindowsFeature GPMC - Internet access to download the Security Compliance Toolkit (or an internal mirror)
- A test Organisational Unit (OU) containing non-production servers for initial validation
Step 1: Download the Security Compliance Toolkit
The Security Compliance Toolkit is a free download from the Microsoft Download Center. It ships as a self-extracting ZIP that contains the baselines, LGPO.exe, PolicyAnalyzer.exe, and supporting scripts.
# Download SCT to a staging folder (PowerShell 7 recommended)
$sctUrl = 'https://download.microsoft.com/download/SCT/Windows-Server-2025-Security-Baseline.zip'
$stagingDir = 'C:SCTWindowsServer2025'
New-Item -ItemType Directory -Path $stagingDir -Force | Out-Null
Invoke-WebRequest -Uri $sctUrl -OutFile "$stagingDirWS2025-Baseline.zip" -UseBasicParsing
Expand-Archive -Path "$stagingDirWS2025-Baseline.zip" `
-DestinationPath $stagingDir -Force
Get-ChildItem $stagingDir -Recurse | Select-Object FullName
After extraction you will find a folder structure similar to:
C:SCTWindowsServer2025
├── Documentation
├── GP Reports
├── GPOs
│ ├── MSFT Windows Server 2025 - Domain Controller
│ ├── MSFT Windows Server 2025 - Member Server
│ └── MSFT Windows Server 2025 - Credential Guard
├── Scripts
│ ├── Baseline-LocalInstall.ps1
│ └── MapGuidsToGpoNames.ps1
└── Tools
├── LGPO.exe
└── PolicyAnalyzer
Step 2: Apply a Baseline to a Local Machine with LGPO.exe
LGPO.exe (Local Group Policy Object tool) imports baseline settings into the local machine policy, making it ideal for standalone servers or for validating the baseline before domain deployment. The /g flag imports from a GPO backup folder:
# Apply the Member Server baseline locally
$lgpoExe = 'C:SCTWindowsServer2025ToolsLGPO.exe'
$gpoBackup = 'C:SCTWindowsServer2025GPOsMSFT Windows Server 2025 - Member Server'
# /g imports from a GPO backup folder (the folder containing {GUID} subfolders)
& $lgpoExe /g $gpoBackup
# To import from a raw LGPO text file use /t instead:
# & $lgpoExe /t 'C:SCT...registry.pol.txt'
# Verify local policy was updated
gpresult /r /scope computer
To export the current local policy as a backup before making changes, use the /b flag:
# Backup current local GPO before importing baseline
$backupPath = "C:SCTBackupsPreBaseline_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
& $lgpoExe /b $backupPath
Write-Host "Local GPO backed up to $backupPath"
Step 3: Import the Baseline into Active Directory with GPMC
For domain deployments, import the baseline as a new GPO in Active Directory using GPMC. PowerShell automates the process and avoids the manual import wizard:
Import-Module GroupPolicy
$domainName = (Get-ADDomain).DNSRoot
$gpoName = 'MSFT WS2025 Member Server Baseline'
$backupFolder = 'C:SCTWindowsServer2025GPOs'
$backupId = '{GUID-OF-MEMBER-SERVER-BACKUP}' # Replace with actual GUID from the GPOs folder
# Create a new blank GPO
$newGpo = New-GPO -Name $gpoName -Domain $domainName -Comment 'Microsoft Security Baseline — WS2025 Member Server'
# Import the baseline settings into the new GPO
Import-GPO -BackupId $backupId `
-TargetName $gpoName `
-Path $backupFolder `
-Domain $domainName
Write-Host "GPO '$gpoName' created with ID: $($newGpo.Id)"
To discover the GUID of the backup folder automatically:
# Find backup GUIDs from bkupInfo.xml files in the GPO backup directory
Get-ChildItem -Path 'C:SCTWindowsServer2025GPOs' -Recurse -Filter 'bkupInfo.xml' |
ForEach-Object {
$xml = [xml](Get-Content $_.FullName)
[PSCustomObject]@{
GPOName = $xml.BackupInst.GPODisplayName.'#text'
BackupId = $xml.BackupInst.ID.'#text'
Path = $_.DirectoryName
}
}
Step 4: Link the GPO to a Test OU First
Never link a new baseline directly to the domain root or a tier-0 OU on first deployment. Link it to a dedicated test OU, apply gpupdate /force on a test server, and validate functionality before broader rollout:
$testOuDN = 'OU=WS2025-Test,OU=Servers,DC=contoso,DC=com'
$gpoName = 'MSFT WS2025 Member Server Baseline'
# Link GPO to test OU (order 1 = highest precedence within the OU)
New-GPLink -Name $gpoName -Target $testOuDN -LinkEnabled Yes -Order 1
# Force policy refresh on a specific test server
Invoke-Command -ComputerName 'TESTSVR01' -ScriptBlock { gpupdate /force /wait:0 }
# Retrieve RSoP (Resultant Set of Policy) summary remotely
Get-GPResultantSetOfPolicy -Computer 'TESTSVR01' -ReportType Html `
-Path 'C:SCTReportsTESTSVR01-RSoP.html'
Step 5: Use Policy Analyzer to Identify Deviations
Policy Analyzer is a GUI tool included in the SCT that compares two policy sets — typically your live GPO backup against the Microsoft baseline — and highlights every setting that differs. Run it from the command line to produce a CSV delta report:
# Export current domain GPO as a backup for comparison
$liveBackupPath = "C:SCTBackupsLive_$(Get-Date -Format 'yyyyMMdd')"
New-Item -ItemType Directory -Path $liveBackupPath -Force | Out-Null
Backup-GPO -Name 'MSFT WS2025 Member Server Baseline' `
-Path $liveBackupPath `
-Comment 'Live baseline snapshot for Policy Analyzer comparison'
# PolicyAnalyzer.exe is a GUI tool — launch it pointing at both policy sets:
# 1. File > Add > Browse to baseline GPO backup folder
# 2. File > Add > Browse to live backup folder
# 3. View > Compare to see all differences highlighted
# From command line, export the policy set to XML for scripted diffing:
$policyAnalyzerExe = 'C:SCTWindowsServer2025ToolsPolicyAnalyzerPolicyAnalyzer.exe'
Start-Process $policyAnalyzerExe
Step 6: Create an Exceptions GPO to Override Specific Settings
Some baseline settings will conflict with legitimate business requirements. The correct pattern is to create a separate higher-precedence GPO that overrides only the specific conflicting settings, leaving the baseline GPO untouched and upgradeable:
# Create the exceptions GPO
$exceptionsGpoName = 'WS2025 Baseline Exceptions — AppTeam'
New-GPO -Name $exceptionsGpoName -Domain $domainName `
-Comment 'Targeted overrides to Microsoft WS2025 baseline'
# Example: re-enable a specific logon right that the baseline removed
# Use Set-GPRegistryValue for registry-based policy settings
Set-GPRegistryValue -Name $exceptionsGpoName `
-Key 'HKLMSOFTWAREMicrosoftWindows NTCurrentVersionWinlogon' `
-ValueName 'CachedLogonsCount' `
-Type DWord `
-Value 2
# Link the exceptions GPO to the same OU with a lower order number (higher precedence)
# so it wins over the baseline GPO when both are linked
New-GPLink -Name $exceptionsGpoName -Target $testOuDN -LinkEnabled Yes -Order 1
# Move baseline GPO to order 2
Set-GPLink -Name $gpoName -Target $testOuDN -Order 2
Write-Host "Exceptions GPO linked at higher precedence than baseline"
Step 7: Promote to Production and Document
Once testing is complete, link the baseline and exceptions GPOs to your production server OUs. Use Get-GPInheritance to audit the final link order and document the rationale for every exception in the GPO comment field:
$prodOuDN = 'OU=MemberServers,OU=Servers,DC=contoso,DC=com'
New-GPLink -Name $exceptionsGpoName -Target $prodOuDN -LinkEnabled Yes -Order 1
New-GPLink -Name $gpoName -Target $prodOuDN -LinkEnabled Yes -Order 2
# Audit final inheritance chain
Get-GPInheritance -Target $prodOuDN | Select-Object -ExpandProperty GpoLinks |
Sort-Object Order |
Format-Table Order, DisplayName, Enabled, Enforced -AutoSize
Security baselines are living documents. Microsoft releases updated SCT packages with every major Windows Server servicing update, and the delta between versions is typically small but security-critical. Establish a quarterly review cycle: download the latest SCT, run Policy Analyzer against your current production baseline GPO, evaluate each changed setting against your risk register, and update the baseline GPO in a test OU before promoting. This disciplined process keeps your environment aligned with Microsoft’s threat-informed recommendations without disrupting business operations.