What is PowerShell DSC?
Have some software that needs to be installed in a certain order? With special configuration steps? Some security policies that must be applied to every server? How about ensuring that a set of services are never enabled to start? Have you ever written scripts to handle this kind of work, but found them brittle because of changes in software from release to release? Needed to make these changes on dozens or hundreds of servers repeatedly on schedule? Ever had someone change something and have your script break because the state is not what you expected? These and many more scenarios are handled by DSC.
PowerShell DSC is a new management platform in Windows PowerShell that enables the deploying and managing of configuration data for systems and software services and the managing of the environment in which these services run. DSC allows you to define the current state of a machine and ensure that the machine is always in that state.
What we mean by state here is everything that is on that machine, including the operating system and software installed, all the configuration settings for the OS and software, and any file or process that needs to be present or set with specific content; the list goes on. Whether you considered this before or not, all this makes up the configuration of your system. DSC is designed to help you deal with all this configuration data and execute it consistently and repeatedly.
What is PowerShell?
While we assume in this book that the reader has a basic understanding of PowerShell command-line use and scripting, before we get too much into DSC, it is helpful to describe what PowerShell is compared to PowerShell DSC.
First released in 2006, PowerShell is a scripting language and command-line shell built on the .NET Framework. PowerShell provides full access to COM, WMI, and .NET, and also provides a large set of commands called Cmdlets to perform administrative tasks on both local and remote systems.
PowerShell can execute PowerShell scripts, PowerShell Cmdlets, and standalone executable programs or other language files. PowerShell also provides a hosting API that allows programs to run PowerShell natively inside their program, enabling scripting or automation scenarios. Being both a shell language and a scripting language allows it to be both quick and terse on the command line as well as verbose and consistent in scripts.
Over the years, PowerShell has become the de facto way to administer and automate Windows OS and software. As computing environments grow larger and engineering teams smaller, it is paramount in automating processes and procedures that used to be done by hand. PowerShell provides a consistent command-line language for automating the administration of a large number of scenarios, which is growing every day and was previously not available on Windows. Because of PowerShell's hosting API, applications such as Exchange have enabled a command-line first, GUI second mode of development, which enables quick deployment and management using automated tools.
PowerShell not only enables automation at the single system level, but also scales out to the multi-node environment. Being able to automate your system from the command line or script is fine, but if you have to manually run that on every system in your environment by hand, then we still have a bottleneck on efficiency. Using an industry standard protocol, PowerShell provides PowerShell Remoting as a way of running commands or scripts on any number of remote hosts in parallel. Thousands of computers can be managed at the same time, consistently, and in a repeatable and automated manner.
Consistent repeatable automation is important, but PowerShell is also extensible, which is not only essential, but leads us into DSC. PowerShell is both a typed and a dynamic scripting language, which means that it supports both static typed objects (System.IO.FileInfo
) and objects with methods and properties that are defined at runtime (PSCustomObject
and Add-Member). This enables PowerShell to be extended to suit the needs of the user. You do this every day to an extent, by creating functions and scripts to wrap common operations into reusable components or modules. Taking this a step further, PowerShell can be extended to support specific scenarios that were not envisioned when the product was made. DSC is such an extension, as it builds on the existing PowerShell language and infrastructure to enable new uses of the program.
On to PowerShell DSC
PowerShell DSC is released as a feature of PowerShell, so it comes bundled with specific versions of PowerShell that are part of the Windows Management Framework (WMF). The PowerShell DSC versions section goes into greater detail about the versions of PowerShell and PowerShell DSC and the available features in each, so we won't go into too much detail here.
The WMF release notes describe DSC in this way:
Windows PowerShell DSC helps ensure that the resources in your datacenter are correctly configured. DSC is a set of Windows PowerShell language extensions and providers that enable declarative, autonomous, and idempotent (repeatable) deployment, configuration, and conformity of datacenter resources. DSC enables an IT Pro, developer, or fabric administrator to define the configuration of target nodes (computers or devices) and prevent configuration inconsistencies or drift.
DSC provides a set of Windows PowerShell language extensions, new Windows PowerShell Cmdlets, and resources that you can use to declaratively specify how you want your operating system and software environment to be configured. It also provides a means to maintain and manage existing configurations. It supports both an interactive push model, where configurations are executed on target nodes on demand, and a pull model, where a central server manages and distributes configurations.
We won't delve into too much architecture talk here. (The next chapter discusses the architecture and inner workings of DSC in detail.) For now, it is sufficient to say DSC is comprised of both a data file and configuration file that are translated into a text file following the Managed Object Format (MOF). This file is then parsed and executed on the target server, using DSC features that know how to configure the system.
That was a lot of information in a short space, so don't worry if it is a lot to take in at once. We will go over each part as we move on. You don't have to know right away what MOF is or how DSC executes the configuration to use DSC. DSC abstracts all the details away for you. When you get to the point that you need to know these details, DSC still exposes them so you can tweak under the hood or find out what is really going on.
At a high level, DSC work isn't programming work; it's listing how you want a server to look in a special format. The execution of this list is abstracted from the listing, allowing the how to work separately from the why. This is an important concept, and really the key to understanding the importance of DSC. Jeffery Snover, the architect and inventor of PowerShell, explained it best using Star Trek. Captain Picard often used the line Make it so, and Commander Riker had to figure out how to actually make what the Captain wanted to happen, happen. Captain Picard knew what needed to be done, but didn't particularly care how it got done. Commander Riker knew how to get things done, but did not concern himself (most of the time) with deciding when and what to do. This separation allowed both officers to be good at their jobs without interfering with each other.
It may be useful to see the following short, complete example of an entire DSC configuration:
configuration BaseServerConfiguration { File ExampleTextFile { Ensure = 'Present' Type = 'File' DestinationPath = 'D:\FooProduct\foo.txt' Contents = "this is an example text" } WindowsFeature DotNet { Ensure = 'Present' Name = 'NET-Framework-45-Core' } }
That's it! Sure, there is more to understand and cover, but as we can see here, this is plain PowerShell code that is as readable as any script you've written before, and all it does is list what should be on a system. What this DSC configuration does is ensure that a file is created in the D:\FooProduct
folder called foo.txt
, with the contents this is an example text
. It then ensures that the .NET Framework v4.5 is installed. Yes, .NET 4.5 is most likely already there, but the point of DSC is to describe the state of the target node, regardless of what you think might be there. This way, if someone removes .NET 4.5, DSC will ensure that it is installed, thereby maintaining the known good state of the target node.
We will go into this further later, but now you may be asking why it is important to manage the configuration of your systems this way. Read on.