How to Use PowerShell DSC (Desired State Configuration) on Windows Server 2025
PowerShell Desired State Configuration (DSC) is a declarative management framework built into Windows Server 2025 that lets you define the intended configuration of a server — installed features, running services, registry values, file contents, and more — and then continuously enforce that state. Rather than writing imperative scripts that perform actions step by step, DSC lets you describe what a server should look like and lets the engine figure out how to get there. This is particularly valuable in large-scale server environments where configuration drift is a constant operational risk. This guide covers writing your first DSC configuration, compiling it to a MOF file, applying it in push mode, testing compliance, using built-in and community resources, and an introduction to pull server architecture.
Prerequisites
- Windows Server 2025 with PowerShell 5.1 or PowerShell 7.x
- WinRM enabled (required for push-mode delivery to remote nodes)
- Administrator privileges on target nodes
- Internet access or internal PSGallery mirror for installing community DSC resources
- Basic familiarity with PowerShell syntax
Step 1: Understand Push vs Pull Mode
DSC operates in two fundamental delivery modes. In push mode, an administrator compiles a configuration and manually pushes it to target nodes using Start-DscConfiguration. This is simpler to set up and suitable for smaller environments or initial deployments. In pull mode, target nodes are configured to periodically contact a central DSC pull server over HTTPS and retrieve their assigned configurations automatically — enabling consistent, unattended configuration enforcement across hundreds of servers.
# Check current DSC Local Configuration Manager (LCM) settings on a node
Get-DscLocalConfigurationManager
# Key LCM properties:
# ConfigurationMode: ApplyOnly | ApplyAndMonitor | ApplyAndAutoCorrect
# RefreshMode: Push | Pull
# RefreshFrequencyMins: how often pull clients check for new config (default 30)
# RebootNodeIfNeeded: $true | $false
# ApplyAndAutoCorrect is the most powerful mode — it continuously corrects drift
Step 2: Write Your First DSC Configuration
A DSC configuration is a PowerShell script block using the Configuration keyword. Inside, you declare Node blocks targeting specific machines, and within each node you use DSC resources — named blocks that describe a desired state for one specific aspect of the system.
# Save as: C:DSCWebServerConfig.ps1
Configuration WebServerConfig {
# Import required DSC resource modules
Import-DscResource -ModuleName PSDesiredStateConfiguration
# Target node — use 'localhost' for the local machine
Node 'localhost' {
# Ensure IIS is installed
WindowsFeature IIS {
Name = "Web-Server"
Ensure = "Present"
}
# Ensure IIS Management Console is installed
WindowsFeature IISManagementConsole {
Name = "Web-Mgmt-Console"
Ensure = "Present"
DependsOn = "[WindowsFeature]IIS"
}
# Ensure the W3SVC service is running
Service W3SVC {
Name = "W3SVC"
State = "Running"
DependsOn = "[WindowsFeature]IIS"
}
# Ensure a web root directory exists
File WebRoot {
DestinationPath = "C:inetpubwwwrootapp"
Type = "Directory"
Ensure = "Present"
}
# Ensure a specific registry value is set
Registry DisableSSL3 {
Key = "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsSSL 3.0Server"
ValueName = "Enabled"
ValueData = "0"
ValueType = "Dword"
Ensure = "Present"
}
}
}
Step 3: Compile the Configuration to a MOF File
DSC configurations are not executed directly. They must first be compiled into a Managed Object Format (MOF) file — a standard configuration document that the DSC engine can interpret. Compiling is done by dot-sourcing the configuration script and then calling it like a function.
# Dot-source the configuration file to load it into the session
. "C:DSCWebServerConfig.ps1"
# Compile the configuration — this creates a MOF file in a subfolder
# named after the configuration function
WebServerConfig -OutputPath "C:DSCWebServerConfig"
# Verify the MOF was created
Get-ChildItem "C:DSCWebServerConfig"
# Should show: localhost.mof
# Inspect the MOF file (plain text — readable)
Get-Content "C:DSCWebServerConfiglocalhost.mof"
Step 4: Apply the Configuration with Start-DscConfiguration
With the MOF compiled, use Start-DscConfiguration to apply it. The -Wait flag makes the command synchronous (it blocks until completion); -Verbose shows detailed progress including which resources are being tested and applied.
# Apply configuration to the local machine
Start-DscConfiguration -Path "C:DSCWebServerConfig" -Wait -Verbose -Force
# Apply to a remote server (push mode)
Start-DscConfiguration -Path "C:DSCWebServerConfig" `
-ComputerName "WEB01" `
-Credential (Get-Credential) `
-Wait -Verbose -Force
# Apply to multiple servers simultaneously
$servers = @("WEB01", "WEB02", "WEB03")
Start-DscConfiguration -Path "C:DSCWebServerConfig" `
-ComputerName $servers `
-Credential (Get-Credential) `
-JobName "WebServerDSC"
# Check background job status
Get-Job -Name "WebServerDSC"
Receive-Job -Name "WebServerDSC" -Wait
Step 5: Test and Get Current Configuration State
Test-DscConfiguration compares the current system state against the last applied configuration and returns True if compliant or False if drift has occurred. Get-DscConfiguration returns the current values of all DSC-managed resources.
# Test whether the current state matches the desired configuration
Test-DscConfiguration -Verbose
# Returns: True (compliant) or False (drift detected)
# Get detailed compliance report showing which resources are in/out of compliance
Test-DscConfiguration -Detailed | Select-Object -ExpandProperty ResourcesNotInDesiredState
# Get the currently applied configuration values
Get-DscConfiguration
# Get DSC configuration status history
Get-DscConfigurationStatus
# Get last 5 configuration runs with success/failure
Get-DscConfigurationStatus -All | Select-Object -First 5 | Format-Table StartDate, Type, Status, Error -AutoSize
Step 6: Use Built-In DSC Resources
The PSDesiredStateConfiguration module ships with Windows Server 2025 and includes a core set of built-in resources covering the most common configuration needs.
# List all available built-in DSC resources
Get-DscResource -Module PSDesiredStateConfiguration
# KEY BUILT-IN RESOURCES:
# WindowsFeature - Install/remove Windows roles and features
# File - Manage files and directories
# Service - Control Windows services (state, startupType)
# Registry - Manage registry keys and values
# User - Manage local user accounts
# Group - Manage local group membership
# Environment - Manage environment variables
# Script - Run arbitrary PowerShell as a resource (GetScript/SetScript/TestScript)
# Package - Install/remove MSI packages
# Example: User resource
Configuration LocalAdminSetup {
Import-DscResource -ModuleName PSDesiredStateConfiguration
Node 'localhost' {
User MonitoringAccount {
UserName = "svc_monitor"
FullName = "Monitoring Service Account"
Description = "Used by monitoring tools"
Ensure = "Present"
Password = (New-Object PSCredential "svc_monitor", (ConvertTo-SecureString "P@ssw0rd2025!" -AsPlainText -Force))
PasswordNeverExpires = $true
}
Group MonitoringGroup {
GroupName = "Monitoring"
Ensure = "Present"
MembersToInclude = @("svc_monitor")
DependsOn = "[User]MonitoringAccount"
}
}
}
Step 7: Install and Use Community DSC Resources
The PowerShell Gallery hosts a rich ecosystem of community DSC resource modules that extend DSC to cover SQL Server, DNS, DHCP, networking, certificates, and much more. The most commonly used modules are maintained by Microsoft’s DSC community team.
# Install the core community DSC resource pack
Install-Module -Name PSDesiredStateConfiguration -Force -AllowClobber
Install-Module -Name ComputerManagementDsc -Force
Install-Module -Name NetworkingDsc -Force
Install-Module -Name SqlServerDsc -Force
Install-Module -Name CertificateDsc -Force
Install-Module -Name xDnsServer -Force
# List all installed DSC resource modules
Get-InstalledModule | Where-Object { $_.Name -like "*Dsc*" }
# Example using ComputerManagementDsc to set timezone and power plan
Configuration ServerBaseline {
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName ComputerManagementDsc
Node 'localhost' {
TimeZone SetTimezone {
IsSingleInstance = "Yes"
TimeZone = "UTC"
}
PowerPlan SetHighPerf {
IsSingleInstance = "Yes"
Name = "High Performance"
}
WindowsEventLog SystemLog {
LogName = "System"
IsEnabled = $true
LogMode = "Circular"
MaximumSizeInBytes = 524288000 # 500 MB
}
}
}
Step 8: DSC Pull Server Basics
For environments with many servers, a DSC pull server allows nodes to self-manage their configuration by periodically fetching MOF files and required resource modules from a central HTTPS endpoint. Windows Server 2025 supports both SMB and HTTPS pull servers.
# Install the DSC Service feature on the pull server
Install-Module -Name xPSDesiredStateConfiguration -Force
Install-WindowsFeature -Name DSC-Service
# Configure a basic HTTPS pull server (run on the pull server)
Configuration PullServer {
Import-DscResource -ModuleName xPSDesiredStateConfiguration
Node 'localhost' {
xDscWebService PullServerEP {
EndpointName = "DSCPullServer"
Port = 8080
PhysicalPath = "$env:SystemDriveinetpubDSCPullServer"
CertificateThumbPrint = "AllowUnencryptedTraffic" # Use real cert in production
ModulePath = "$env:SystemDriveProgram FilesWindowsPowerShellDscServiceModules"
ConfigurationPath = "$env:SystemDriveProgram FilesWindowsPowerShellDscServiceConfiguration"
State = "Started"
Ensure = "Present"
}
}
}
# On each client node, configure the LCM to use the pull server
[DSCLocalConfigurationManager()]
Configuration LCMPullConfig {
Node 'localhost' {
Settings {
RefreshMode = "Pull"
ConfigurationMode = "ApplyAndAutoCorrect"
RebootNodeIfNeeded = $true
RefreshFrequencyMins = 30
}
ConfigurationRepositoryWeb PullServerConnection {
ServerURL = "http://dscpullserver:8080/PSDSCPullServer.svc"
RegistrationKey = "YOUR-GUID-REGISTRATION-KEY-HERE"
ConfigurationNames = @("WebServerConfig")
}
}
}
# Compile and apply LCM config
LCMPullConfig -OutputPath "C:DSCLCMConfig"
Set-DscLocalConfigurationManager -Path "C:DSCLCMConfig" -Verbose
Conclusion
PowerShell Desired State Configuration on Windows Server 2025 gives operations teams a principled, repeatable approach to server configuration management. By writing declarative configurations instead of imperative scripts, you gain built-in idempotency — running a DSC configuration multiple times produces the same result without unintended side effects. Starting with push mode and the built-in PSDesiredStateConfiguration resources is the quickest path to value, while the rich community resource ecosystem on PSGallery extends DSC to cover virtually any server role. As your fleet grows, graduating to a pull server architecture with ApplyAndAutoCorrect mode provides continuous, automated compliance enforcement with no manual intervention required.