At the end of the previous post I said that dependsOn only decides the order in which resources are processed. It doesn't check that the resource you depend on is actually in the desired state.
Sometimes that's not enough. You want to say "only touch this machine if it's Windows Server 2025", or "only configure the website if IIS is really installed". That's what the Microsoft.DSC/Assertion resource is for.
Note: this post is part of a bigger series on Microsoft Desired State Configuration.
- Getting started with DSC 3.0 – Part 1: What is DSC and what changed?
- Getting started with DSC 3.0 – Part 2: Managing a Windows service end to end
- Getting started with DSC 3.0 – Part 3: Capturing the current state with dsc config export
- Getting started with DSC 3.0 – Part 4: Configuring IIS with multiple resources and dependsOn
- Getting started with DSC 3.0 – Part 5: Guarding your configuration with Assertion (this post)
What is an assertion?
An assertion is a group resource. It contains a nested configuration document and runs the test operation on every resource inside it. It never changes anything.
- If every nested resource is in the desired state, the assertion passes.
- If one of them isn't, the assertion fails, and DSC doesn't invoke the resources that depend on it.
Only the resources that dependsOn the assertion are affected. The rest of the document runs as usual.
Remark: resources that only implement get, like Microsoft/OSInfo, are a natural fit for assertions. They can read the state but not change it.
A minimal example
Save this as assertion.dsc.yaml:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Demo key
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Demo
_exist: true
dependsOn:
- "[resourceId('Microsoft.DSC/Assertion', 'Windows only')]"
- name: Windows only
type: Microsoft.DSC/Assertion
properties:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Operating system
type: Microsoft/OSInfo
properties:
family: Windows
Two things to notice:
- The assertion has its own
$schemaandresources, nested insideproperties - The registry key depends on the assertion with the same
resourceId()syntax we used in Part 4, withMicrosoft.DSC/Assertionas the type and the instance name
Apply it:
dsc config set --file assertion.dsc.yaml
The operating system is Windows, so the assertion passes and DSC creates the key.
Check it:
Test-Path HKCU:\Software\Demo
Let it fail
Remove the key first:
Remove-Item HKCU:\Software\Demo
Now change family: Windows to family: Linux in the document and run the same command again:
dsc config set --file assertion.dsc.yaml
The assertion fails, so DSC doesn't invoke the registry resource. Run Test-Path again and the key is not there.
Remark: the registry resource is listed before the assertion in the document. Like we saw in Part 4, the order in the document doesn't matter. The dependency does.
A more realistic case
A common use is applying settings depending on the Windows Server version. The OS version check is the gate:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Baseline tag
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\SOFTWARE\Contoso
valueName: Baseline
valueData:
String: Server2025
dependsOn:
- "[resourceId('Microsoft.DSC/Assertion', 'Server 2025 check')]"
- name: Server 2025 check
type: Microsoft.DSC/Assertion
properties:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Server 2025
type: Microsoft/OSInfo
properties:
version: "10.0.26100"
Add one pair like this per OS version and each machine only gets the settings that fit.
Here the version is an exact match. DSC 3.3 added version comparison to Microsoft/OSInfo, so you can assert a constraint instead.
Remark: this one writes to HKLM, so run it from an elevated terminal.
Back to our previous example
In Part 4, dependsOn made sure IIS was installed before the web resources. But dsc config test on a clean machine could still fail, because the IIS cmdlets weren't there yet.
An assertion that checks the Web Server role fixes that. Add this to the document from Part 4:
- name: IIS is installed
type: Microsoft.DSC/Assertion
properties:
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Web server role
type: PSDesiredStateConfiguration/WindowsFeature
directives:
requireAdapter: Microsoft.Adapter/WindowsPowerShell
properties:
Name: Web-Server
Ensure: Present
dependsOn:
- "[resourceId('PSDesiredStateConfiguration/WindowsFeature', 'IIS')]"
And let the web resources depend on the assertion. For the application pool:
dependsOn:
- "[resourceId('Microsoft.DSC/Assertion', 'IIS is installed')]"
Give the website and the web application the same dependency, next to the ones they already have.
The flow is now: install IIS, check that IIS is installed, and only then configure the pool, the site and the application. If the check fails, DSC doesn't touch them.
Things to keep in mind
- An assertion only gates the resources that depend on it
- It never changes anything. If you want DSC to fix something, that's a normal resource
- The assertion itself must be a top-level instance. A resource inside a group can only depend on its neighbors in the same group, so the IIS install and the assertion stay at the top
We are not there yet. In our next and probably last post about DSC, we'll add AI into the mix.
