PowerShell DSC 101 – What’s it all about?

What is PowerShell DSC, and what can I use it for?

DSC: Desired State Configuration

DSC is a Powershell technology that enables a set of server’s configuration states to be described in a Powershell configuration object.  Each part of the configuration for a server (or Node) is described using a Powershell DSC Resource.  There are some “built in” resources, such as File, Registry, WindowsFeature, Script, but many others are available from third-party sources, such as the Powershell Gallery, or can be custom written.  A DSC Resource provider will typically have three functions:

  • Test (Figure out if the configuration is already in the desired state or not)
  • Get (Return the state of the existing configured resource)
  • Set (Make the resource comply with the desired state)

Put simply, you can use DSC to define the state of a server or set of servers, and when deployed, you can rest easy that those servers will be in the state you’ve dictated for them – even if someone RDPs into your server and changes one of your settings – DSC will know about it and change it back automatically.

In this post, I’m just going to cover the high level – I’ll follow up with some more details including specific examples of how to carry out certain tasks, such as enable RDP for administrators on a server, make sure SQL Server’s installed, etc..

Which brings me to my first DSC observation, having played with it for some time, I’ve come to the conclusion that there’s not an awful lot you can’t do with it.  This is a good thing, but as with all good things, judgement as to how far you go and what kinds of things you do lies with the implementer.  You could use it for making sure pre-requisite settings, features and services exist on your application server – thereby adding some additional protection against configuration errors and inconsistent setup documentation.  You can also use it to take a blank Windows Server installation and install SQL and TFS Server on it and use this as your way of producing a line of business server.  I’d recommend the former, but maybe not the latter – there are in my humble opinion, better ways to crack this kind of nut – preparing a server image as a template for example, using sysprep to generalize it and mount it.

How do I get the configuration to my servers?

A service called Local Configuration Manager does the work here. The configuration is executed on each target server by the windows Powershell DSC engine – the DSC Local Configuration Manager (LCM) (https://technet.microsoft.com/en-us/library/dn249922.aspx). This engine is responsible for acquiring the machine’s configuration and applying it – it accepts various parameters to control how it goes about doing this, eg. How frequently it should check for new configurations, how the configuration files should be obtained, etc.

There are two distinct modes of operation for the LCM to be set to – Push or Pull.

pushmode - Copy


Push Mode:
The server (S1) uses a PowerShell command to send the configuration data to the target servers.
The target servers must be online and configured to be able to listen for configuration updates.



Pull Mode:
The server (S1) is configured to listen for requests from the target servers. The target servers will make requests to S1 on a regular basis, only downloading configurations if they vary from the current applied configuration. They will then apply the updates. Once the servers have been setup, there is no need to check or maintain configurations on the target servers – DSC will manage that on your behalf.

I found that during development of scripts, I’d use push mode to my test server, then when deploying for production, pull mode is the more scalable option – the benefits being:

  • You manage the configuration centrally, and when you update it, the servers will discover the updates for themselves when they’re ready
  • You don’t need to know the names of any of the servers in your farm, as long as you’ve set them up so they know where the pull server is and what configuration ID to request, that’s all you need to do

What can DSC Control?

DSC was designed to ensure that a server or suite of servers (environment) is configured as expected, and any configuration changes made inadvertently during operational use which would otherwise lead to the environment not functioning correctly, are rectified automatically, removing the need for IT teams to spend time investigating and correcting configuration errors.

DSC is also used to carry out the initial setup of a new server, and is commonly seen in virtualized environments for the automatic provisioning of new VMs, removing any risk of human error, or time spent following lengthy scripts and documentation. As a DevOps tool, developers and testers can benefit hugely by being able to provision complex infrastructure environments in a self-service fashion, rather than submit requests for environments to be built and configured by an IT team.
Microsoft’s Azure supports DSC, and its use is widespread when setting up Infrastructure as a Service environments (IaaS). In this respect, the original VM image plus DSC configuration are effectively a template for a server, and can be used to scale up IaaS environments horizontally.
Since DSC is underpinned by PowerShell, there isn’t a lot that can’t be achieved with DSC. In this series of posts I’m going to show how to achieve the following fairly common tasks:

  • Ensure mandatory Windows Roles and Features are installed, (different requirements per target server type)
  • Ensure required security and network settings are made
  • Deploy an installation DVD image (ISO) to the target server and carry out a silent install
  • Deploy .MSI, .MSU and .EXE package installations to the target server and have them installed silently
  • Modify registry entries
  • Call custom scripts to carry out ad hoc operations (eg. Setting the time zone)

Authoring Process (How to start using DSC)

Although configuration files are created as PowerShell Scripts, the actual deployment to target servers is achieved via a file format called Managed Object Format (MOF), http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0.pdf. MOF is a standard for describing managed objects that conform to the Common Information Model (CIM). http://www.dmtf.org/sites/default/files/standards/documents/DSP0004_3.0.1.pdf. This step allows other server types to be configured by DSC (not just Windows Operating Systems) – MOF Files can be used to set state on Linux servers, for example.

authoring process

The initial script, being PowerShell, enables the use of parameters and configuration data files, and rich scripting control over how the PS1 file is built. When the configuration is executed, one MOF file per target Node (server) is generated in the configuration subfolder.

In order to deploy any resource via the Pull web service download manager, a checksum file is also required to be generated. The checksum is used by the target server to validate the content of the configuration, and determine whether or not the configuration content matches the currently applied configuration.

Modules and Resources

The PowerShell Gallery contains many DSC modules and resources that can be used very simply – WMF5 adds the PowershellGet module which brings the following commands that interact with the gallery:

  • Find-module – discover modules in the gallery by name or list all
  • Install-module – download and install the module and it’s resources
  • Update-Module – keeps modules and dependencies up to date, use –Whatif to see what would be updated as a result of running the command without making changes

Once a module is installed, you can view the resources using Get-DSCResource, and to list a specific DSC resource’s syntax, use Get-DSCResource -Syntax, for example, the xFirewall resource within the xNetworking module is shown below. This syntax can be copy/pasted into your powershell DSC configuration file, and you then just complete the parameters (and remove those you don’t want to specify):

get-DscResource xFirewall -syntax
xFirewall [String] #ResourceName
Name = [string]
[Action = [string]{ Allow | Block | NotConfigured }]
[ApplicationPath = [string]]
[DependsOn = [string[]]]
[Description = [string]]
[Direction = [string]{ Inbound | Outbound }]
[DisplayGroup = [string]]
[DisplayName = [string]]
[Enabled = [string]{ False | True }]
[Ensure = [string]{ Absent | Present }]
[LocalPort = [string[]]]
[Profile = [string[]]]
[Protocol = [string]]
[PsDscRunAsCredential = [PSCredential]]
[RemotePort = [string[]]]
[Service = [string]]

That completes the 101 overview post, coming next is the implementation post, including how to setup your authoring environment, the pull server, and sample tasks and code for completing the common tasks mentioned earlier.