In today's cloud-centric world, we’re seeing an explosion in the number of servers under IT management. Virtual machines made servers cheap, and containers will push prices down further. As a result, businesses can afford to deploy a server for every new need, but they can no longer afford to manage servers individually. Your servers no longer garner individual attention but are simply soldiers in a huge resource pool, dutifully fulfilling the resource requests of the data center.
This dramatic increase in server population requires a new method of resource management, called configuration management. Products like Chef, Puppet, Ansible, Salt, and CFEngine have automated configuration management in the Linux world for many years now. It wasn't until recently that the companies behind these products started taking Windows seriously. This is in part due to Windows PowerShell Desired State Configuration (DSC). Introduced with PowerShell 4, DSC provides a way to manage Windows servers declaratively through the same configuration management practices the open source community has been using for years.
At first glance, you might think that DSC is a competitor to these trusted configuration management solutions. Technically, you can bring all of your servers under DSC management and forgo the other products. However, this is not Microsoft's intention, and in an environment of any size, you'd soon see the downfalls of such an attempt. Microsoft did not build DSC to be a competitor but to be used as a platform for others to build upon. DSC was built to provide a standardized method that any solution could use to manage Windows (and Linux) systems however they choose.
If you're looking into managing your Windows systems with a configuration management product, why would you choose to use DSC anyway? After all, it's a bare-bones platform. In fact, DSC is still extremely valuable for smaller businesses that don't require features, such as reporting and Web management, that larger enterprises might require. One of the big advantages DSC has for smaller businesses is that it's built right into the operating system as of Windows Server 2012 R2. There's no need to download, deploy, and manage third-party software. It comes baked into Windows already.
What DSC is made of
DSC is built to manage configuration baselines using three main components: resource providers (Windows Server features, processes, files, registry keys, and so on), resources (the building blocks of configuration scripts), and a Local Configuration Manager (LCM), the DSC “client” or “agent” that applies configuration scripts on each target node. These components work in tandem to deliver a configuration to a particular server.
Resource providers are the "API" between the operating system and other services in which DSC tests, gets, and sets (if applicable) each configuration item on each server. Resource providers then consume DSC resources in the form of PowerShell scripts. Resources are the component of DSC that control the features, services, and applications installed on the operating system. Microsoft provides you with about a dozen kinds of resources built into Windows, including WindowsFeature
, WindowsProcess
, and File
, to name a few.
Figure 1: Built-in resources for Windows Server 2012 R2.
These are components that allow you to control the presence and configuration of Windows features, processes, files, and other components of the operating system. A downside of using native DSC is that only a few DSC resources come built in. This forces users to build their own resources in PowerShell. Users can download and consume custom-built resources from others in the PowerShell community as well.
The various resource providers take their marching orders from scripts managed by the LCM, which is in charge of such details as how often resource providers consume resources (in the form of PowerShell scripts) and how they are applied. The LCM is the mediator that controls the resource providers.
Figure 2: An example of LCM properties.
Lastly, resources can be delivered to resource providers in two ways: push and pull. Push mode operates in the traditional way you'd expect to run a script. You simply copy the resource to the server and execute it. Once the script is executed, the LCM sends the resource to the resource provider, which then follows the instructions in the resource.
The pull method entails a server downloading the resource from a central server running a small Web service known as a pull server. This pull server is in charge of storing all of the resources. Once a server requests all resources assigned to it, the pull server delivers the resource, the server pulls them down locally and executes them.
Most businesses choose to start out delivering resources via the push method. This allows them to build resources as they would PowerShell scripts and forgo building a pull server. However, push does not scale. It is recommended to build a pull server if you are deploying DSC to production in order to manage many servers.
Creating a DSC configuration
To manage a set of configuration items on a server first requires building a DSC configuration script. A DSC configuration script is a combination of various references to DSC resources that, when combined, form the desired state of a server.
DSC configuration scripts look similar to simple PowerShell modules and follow a domain specific language similar to that of Puppet. They also follow a similar naming convention with PowerShell functions; instead of the word "function" they use the word "configuration," for example. This makes it easy for people who already know PowerShell to start writing DSC modules.
Figure 3: A DSC configuration to install a Windows Server feature.
Configurations contain one or more resources. These resources can be built-in resources, like the WindowsFeature
resource mentioned above, or custom resources, which allow you to incorporate any kind of PowerShell code you would like into the configuration. You can write custom resources yourself or draw on those created by the broader PowerShell community. Microsoft provides many resources that do not come installed by default in its GitHub repository. There you can find dozens of DSC resources like xHyper-V
, xCertificate
, and xDnsServer
to use in your configurations.
Let's go over how to build your first DSC configuration. In this example, we will build the DSC configuration script to ensure a Windows server has the SNMP feature enabled. Because the DSC resource WindowsFeature
comes built into Windows Server 2012, we don't have to download any external files. We will build this configuration on a Windows Server 2012 R2 server and execute it on the same machine. This means we will use the push mode, as our DSC client will not pull a configuration from an external server.
Build the script
The first task is building the configuration script. To do this, we’ll open up our editor of choice and get started.
In the first line you'll notice that we have a block called Configuration
. This is how every configuration script must begin. The name of the script can be anything we’d like. Inside of that we’ll typically have a parameter block with various parameters to the configuration. $ComputerName
is a typical parameter, and you'll see that we’re defaulting to the local computer here. Then, we have a Node
block. This represents the name of the computer, or group of computers, that this configuration will be applied to. Since I’m specifying $ComputerName
here, this script will build our configuration for the localhost machine. Next, we have the WindowsFeature
block. This is a reference to the WindowsFeature
DSC resource. I chose to give this reference a name of SNMPService
, but it can be anything you'd like.
Inside of our DSC resource, we have two attributes: Name
and Ensure
. For the WindowsFeature
resource, the name attribute signifies the name of the Windows feature. The Ensure
attribute signifies that we want to ensure that this feature is present. We could just as easily choose to ensure that something isn’t present, if that's what we wanted.
Create the MOF file
Once the configuration script is created, we then build a Managed Object Format (MOF) file. To do this requires executing our configuration block, which is as simple as referencing it in that same script. This will create a MOF file with the same name as the computer it will be run on in a subfolder with the same name as the configuration. You can see in Figure 4 below that executing our InstallSNMPService
configuration created a subfolder of the same name with a localhost.mof file inside.
Figure 4: Creating the configuration MOF directory and file.
Once we have the MOF file generated, we can then call Start-DscConfiguration
and specify the path to the folder we created. In the example below, I'm also using –Verbose
to get more information as it applies the configuration and –Wait
in order for the LCM to wait until the configuration has been applied. By default, LCM will create a PowerShell job and continue on before it is done.
Figure 5: Applying the DSC configuration.
Once the configuration is applied, we can run the script again and you'll see that LCM simply skipped over the install since SNMP was already installed (Figure 6). The beauty of DSC is that you don't have to account for the Windows feature being installed or absent. DSC takes care of all that conditional logic for you. All you need to do is define how you want the state of the server to be -- that's it!
Figure 6: A subsequent run of the DSC configuration.
Once the configuration is applied, the LCM will take over and run again on its own every 15 minutes (by default). This means that once a configuration is set it will stay that way until you change the script. If someone should change the server’s configuration manually, the LCM will soon set things right again. Thus DSC helps you to enforce standard configuration policies at regular intervals.
Building your own DSC resources
We've now covered building a configuration script using the built-in WindowsFeature
resource. If the built-in resources don't cover all the functionality you're seeking, you can build custom DSC resources. If you choose to create your own, you'll need to know that DSC resources include three functions: Get
, Set
, and Test
.
When the LCM runs, the resource provider first initiates the Test
function to determine whether the configuration specified in the resource already matches the server's current configuration. If not, it then initiates the Get
function to retrieve the current configuration. Depending on the LCM configuration, DSC will then either report that the configuration has drifted or will run the Set
function to bring the server back into compliance.
With PowerShell 4, custom resources are created using MOF. On the plus side, MOF is a simple text file that could be easily consumed on the server. It is also an industry-standard format. In short, MOF was a simple way for Microsoft to get DSC shipped and immediately available to customers. Using MOF-based DSC resources, an admin goes through a four-step process:
- Build the DSC module
- Execute the DSC module to create a MOF file
- The MOF file would get copied to a server somehow
- The MOF file would be consumed by the DSC resource provider to check for the state of the server
This process works, but it is not the elegant method of resource consumption that Microsoft envisioned. As of PowerShell 5, Microsoft recommends creating custom resources via classes.
Classes are one of the big features introduced in PowerShell 5. Classes have been the mainstay of every object-oriented programming language, and now PowerShell can be considered part of the club. Classes have many uses in PowerShell 5, but one of the main use cases is class-based DSC resources. Using class-based resources, we no longer have to fool with MOF files anymore. Our previous four-step process can now be whittled down to three steps.
- Build the DSC module
- Copy the DSC module to the server
- Execute the DSC module
Building resources from classes is not only faster than using MOF files, but it also adheres more closely to how traditional PowerShell modules work. This makes it even easier for people to get started writing DSC resources.
Get to know DSC
If you're looking at configuration management options, it's well worth your time to take a look at DSC to manage your Windows servers. DSC has been around for only two years, but it is garnering ever-increasing support from Microsoft and others in the community. Keep a close eye on Microsoft's PowerShell GitHub repository, where you'll see contributors from Microsoft regularly fixing bugs, adding features, and creating new resources for everyone to use.
Still in its infancy, DSC is far behind products like Chef, Puppet, Ansible, and Salt. Even if you don't choose to use native DSC for configuration management, it's well worth your time to learn how DSC works.
The companies behind the leading configuration management solutions are only now beginning to adopt DSC in their products. You're soon going to find that every configuration management product that manages Windows systems is using DSC under the covers. Although you might not have to manage DSC directly, it will be important to understand how it works in order to better manage and troubleshoot the Windows configuration manager you do use.
Looking for more? Download the essential guide to PowerShell and make the most of Microsoft’s command line for Windows, Windows Server, and Exchange. Get the PDF today