Day 55: Automating the DSC Configuration MOF Build Process (part 2)

Welcome to Day 55 of the “100 Days of DevOps with PowerShell”! For background on our goals in this series, see Announcing the “100 Days of Devops with PowerShell” Series here at SCC. If this is the first time you are viewing an article of the series and you are new to DevOps and PowerShell Desired State Configuration (DSC), I encourage you to read through the previous installments, particularly Day 1. I can’t believe we are already in the second half of our 100 days! As we progress, expect us to push further into new concepts, as well we to tie together our work from previous days.

Objective of this post…

In Day 35, we talked about automating some of the steps in the DSC configuration and node update process. Today, we’re going to extend that process to further automate the build and deployment of the configuration mof file for the existing nodes in your environment. Hopefully by this time, you are storing node details and DSC ID (guid) information in a CMDB (day 5) or central DSC repository (Day 35). In this post, I want to take the process one step closer to full end-to-end automation of the DSC configuration mof creation process.

I will get you most of the way to this goal today. Scott will build on my work here in his day 56 post (tomorrow) to complete the process (a base end-to-end scenario), and then we’ll build on that even further with some source control integration from Mickey to achieve true enterprise-grade end-to-end DSC build automation.

Sample Environment (for this tutorial)

The sample environment used in this tutorial consists of two machines:

  • – A Windows Server 2012 R2 system with 2 GB RAM that is configured as a DSC Pull Server. This system is domain-joined to the domain.
  • – A Windows 2012 R2 system that is domain-joined to the domain. The server will serve as a managed system (node) that will retrieve its configuration file from the pull server.
  • – A Windows 2012 R2 system that is domain-joined to the domain. The server will serve as a managed system (node) that will retrieve its configuration file from the pull server.

End-to-End Process

The high-level process is as follows:

  1. Populate newly provisioned nodes in the central DSC repository (we created in Day 35)
  2. Retrieve node record from the central DSC repository and parse contents
  3. Construct configuration script and create mof file (Scott will cover in Day 56)
  4. Upload to DSC Pull Server and generate checksum
  5. Update node configuration (we are assuming in this example, the node as been configured and we need simply to update configuration mof file.
  6. Force node to evaluate status [optional] (I will provide a simple example of PowerShell remoting so you can trigger this from your remote session)
  7. Update ‘last update’ field in central DSC repository

I will be focusing on steps  in blue. Scott will cover the steps in red tomorrow in Day 56.


1) Populate newly provisioned nodes in the central DSC repository

While I covered in detail in Day 45, we created a central DSC repository how to set this up, I did not give you full context of how you might use this in an end-to-end scenario. Scott covered this in Day 51.

2) Retrieve node record from the central DSC repository and parse contents

In Day 45, we created a central DSC repository in SQL to store details about the nodes we intend to manage through PowerShell DSC. We will start by turning the sample code to query the repository into a parameterized function so we can simply pass a server name to the function and get a copy of the database record with all the details of the server.

Function Get-NodeGuid([string]$NodeFQDN) {

Invoke-Sqlcmd -Database DSCSource -ServerInstance `
-Username corpadmin -Password P@ssw0rd -OutputSqlErrors $True `
-Query "select * from DSCTracking where ServerName = '$NodeFQDN'"


#Call the function to and save the node record to variable

$NodeDetails = Get-NodeGuid ''

The contents of $NodeDetails is shown in the image below.


We will need to retrieve the DSC configuration id (DSCGuid) for this node


as well as the list of applications to be managed with:


With this information in hand, we can build the

3) Construct the configuration script and create mof

The goal of this step is to pull code snippets into a configuration script based the server and application roles retrieved from our central DSC repository, using the values from the previous step as input. This is not a trivial step, and deserves it’s own installment. With that in mind, Scott will cover this off tomorrow in Day 56.

4) Upload to DSC Pull Server and generate checksum

At this point, we have created the configuration mof script that contains the instructions telling the node how it should be configured and run the script to create the configuration mof file. The tasks in this step are to 1) upload mof file and name as <Node DSC ID>.mof and 2) generate the checksum file the managed node uses to ensure the mof file has not been modified. Notice this function is fully parameterized to ensure we can leverage it as part of an end-to-end DSC configuration and provisioning process.

Function PrepMofForDist([string]$PullServer, [string]$NodeFQDN, [guid]$Guid, [string]$SourcePath)
$source = “$SourcePath\$NodeFQDN.mof”
write-host $source   

$target= “\\$PullServer\c$\program files\windowspowershell\dscservice\configuration\$Guid.mof"
write-host $target
copy $source $target
New-DSCChecksum $target
# Call the function and pass in values for environment and target node we want to configure
# retrieved from the central DSC repository 
PrepMofForDist -PullServer 'localhost' -NodeFQDN $NodeDetails.ServerName -Guid $NodeDetails.DSCGuid –SourcePath $SourcePath


Now the configuration process is complete.

5) Update node configuration

We are assuming on Day 55 that the node we are managing is already configured with DSC configuration ID (Guid) and other settings.


6) Force node to evaluate status (optional) [PowerShell Remoting version]

This is not a required step, but if you don’t want to wait 15 – 30 minutes to see results, you will want to force the node to evaluate its configuration. Remember that how the LCS on the nodes behaves depends on the ConfigurationMode you set in the configuration mof. What is nice about this sample is that it leverages PowerShell Remoting, so you can force a node to evaluate from your remote management workstation.

FUNCTION ForceDSCNodeEval([string]$ServerName,[string]$User,[string]$Pass) {
## Section 1
# Set up user credentials, if necessary
$username = "$User"
$password = "$Pass" | ConvertTo-SecureString -asPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username,$password)

# Setup the new remote session
# Note the use of the -ConfigurationName parameter.  Microsoft.PowerShell is used to call x64 PowerShell and 
# Microsoft.PowerShell32 is used to call x86 PowerShell.  This methodology will invoke the native PowerShell 
# version on the target server SERVERNAME.
# Note: One or more New-PSSession parameters may not be required depending on your requirements
$session = New-PSSession -ComputerName $ServerName -ConfigurationName Microsoft.PowerShell -Credential $cred

# Invoke the remote session
Invoke-Command -Session $session -ScriptBlock {

$params = @{
Namespace = 'root/Microsoft/Windows/DesiredStateConfiguration'
ClassName = 'MSFT_DSCLocalConfigurationManager'
MethodName = 'PerformRequiredConfigurationChecks'
Arguments = @{
Flags = [uint32] 1
Invoke-CimMethod @params


# Close the scriptblock
## End Section 2

ForceDSCNodeEval -ServerName '' -User 'contoso\administrator' -Pass 'P@ssw0rd'


Now, we are ready to close the loop on the end-to-end process.


7) Update ‘last update’ field in central DSC repository

As part of the end-to-end automation process, we need to close out by updating the DateUpdated field in the node’s record in the central DSC repository (shown in the images in step 2). The base PowerShell snippet you need to update the database is available in Day 45, but Scott will cover this step fully tomorrow in Day 56.


That’s all for this installment. I hope you are able to follow along as your schedule allows, building on your previous efforts. Be sure to check out Day 56 in which Scott takes us through autoomated build of the DSC configuration script and a big step closer to the top of the mountain.

Previous Installments

To see the previous installments in this series, visit “100 Days of DevOps with PowerShell”.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.