Map LCM features to Microsoft DSC
During migration planning, someone will ask about every single LCM setting. Here's the complete mapping in one place, so the answer is a row in a table rather than a research task.
| LCM feature | Microsoft DSC equivalent |
|---|---|
ApplyOnly mode |
Run dsc config set once (from a pipeline, script, or by hand) |
ApplyAndMonitor mode |
Schedule dsc config test and alert on drift; nothing auto-corrects |
ApplyAndAutoCorrect mode |
Schedule dsc config set; each run converges the machine |
ConfigurationModeFrequencyMins |
The schedule you define in Task Scheduler, cron, or your orchestrator |
RefreshMode = 'Pull' + pull server |
A higher-order tool such as OpenDSC |
RebootNodeIfNeeded |
The restartRequired() function and restart metadata; the caller decides to reboot |
PartialConfigurations |
Microsoft.DSC/Include composing multiple documents |
Cross-node WaitFor* resources |
No equivalent by design; cross-node coordination belongs to your orchestration layer |
PSDscAllowPlainTextPassword |
Gone, and good riddance: secureString parameters and the secret() function |
| MOF encryption certificates | Not needed; documents hold no secrets when parameterized correctly |
DscLocalConfigurationManager state |
Nothing; the engine is stateless, results are returned to the caller |
Read the table as three groups
The rows aren't equivalent in kind. They fall into three groups, and conflating them is what makes migration planning meetings run long.
Group 1: Direct substitutions
ApplyOnly, ApplyAndMonitor, ApplyAndAutoCorrect, and ConfigurationModeFrequencyMins all reduce to "which command, how often." There's no conceptual gap here — only a decision about where the schedule lives, which unit 3 covers.
PartialConfigurations is also a direct substitution. What the LCM assembled from multiple sources, Microsoft.DSC/Include composes explicitly in a document:
resources:
- name: Baseline
type: Microsoft.DSC/Include
properties:
configurationFile: ./baseline.dsc.config.yaml
- name: WebRole
type: Microsoft.DSC/Include
properties:
configurationFile: ./webserver-adapted.dsc.config.yaml
The difference is visibility. Partial configurations arrived from wherever the LCM was told to look, and reconstructing what a node actually ran meant querying the node. An Include is a line in a file you can read in a pull request.
Group 2: Responsibilities that moved to you
RefreshMode = 'Pull' and RebootNodeIfNeeded didn't disappear — they moved out of the engine.
Pull mode needs a higher-order tool. Today, that's OpenDSC, a community project that acts as the enforcement and orchestration layer above the engine: nodes register, receive configurations, report results.
[!IMPORTANT]
OpenDSC is community-driven open source and isn't officially supported by Microsoft. If your organization requires vendor support for the enforcement layer, decide that before decommissioning a pull server.
Reboot policy moved to the caller, which unit 4 covers in detail.
Group 3: Things that were cut, not moved
Cross-node WaitFor* resources have no equivalent, deliberately. So does LCM state.
This is the group that surprises people, because the honest answer is "that feature is gone and you need to redesign around it." Unit 4 covers what to do instead.
Three rows that change who is responsible
Three of these deserve more than a table row, because they change accountability rather than syntax:
Scheduled enforcement is now yours to own. The LCM's consistency check ran every 15 minutes whether you thought about it or not. In Microsoft DSC, if nothing invokes the engine, nothing happens. → Unit 3.
Reboots became explicit. The LCM would reboot a node mid-run when a resource requested it and RebootNodeIfNeeded was set. Microsoft DSC will never reboot anything on its own. → Unit 4.
Cross-node coordination was cut, not misplaced. WaitForAll and its siblings let one node's LCM block on another node's state. Nothing replaces this. → Unit 4.
Audit your meta-configuration
Before you decide what to replace, find out what you actually configured. On any managed node:
Get-DscLocalConfigurationManager
Record these properties for each node class in your estate:
| Property | What to record | Why it matters |
|---|---|---|
ConfigurationMode |
ApplyOnly, ApplyAndMonitor, or ApplyAndAutoCorrect |
Determines whether your replacement runs set or test |
ConfigurationModeFrequencyMins |
The interval | Your new schedule should start here, then be tuned |
RefreshMode |
Push or Pull |
Pull means you need an orchestration layer before you can migrate |
RebootNodeIfNeeded |
$true or $false |
$true means something in your estate expects automatic reboots |
PartialConfigurations |
Names and sources | Each becomes an Include — or reveals a source nobody knew about |
CertificateID |
A thumbprint, or empty | Non-empty means encrypted credentials are in play; see unit 5 |
A surprising number of estates discover at this point that half their nodes are in ApplyAndMonitor while everyone believed they were auto-correcting. Better to learn that now than during the first incident after cutover.
[!TIP]
Capture the meta-configuration for every node into a file before you change anything. It's the only record of what the old system was doing, and once the LCM is disabled, reconstructing it means reading old build scripts.Get-DscLocalConfigurationManager | Select-Object ConfigurationMode, ConfigurationModeFrequencyMins, RefreshMode, RebootNodeIfNeeded, CertificateID | Export-Csv -Path .\lcm-baseline.csv -NoTypeInformation -Append
> EOF