DSC - Desired State Configuration
Posted in automation on February 13, 2017 by Adrian Wyssmann ‐ 5 min read

During my work related to test environment provisioning I was stumbling over Desired State Configuration:
It is a new management platform in Windows PowerShell that enables deploying and managing configuration data for software services and managing the environment in which these services run.
Sounds pretty interesting isn’t it? I also recommend to read the DSC-Book @ Penflip.com or have a look at the source code at github. Let’s have a look on how it works…
Writing a DSC
DSC PowerShell scripts are are declarative scripts which define and configure instances of resources. They are idempotent, which means in whatever state the machine is, when applying the configuration LCM will ensure that the machine will end up in the exact state declared by the configuration. Here an example of such a script:
Configuration MyDscConfiguration {
param(
[string[]]$ComputerName="localhost"
)
Node $ComputerName {
WindowsFeature FeatureExample {
Ensure = "Present"
Name = "Telnet-Client"
}
WindowsFeature FeatureExample2 {
Ensure = "Present"
Name = "Telnet-Server"
}
Service ServiceExample {
Name = "TlntSvr"
StartupType = "Manual"
State = "Running"
}
}
} MyDscConfiguration
The outermost script block is the Configuration block. Embedded in the configuration block you can find Node blocks, which defined the nodes (computer, VM) to be configured. Within the node blocks there are one ore more Resource blocks which sets the properties for a resources belonging to the particular node. There are a lot of different resources and it’s corresponding properties available:
- Archive Resource
- Environment Resource
- File Resource
- Group Resource
- Log Resource
- Package Resource
- Registry Resource
- Script Resource
- Service Resource
- User Resource
- WindowsFeature Resource
- WindowsProcess Resource
So in the above example We want to ensure that the “Telnet-Client” and “Terminal-Server” features are installed and the “Terminal-Server” is started. In order to get the appropriate “Names” you can get it by querying the available services with the “Get-WindowsFeature” cmdlet:
PS C:\Users\Administrator> Get-WindowsFeature
Display Name Name Install State
------------ ---- -------------
....
[ ] Telnet Client Telnet-Client Available
[ ] Telnet Server Telnet-Server Available
[ ] TFTP Client TFTP-Client Available
...
Remark: The “Get-WindowsFeature” cmdlet is not available on all Windows versions cause it is either not available (e.g. Windows 7) or the related module needs to be loaded.
Once the DSC script is ready, you need to compile the script into and MOF document by calling the configuration file. This call will
- Resolves all variables
- Create a folder
name of configuration
in the current directory - Create a file named NodeName.mof in the new directory for each target node
In my case the file that is created is “localhost.mof” but by specifing “-ComputerName ‘TestWin2012-01′” I can override the parameter “ComputerName”:
PS D:\Workspaces\DSC> . .\MyDscConfiguration.ps1
Directory: D:\Workspaces\DSC\MyDscConfiguration
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 08.02.2017 15:51 2526 localhost.mof
PS D:\Workspaces\DSC> .\MyDscConfiguration.ps1 -ComputerName 'TestWin2012-01'
Directory: D:\Workspaces\DSC\MyDscConfiguration
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 08.02.2017 15:55 2530 TestWin2012-01.mof
PS D:\Workspaces\DSC> dir .\MyDscConfiguration
Directory: D:\Workspaces\DSC\MyDscConfiguration
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 08.02.2017 15:50 2520 localhost.mof
-a--- 08.02.2017 15:55 2530 TestWin2012-01.mof
The MSDN documentation show more interesting options like dependency handling and configuration of VMs on boot up.
Enacting Configurations
However, now that I have a compiled configuration I would like to run it. So my target machine “TestWin2012-01” does not have Telnet-Client or -Server installed so far. There are two modes for enacting configurations
- Push mode: A user actively applies configuration to a target node by calling the Start-DscConfiguration cmdlet.
- Pull mode: Pull clients are configured to get their desired state configurations from a remote pull server
For the pull mode to work, a server (web, smb) needs to be configured to host the service and the client node or the Local Configuration Manager - needs to be configured to pull the configurations from the pull server. The pull clients have a scheduled task that performs a periodic compliance check on the configuration on the node and if needed pulls the configurations and executes it. In this case I use the push mode
PS D:\Workspaces\DSC> Start-DscConfiguration -Path 'D:\Workspaces\DSC\MyDscConfiguration\'
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
11 Job11 Configuratio... Running True TestWin2012-01 Start-DscConfiguration...
So the Start-DscConfiguration cmdlet starts a background job and there is no visible feedback but you can query the job via the Get-Job cmdlet. Unfortunately in my case I only see that the job failed but there is no reason. So let’s run the job again in interactive mode:
PS D:\Workspaces\DSC> Start-DscConfiguration -Path 'D:\Workspaces\DSC\MyDscConfiguration\' -Wait
WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer TestWin2012-01.
Verify that the computer exists on the network and that the name provided is spelled correctly.
+ CategoryInfo : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070035
+ PSComputerName : TestWin2012-01
No surprise this does not work, I assume one need to set appropriate permissions. You may dig into detailed articles here, here and here. In the end I had to change the “TrustedNodes” configuration on the local machine.
PS D:\Workspaces\DSC> Start-DscConfiguration .\MyDscConfiguration TestWin2012-01 -Credential Administrator -Wait
PS D:\Workspaces\DSC> Enter-PSSession -ComputerName TestWin2012-01 -Credential Administrator
[TestWin2012-01]: PS C:\Users\Administrator\Documents> Get-WindowsFeature
Display Name Name Install State
------------ ---- -------------
....
[X] Telnet Client Telnet-Client Installed
[X] Telnet Server Telnet-Server Installed
...
[TestWin2012-01]: PS C:\Users\Administrator\Documents> Get-Service TlntSvr
Status Name DisplayName
------ ---- -----------
Running TlntSvr Telnet
So this are just some basics and there is a lot more one can do with DSC. Also more interesting is the possibility to have a Pull-Server in place which make DSC configuration files available to target nodes when those nodes ask for them. I will cover this in another blog entry thus.