Summary: Microsoft MVP, Will Anderson, talks about familiarizing yourself with DSC formatting and resources.
Good morning, Ed Wilson is here. Today we have Part 2 of Will Anderson’s awesome DSC series. Be sure you also read Conceptualize Desired State Configuration: Part 1. Today he talks about formatting and resources. Take it away Will…
I'm going to jump ahead here and say that it become vastly easier to find and install resources by using WMF 5.0, which went RTM in December 2015. So, if possible, I highly recommend downloading the latest version of WMF 5.0 and installing it on your system (see Installation Instructions). However, for those who can't, we'll be covering some of the differences that you'll need to know about during this series.
Formatting DSC
When you open the Windows PowerShell ISE, you can use CTRL+J or right-click in the scripting pane to open your collection of snippets. Let's start with the DSC Configuration (simple) snippet.
This snippet will give you the basic layout for a configuration. Let's take a quick look at the parts.
configuration Name
Pretty self-explanatory. This is the name of what we'll be calling our configuration. It's similar to how we declare a function in a PSScript. This configuration is going to be targeted at my SCCM distribution points, so I'm going to call this one CMDPConfig:
configuration CMDPConfig
{
# One can evaluate expressions to get the node list
# E.g: $AllNodes.Where("Role -eq Web").NodeName
node ("Node1","Node2","Node3")
{
Next, we declare the nodes (servers) that we'll be targeting. You can use parameterization to target a system and use configuration data files to declare roles. Now I'm only targeting one type of server, so I'm going to use my test server name in the node declaration:
configuration CMDPConfig
{
# One can evaluate expressions to get the node list
# E.g: $AllNodes.Where("Role -eq Web").NodeName
node ("lwincm02")
{
# Call Resource Provider
# E.g: WindowsFeature, File
WindowsFeature FriendlyName
{
Ensure = "Present"
Name = "Feature Name"
}
File FriendlyName
{
Ensure = "Present"
SourcePath = $SourcePath
DestinationPath = $DestinationPath
Type = "Directory"
DependsOn = "[WindowsFeature]FriendlyName"
}
}
}
The next section is where the meat and potatoes of the configuration begin. This is where you begin declaring DSC resources and setting the desired configuration. The snippet gives you a couple of examples to work with, so we're going to take them apart and see how they work.
Let's look at the WindowsFeature resource example first, since for our distribution point, we'll need to configure some anyway:
WindowsFeature FriendlyName
{
Ensure = "Present"
Name = "Feature Name"
}
WindowsFeature is the name of the DSC resource that we're calling. This resource can be found by using the following command:
PS C:\Windows\system32> Get-DscResource -Name WindowsFeature
ImplementedAs Name ModuleName Version Properties
------------- ---- ---------- ------- ----------
PowerShell WindowsFeature PSDesiredStateConfiguration 1.1 {Name, Credential, DependsOn, Ensure...}
As we can see, the WindowsFeature DSC resource is part of the PSDesiredStateConfiguration module, which is available without having to download and install additional modules. Note that there is a Properties value there. Let's explore that for a moment:
PS C:\Windows\system32> Get-DscResource -Name WindowsFeature | Select-Object -ExpandProperty Properties
Name PropertyType IsMandatory Values
---- ------------ ----------- ------
Name [string] True {}
Credential [PSCredential] False {}
DependsOn [string[]] False {}
Ensure [string] False {Absent, Present}
IncludeAllSubFeature [bool] False {}
LogPath [string] False {}
PsDscRunAsCredential [PSCredential] False {}
Source [string] False {}
The properties table gives you a list of all of the configurable properties available for a given DSC resource, in addition to whether they are mandatory and what values may be accepted. Pretty cool, but DSC resources do something even better for you when you use the Get-DSCResource cmdlet with the Syntax parameter:
PS C:\Windows\system32> Get-DscResource -Name WindowsFeature -Syntax
WindowsFeature [String] #ResourceName
{
Name = [string]
[Credential = [PSCredential]]
[DependsOn = [string[]]]
[Ensure = [string]{ Absent | Present }]
[IncludeAllSubFeature = [bool]]
[LogPath = [string]]
[PsDscRunAsCredential = [PSCredential]]
[Source = [string]]
}
Notice how the format of the output resembles that of the format of the Desired State Configuration example? This is by design. So now all you have to do is paste the output into your code as a template! We're going to do exactly that. But first, let's take a look at how the parameters are presented to us.
Reading DSC parameters
Mandatory parameters are listed without being encapsulated in angle brackets, and optional parameters have them, for example:
{
Name = [string] #This is a mandatory parameter
[Credential = [PSCredential]] #This is an optional parameter
}
Each parameter will also call out the value type that it's looking for. Like a PowerShell cmdlet, arrayed values will be annotated with a second set of angle brackets next to the value. Parameters that have a validated set of inputs will call out the valid inputs that the given parameter is looking for:
{
Name = [string] #This can only take a single value
[DependsOn = [string[]]] #This can take an array of values.
[Ensure = [string]{ Absent | Present }] #This can only take Absent or Present as valid values.
}
You can also use hash tables to add multiple values and reuse instances of DSC resources. We'll get into that later—we're just getting started with some basic configurations for now. Now that we have some of the basics for how DSC resource providers work in a configuration script, we're going to gear up and build our first configuration.
~Will
Thank you, Will, for another awesome post. He will be back tomorrow with Part 3 of this series.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy