Configuration drift: OSConfig, DSC and compliance reports
Detect and correct Windows configuration drift: OSConfig on Server 2025, PowerShell DSC auto-correct, Group Policy reprocessing, change events and reports.
Applying a baseline is a moment in time. After that, software installers relax settings they don't like, administrators make "temporary" changes during an incident, scripts from a vendor flip a registry value, and a GPO gets unlinked during a reorganisation. Six months later, the machine no longer matches the baseline you showed the auditor. That gap is configuration drift.
The security baselines pillar introduced OSConfig as one way to keep a baseline in place. This guide covers drift as a whole: the correction engines available on Windows (OSConfig, Group Policy, PowerShell DSC, Intune), how to detect changes as they happen, and how to report compliance across a fleet.
Where drift comes from and what corrects it
| Engine | Scope | Corrects drift | Reports compliance |
|---|---|---|---|
| Group Policy | Domain-joined clients and servers | Security settings every 16 hours; registry policy only when GPOs change, unless configured | No (use Policy Analyzer or RSoP) |
| Intune (Policy CSP) | MDM-enrolled devices | Re-applies on device check-in | Yes, per setting |
| OSConfig | Windows Server 2025 | Yes, drift control on a schedule | Yes, per setting |
| PowerShell DSC (LCM) | Any Windows with Windows PowerShell 5.1 | Yes, with ApplyAndAutoCorrect | Yes, Test-DscConfiguration |
Each device class should have exactly one engine that owns its security configuration, plus independent reporting to catch the cases where the engine itself is broken or bypassed.
Step 1: make Group Policy re-apply what it owns
If Group Policy owns the configuration, close the reprocessing gap. Under Computer Configuration > Policies > Administrative Templates > System > Group Policy:
- Configure registry policy processing: Enabled, tick Process even if the Group Policy objects have not changed.
- Configure security policy processing: Enabled, same option.
With these, a local change to an Administrative Template setting is overwritten at the next background refresh (90 minutes plus a random offset by default) instead of surviving until someone edits the GPO. The Microsoft baseline enables registry policy reprocessing already; confirm it hasn't been removed.
This doesn't help with settings no GPO defines, with machines outside the domain, or with GPOs that stop applying. That's what reporting is for.
Step 2: OSConfig on Windows Server 2025
OSConfig applies Microsoft's security baselines for Windows Server 2025 as named scenarios, then enforces and reports them. Install the module from the PowerShell Gallery and apply the scenario that matches the server's role:
Install-Module -Name Microsoft.OSConfig -Scope AllUsers -Repository PSGallery -Force
# One of: SecurityBaseline/WindowsServer/2025/MemberServer, /DomainController, /WorkgroupMember
Set-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer -Default
Restart-ComputerCompanion scenarios apply the same way: SecuredCore, Defender/Antivirus/WindowsServer/2025 and, on member servers only, LAPS/WindowsServer/2025/MemberServer. OSConfig also has a scenario for App Control for Business. Applying or removing a baseline needs a restart. The baseline version ships inside the module, so Update-Module Microsoft.OSConfig followed by reapplying the scenario moves a server to the new baseline.
To change one setting from the default, for example to match an entry in your deviation register, set it by name rather than editing the registry, so drift control enforces your value rather than fighting it:
Get-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer |
Where-Object Name -like '*Audit*' | Select-Object Name, Value
Set-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer `
-Setting AuditDetailedFileShare -Value 3Check a single customised value with Get-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer -Setting AuditDetailedFileShare.
Drift control runs as a scheduled refresh task that compares each setting with the desired value and resets it if it changed. Current Microsoft documentation doesn't state the interval (earlier versions gave four hours), so measure it in your pilot rather than assuming it. Removing a scenario with Remove-OSConfigDesiredConfiguration stops enforcement, and Microsoft states it can't guarantee that settings return to their pre-baseline values, so take a snapshot of the original configuration first on servers where you may need to roll back.
On domain-joined servers, decide who owns the baseline. If your domain GPOs apply the same Microsoft baseline, avoid enforcing it twice: either keep GPOs and use OSConfig reporting only on a sample, or move the baseline to OSConfig and strip those settings from the server GPOs. Domain controllers deserve extra care since a conflicting user rights assignment can break replication or logons; pilot on one DC first.
Step 3: PowerShell DSC for everything else
For settings that no baseline covers, or for older servers, Windows PowerShell 5.1's Desired State Configuration can enforce and report. Configure the Local Configuration Manager (LCM) to auto-correct:
[DSCLocalConfigurationManager()]
configuration LcmAutoCorrect {
Node localhost {
Settings {
RefreshMode = 'Push'
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationModeFrequencyMins = 30
}
}
}
LcmAutoCorrect -OutputPath C:\DSC\Lcm
Set-DscLocalConfigurationManager -Path C:\DSC\Lcm -VerboseThen a configuration with the settings you own. The built-in Registry resource is enough for many hardening values:
configuration HardeningExtras {
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node localhost {
Registry DisableLLMNR {
Key = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient'
ValueName = 'EnableMulticast'
ValueData = '0'
ValueType = 'Dword'
Ensure = 'Present'
}
}
}
HardeningExtras -OutputPath C:\DSC\Hardening
Start-DscConfiguration -Path C:\DSC\Hardening -Wait -VerboseCommunity modules such as SecurityPolicyDsc and AuditPolicyDsc cover user rights, security options and audit subcategories, and the BaselineManagement module can convert a GPO backup into a DSC configuration. Newer Microsoft DSC (version 3) is a separate, cross-platform tool with a different model; evaluate it separately rather than mixing it with the LCM.
The DSC configuration files (.mof) can contain sensitive data and the LCM runs as SYSTEM, so store them in a protected location and restrict who can push configurations, just as you would restrict GPO editing (see admin tiering).
Step 4: detect changes as they happen
Correction engines hide drift by fixing it. You also want to know it happened, because a setting that keeps flipping back usually means someone or something is working against you. Enable the relevant audit subcategories (see audit policy and Sysmon) and forward these events:
| Event | Log | Meaning |
|---|---|---|
| 4719 | Security | System audit policy was changed |
| 4739 | Security (DCs) | Domain policy was changed (password, lockout, Kerberos) |
| 5136 | Security (DCs) | Directory object modified, including GPO objects and links (needs Audit Directory Service Changes and SACLs) |
| 4657 | Security | Registry value modified, for keys with an auditing SACL |
| 4670 | Security | Permissions on an object changed |
For a few high-value registry keys (for example LSA settings under HKLM\SYSTEM\CurrentControlSet\Control\Lsa), add an auditing SACL so 4657 fires on change. Sysmon event 13 (registry value set) with a targeted configuration is an alternative. Forward everything with Windows Event Forwarding to your SIEM, and alert on changes outside change windows.
Step 5: report compliance across the fleet
Enforcement tells each machine what to do; reporting tells you whether it worked. For Windows Server 2025 with OSConfig, collect per-setting compliance remotely:
$servers = Get-Content C:\Reports\ws2025-servers.txt
Invoke-Command -ComputerName $servers -ScriptBlock {
Get-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer |
Select-Object Name,
@{n='Status';e={$_.Compliance.Status}},
@{n='Reason';e={$_.Compliance.Reason}}
} | Select-Object PSComputerName, Name, Status, Reason |
Export-Csv "C:\Reports\osconfig-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformationFor DSC-managed nodes, Test-DscConfiguration -Detailed returns resources in and out of desired state, and Get-DscConfigurationStatus shows the last run. Local audit tools such as secedit /analyze /db C:\Temp\bl.sdb /cfg C:\Baseline\GptTmpl.inf /log C:\Temp\analyze.log compare security settings with a template. Policy Analyzer's effective-state comparison (see Policy Analyzer and LGPO) covers sampled clients. At scale, Intune per-setting reports, Azure machine configuration for Arc-connected servers, and Defender Vulnerability Management's security baselines assessment (licensing dependent) give a central view.
Track three numbers per device class: percentage of settings compliant, number of devices with any non-compliant high-risk setting, and settings that drift repeatedly.
Verify it
Prove the correction loop works on a pilot server: change one enforced setting by hand, wait for the next refresh, and confirm it's back.
Get-OSConfigDesiredConfiguration -Scenario SecurityBaseline/WindowsServer/2025/MemberServer |
Where-Object { $_.Compliance.Status -ne 'Compliant' } |
Format-Table Name, @{n='Reason';e={$_.Compliance.Reason}} -Wrap
Test-DscConfiguration -Detailed | Select-Object -ExpandProperty ResourcesNotInDesiredState
Get-WinEvent -LogName 'Microsoft-Windows-DSC/Operational' -MaxEvents 20Confirm the change event reached your SIEM too. A drift correction that nobody saw is still a signal you missed.
What breaks
- Two engines, one setting. GPO and OSConfig, or Intune and DSC, enforcing different values produce flapping settings and confusing reports.
- Legitimate changes reverted. An emergency fix made by hand is undone at the next refresh. Make changes through the engine, not around it.
- Baseline exceptions lost. Customisations applied outside the engine disappear. Record them in the engine's configuration and in the deviation register.
- Stale reports. A device that stopped reporting looks compliant in some dashboards. Alert on missing reports, not only on failures.
Checklist
- One enforcement engine chosen per device class
- Group Policy registry and security processing set to reapply unchanged GPOs
- OSConfig baseline scenario applied on Windows Server 2025 by role
- Deviations applied through OSConfig or DSC, not by hand
- DSC LCM in
ApplyAndAutoCorrectfor settings outside the baseline - Change events (4719, 4739, 5136, 4657) forwarded and alerted
- Fleet compliance report produced and reviewed monthly
- Correction loop tested by deliberately changing a setting
Drift management is what keeps a baseline true after the project ends. See the full security baselines area for choosing, testing and deploying baselines in the first place.
Frequently asked questions
What is OSConfig?
OSConfig is a security configuration stack for Windows Server 2025, managed through the Microsoft.OSConfig PowerShell module and also used by Windows Admin Center and Azure Arc. It applies Microsoft security baselines as scenarios, reports compliance per setting and runs drift control, periodically putting changed settings back to the desired value.
Should I use OSConfig on domain-joined servers that already get baseline GPOs?
Pick one authority per setting. If domain GPOs apply the baseline, use OSConfig or Policy Analyzer only to report, or let OSConfig own the baseline and remove the overlapping GPO settings. Two engines enforcing different values for the same setting will overwrite each other on every refresh, and the result depends on timing.
Does Group Policy correct drift on its own?
Partly. Security settings are reapplied every 16 hours even when GPOs haven't changed, but registry-based Administrative Template settings are only reprocessed when a GPO changes unless you enable Process even if the Group Policy objects have not changed. Local changes to those settings can persist until the next GPO modification.
Configuration drift: OSConfig, DSC and compliance reports