In this blog, we’ll break down Desired State Configuration (DSC). What it is, why it still matters, and why Microsoft didn’t just update it, but rebuilt it entirely in DSCv3.

Introduction to Desired State Configuration

Microsoft’s PowerShell Desired State Configuration (DSC) has been part of the Windows configuration management ecosystem since PowerShell 4.0. Introduced in 2013, it allowed administrators to define infrastructure as code and enforce configuration over time. Instead of scripting every action, you described what the system should look like, the “desired state,” and DSC handled the rest.

That PowerShell Desired State Configuration model worked well for its time, but infrastructure practices didn’t stand still. As demand for cross-platform support increased and infrastructure as code matured, teams began favoring Git-backed CI/CD pipelines over traditional agent-based management models. Managing configuration through background agents like LCM or legacy tech like WMI/WinRM no longer fits the model. Microsoft responded by redesigning PowerShell Desired State Configuration from the ground up, driven by the limitations of the original Windows-only architecture and the need to support modern, cross-platform development workflows.

And yet… MOF isn’t gone. While one team removed it entirely, another brought it back. Intune’s MMP-C stack utilizes MOF fragments internally through WinDC, its cloud-based policy engine. Therefore, you may now write YAML for DSC v3, but still end up dealing with MOF-based enforcement on managed endpoints.

This article guides you through the changes, explains why they matter, and helps you determine when and if to migrate to Desired State Configuration v3.

What Desired State Configuration v2 Looked Like

Before diving into DSC v3, it’s worth understanding how PowerShell DSC v2 worked and why it eventually became a limiting model.

PowerShell Desired State Configuration (DSC) v2 was built around the Local Configuration Manager (LCM). This engine ran on each node and was responsible for applying and enforcing its configuration. It worked by checking the system at regular intervals, reading its current state using Get-TargetResource, comparing it to the desired state using Test-TargetResource, and correcting it if needed using Set-TargetResource.

Desired State Configuration v2

This get-test-set workflow defined how DSC enforced configuration, but it also introduced complexity. Writing resources meant dealing with schema.mof files, strict function definitions, and deep PowerShell knowledge. Cross-platform support was non-existent, and even supporting new Windows scenarios often required significant effort.

To define configuration, we needed to write .ps1 scripts using a special declarative syntax. These were compiled into MOF files and either pushed to the node or pulled from a central server. Everything relied on PowerShell 5, WMI, and WinRM, all delivered through the Windows Management Framework (WMF).

But as infrastructure and development practices evolved, this model became harder to maintain. The LCM engine was deeply tied to Windows-only technologies and could not be easily extended or integrated into modern toolchains. Rather than trying to retrofit those limitations, Microsoft chose to redesign DSC entirely, resulting in DSC v3.

Why Microsoft Rebuilt Desired State Configuration v3

Rather than evolving the existing Desired State Configuration engine, Microsoft decided to start fresh. The original implementation was tied closely to Windows internals like WMI, WinRM, and the .NET Framework. These dependencies made it increasingly challenging to modernize or extend beyond the Windows ecosystem.

Desired State Configuration v3 takes a different approach. It introduces a lightweight CLI tool called dsc.exe, written in Rust, that runs across Windows, Linux, and macOS. It doesn’t rely on MOF files, background services, or Windows Management Framework components. Instead, it applies declarative configuration files, which are written in YAML or JSON, when explicitly invoked.

This design trades in automatic enforcement for portability and simplicity. Features previously handled by the Local Configuration Manager (LCM), like drift correction, versioned pull servers, consistency checks, and reporting, are no longer part of the product. If you need those capabilities, you’re expected to build them yourself using CI/CD, cron jobs, or scheduled tasks.

Desired State Configuration v3 isn’t trying to replace everything Desired State Configuration v2 did. It focuses on applying configuration, not managing it continuously. That shift means less overhead, fewer assumptions, and a better fit for environments that already rely on pipelines to control deployment timing.

How to Install Desired State Configuration v3

DSC v3 is distributed as a standalone CLI tool called dsc.exe. There’s no agent or service. Just download and run it. On Windows, you can install it using Winget:

winget install Microsoft.DSC

⚠️ Note: DSC v3 requires PowerShell 7.2 or later to run PowerShell-based adapters. Since Windows Server 2025 still ships with Windows PowerShell 5.1, you’ll need to install PowerShell 7.x separately. You can do that manually, or from an elevated PowerShell prompt using:

winget install –id Microsoft.PowerShell –source winget

On Linux or macOS, download the latest release from GitHub:

👉 https://github.com/PowerShell/DSC/releases

Extract the binary, place it in your PATH, and you’re ready to go.

DSC v3: Example YAML Configuration

Below is a basic example of a DSC v3 configuration that ensures a specific registry key is present. This could be used to enforce a group policy setting or reapply a compliance rule at runtime.

# yaml-language-server: $schema=https://aka.ms/dsc/schemas/v3/bundled/config/document.vscode.json
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json

resources:
  - name: Ensure PatchMyPC Key
    type: Microsoft.Windows/Registry
    properties:
      _exist: true
      keyPath: HKLM\SOFTWARE\Patch My PC

  - name: Ensure DesiredStateTest Value
    type: Microsoft.Windows/Registry
    properties:
      _exist: true
      keyPath: HKLM\SOFTWARE\Patch My PC
      valueName: DesiredStateTest
      valueData:
        DWord: 1

This configuration ensures that the DesiredStateTest registry value exists under the specified key with the correct data and type. If someone changes or deletes the value, DSC can detect the drift when tested

Once tested, you can (re)apply the desired state manually using dsc config set.

running desired state configuration dsc config set  and specifying the yaml file

Note: DSC v3 does not utilize a background service or Local Configuration Manager (LCM), unlike previous versions of DSC. It won’t monitor or reapply the configuration automatically. You must trigger it explicitly using a script, scheduled task, or CI/CD pipeline.

Orchestration and Drift Detection with DSC

In DSC v2, the Local Configuration Manager enforced configuration automatically in the background. It handled periodic checks, re-applied settings when drift was detected, and operated under the SYSTEM context by default.

DSC v3 does not include any of this functionality. There is no built-in timer, no polling mechanism, and no background service. Configuration is only applied when explicitly executed. This gives administrators full control over when and how DSC runs, but it also means you are responsible for ensuring enforcement happens when needed.

To apply or test a configuration with DSC v3, you invoke the CLI directly:

dsc config test --file config.yaml
dsc config set --file config.yaml

If you need continuous enforcement or scheduled reapplication, you must implement that using one of the following methods:

  • CI/CD pipelines – Integrate DSC execution into GitHub Actions, Azure DevOps, or GitLab pipelines
  • Scheduled tasks – Use Windows Task Scheduler or cron on Linux or macOS
  • Custom agents or services – Build lightweight daemons that mimic LCM-like behavior

It’s also important to remember that dsc.exe runs in the user context. If your configuration requires elevated access (such as writing to HKLM or Program Files), it must be executed with administrative privileges.

If you previously relied on LCM for enforcement, drift correction, and SYSTEM-level execution, you will now need to rebuild those pieces manually. DSC v3 assumes that orchestration is handled externally, and that approach aligns with modern infrastructure practices based on pipelines and automation.

How the Adapter Model Works

DSC v3 removes the use of PowerShell classes and MOF schemas and introduces an adapter model. Each resource consists of a .dsc.resource.json manifest and one or more scripts or binaries that implement three required operations: Get, Test, and Set. These are called by the DSC engine, which passes input and output as structured JSON over standard input and output.

Here’s a simple example of a PowerShell-based adapter manifest:

{ "name": "MyCompany/File", "entryPoint": "./file.resource.ps1", "type": "script", "operations": ["Get", "Test", "Set"] }

When dsc.exe runs, it reads this manifest, calls the adapter’s entry point, and passes input and output as JSON.

Adapters can be:

  • PowerShell scripts (using pwsh)
  • Bash scripts
  • Compiled CLI tools (like Go or Rust binaries)

The adapter model is flexible, but not necessarily simple. You are responsible for maintaining strict structure and idempotent behavior. Each adapter must correctly separate the logic for reading, testing, and applying configuration, and must adhere to the JSON schema expected by the DSC engine.

Existing DSC v2 resources can still be reused if wrapped inside a proper adapter. There is no automatic compatibility. You must build the bridge script to expose the required operations in the correct format.

To confirm your adapters are registered and available to the DSC engine, use:

dsc resource list

And Yet Microsoft Is Using MOF Again

Although DSC v3 no longer uses MOF files, Microsoft’s other systems, like Intune’s (using WinDC), still depend on MOF fragments for policy enforcement. The MMP-C stack processes partial MOF content behind the scenes as part of its device configuration engine.

This means that while you may define configuration using YAML in DSC v3 for your servers, MOF-based logic may still apply on managed endpoints via Intune.

Let’s take a closer look at the feature comparison table before considering when and how to migrate from PowerShell DSC v2 to DSC v3

Feature Comparison Table

FeatureDSC v2DSC v3 (Rust CLI)
Runtime EnginePowerShell with LCMRust CLI (dsc.exe)
State MethodsGet / Test / SetAdapter-driven Get/Test/Set
Config Format.ps1 to MOFYAML or JSON
Shell or Language SupportPowerShell 5 onlyPowerShell, Bash, Python, Go
Enforcement ModelLCM background agentOrchestration by CI/CD or cron
ContextSYSTEMUserland (unless elevated)
Pull Server SupportYes (with versioning)No
Export or Reverse ConfigScripting onlyBuilt-in (planned)
Assertions / Conditional LogicScript-basedNative assertion resource
Data Flow FunctionsManual parsingBuilt-in cross-resource logic
GitOps IntegrationManualCompatible with CI/CD

Migration Guide for Desired State Configuration v3

DSC v3 isn’t a drop-in upgrade, it’s a complete re-architecture. Migration is possible, but it comes with tradeoffs. You should consider moving to DSC v3 if:

  • You need to manage both Windows and Linux systems using a single tool
  • You want to adopt GitOps-style workflows and integrate configuration into your CI/CD pipelines
  • You prefer YAML or JSON over MOF and want to avoid the Windows Management Framework
  • You’re eliminating legacy dependencies like WinRM or LCM

What to Expect

  • DSC v3 removes built-in enforcement, drift correction, pull servers, and version tracking.
  • There is no SYSTEM-level agent. Configuration is only applied when you explicitly run it.
  • Orchestration, scheduling, and reporting are now your responsibility.

Migration Steps

  1. Rebuild Resources
    Replace class-based PowerShell Desired State Configuration v2 resources with adapter-based implementations using the Get, Test, and Set model. You’ll still need to structure logic carefully and ensure idempotency, which hasn’t changed.
  2. Convert Configuration
    Convert .ps1 and MOF-based configurations into YAML or JSON.. There’s no compiler, you author and run configuration files directly.
  3. Implement Orchestration
    Replace the pull server model with pipelines, scheduled tasks, or service wrappers. DSC v3 provides no scheduling or versioning.
  4. Wrap Existing Logic
    PowerShell DSC-based logic from v2 can be reused, but only if wrapped in a proper adapter. There’s no automatic compatibility.

Proceed Gradually

You can run DSC v2 and v3 side-by-side. For example:

  • Continue using LCM for existing nodes
  • Use DSC v3 for new workloads that fit into GitOps or CI/CD pipelines
  • Migrate resources and nodes incrementally

Not for Everyone

DSC v3 is better suited for environments where you control your orchestration and are prepared to handle scheduling, drift detection, and reporting externally. If your workflow depends on built-in compliance tracking, automatic correction, or deeply integrated PowerShell modules, tools like Ansible or Chef may offer more out-of-the-box functionality.

Final Thoughts

DSC v3 drops the agent model and leaves configuration enforcement up to you. There’s no automatic drift correction; you decide when and how the desired state gets applied.

But drift still matters. Even with DSC handling the system layer, keeping applications up to date is just as critical. That’s where Patch My PC helps, ensuring software stays in a known, supported state across your devices.