Showing off some DSC Resources

Yesterday I wrote three articles ( Part 1, Part 2, Part 3 ) about Desired State Configuration. I thought I would post a slightly more complex Configuration. This configuration performs several actions on the target node.

  1. Install the Web-Server feature
  2. Install several additional features that depend on the Web-Server
  3. Install the WebDeploy application
  4. Configure Windows Firewall to allow WebDeploy traffic

This particular Configuration has some nice features to note. The first of which are the parameters. You must provide a ComputerName (or guid) and a path to the WebDeploy MSI. You can also optionally specify a source path for the features, this is useful if you have cloned a server.

You will also notice that nearly all the Resources use the DependsOn property. Since all the features are web server related, I set the DependsOn property to be the WebServerRole. If you look in the documentation I believe that Microsoft has this down as Requires, but I believe it’s changed since the docs came out.

The Package Resource installs WebDeploy. The ProductID I was able to pull from the MSI using ORCA ( SDK Download ). If you don’t have that installed, or don’t want to install it, you can install WebDeploy on a reference machine and ought to be able to query the ProductID from WMI.

The Script Resource was a little more difficult for me, and thankfully I found a wonderful article that did the deep diving. Basically a Script has three scripts that need to run. The TestScript must evaluate to True or False. If the TestScript == False then the SetScript runs. The GetScript must return a HashTable, and the only thing that it needs to return is the Result property, but you can also specify the contents of the GetScript, TestScript and SetScript scripts. Finally the SetScript is the script that will do the thing you need done. In this example create a firewall rule to allow port 8172.

So basically what happens is when you run Start-DSCConfiguration, the script will perform a test. If that test returns true then we can assume that the thing we need done is done. If that test returns false then we need to do the thing, whatever that thing is.

When you run Get-DSCConfiguration, the script will get the state of what we did, which is why all we need is a result.

DSC Part 3

It’s been a busy day, I haven’t posted anything since July and today three posts!

Well in Part 1 we talked about what Desired State Configuration was, in Part 2 I showed you how to manually setup the pull server. Now I’ll show you how to get your target node to pull configurations from the pull server. This is basically tying the loose ends together. I don’t anticipate adding any additional posts around this particular series as it really just fills a need for me. Detailed steps on how to get from point A to point B.

So in order for the client to talk to the server we need a GUID. This GUID will represent this client, if you have several clients it may be worthwhile noting these down, along with the name and or IP of the client. Honestly, the best way to make these things is in PowerShell, it’s a one-liner.

[System.Guid]::NewGuid()

Guid                                                                                                      ----
6e4bc22c-1ea3-4be6-b6a9-5694f0cfcaf8

Now that our pull server is up and running, we’ll need to modify our Configuration, and really all that needs to be changed is where we specify ComputerName. This time around our command looks like this

BasicWebServer -ComputerName "6e4bc22c-1ea3-4be6-b6a9-5694f0cfcaf8"

Note we passed in the GUID we just created, this is important as it will update the MOF we have locally stored with the GUID instead. If we look inside our .\BasicWebServer folder you will see a new MOF file with the GUID as the name. Now we need to create our checksum file.

New-DSCCheckSum -ConfigurationPath .\BasicWebServer -OutPath .\BasicWebServer

This result of this cmdlet is a .checksum file that is the same name as the MOF file that we just created. These two files are then copied to the pull server’s configuration directory. Once these have been copied over we can run the Configuration that configures the Local Configuration Manager.

This is run like you would run any other configuration EXCEPT, you must specify the GUID we just created, as well as the URL to the pull-server. In Part 2, our URL was not a virtual directory so we can just pass in the name of the server. If you created a virtual directory, you will need to pass in the full URL.

This particular configuration TURNS OFF SSL. I put that in caps because I think it’s important to note that DSC defaults to working over SSL only.

SetupDSCClient -NodeId "6e4bc22c-1ea3-4be6-b6a9-5694f0cfcaf8" -PullServer "webserver01"

Now, every 30 minutes your client will communicate with your pull-server and make sure that all the basic web server features are available. You should remove all those features and test it out.

I had some trial and tribulation when I was first setting this up, my first obstacle was my server was 2012, so I had to install WMF 4.0. Then I needed to change my configuration to run unsecure since I didn’t want to mess with certs. Finally since there were other web sites running on the server I needed to change to a different port.

DSC Part 2

In my previous article I talked about Desired State Configuration in a more or less generic way. I provided a sample Configuration that installed the basic services needed for a web server. This Configuration could be applied locally and once applied you could manage it manually as needed.

But the cool setup what is called a pull server ( a push server can also be setup but is more complex ). A pull server is basically a web server that has been configured with the proper DSC services and setup to listen.

The main difference between something local and a pull server is the Configurations are required to use GUID’s instead of computer names. Additionally the MOF files get hashed and the hash is stored in a file named after the MOF. These two files are then uploaded to the pull server and your client ( target node ) is configured to point at the pull server.

You can define intervals such that every 30 minutes the client will check in with the pull sever to validate it’s configuration. If something is missing, it will re-apply the configuration automatically.

So, if you already ran the Configuration from part 1, then you’re already halfway there. I’ll setup through the manual process for configuring the web portion of the pull server ( keep in mind Microsoft has released some Configurations that will assist with this ). We’ll need to make sure that the DSC service is available.

The next thing we need to do is setup the web portion of the pull-server. This entails copying files, creating an Application Pool, and setting up a website.

This leaves a few manual steps left to do, adding a few lines to the web.config file and setting the newly created Application Pool’s identity to LocalSystem.

<add key="dbprovider" value="System.Data.OleDb" />
<add key="dbconnectionstr" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program Files\WindowsPowerShell\DscService\Devices.mdb;" />
<add key="ConfigurationPath" value="C:\Program Files\WindowsPowerShell\DscService\Configuration" />
<add key="ModulePath" value="C:\Program Files\WindowsPowerShell\DscService\Modules" />

These lines are added inside the appSettings section of the web.config file. These are default values and can be left as is, they define where the modules are if you need any, and where the Configurations will be stored.

The last thing you need to do is open up IIS Manager, open Application Pools and find your Application Pool in the list. Click on it, and select Advanced Settings, click on Identity and then the build button, and from the list choose LocalSystem.

Once you’re done you should be able to point your browser at your server and see an xml output

http://pullserver.company.com/PSDSCPullServer.svc/

<?xml version="1.0" encoding="utf-8" ?> 
<service xml:base="http://pullserver.company.com/PSDSCPullServer.svc/" xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
<workspace>
<atom:title>Default</atom:title> 
<collection href="Action">
<atom:title>Action</atom:title> 
</collection>
<collection href="Module">
<atom:title>Module</atom:title> 
</collection>
</workspace>
</service>

DSC Part 1

Desired State Configuration is a new feature of PowerShell 4.0 that is included out of the box with Windows 8.1 and Windows Server 2012 R2. This feature can be loaded on down-level clients by installing the Windows Management Framework 4.0.

The way it works is pretty straightforward, PowerShell 4.0 has introduced a few new keywords, one of which is Configuration. If you’ve written any PowerShell functions it operates in a similar fashion as the Function keyword. Within a Configuration you can have one or more Nodes, each Node is defined as either a string “computer name”, or a variable $Computer, or as a GUID. Within each Node you can have 0 or more resources, there are a dozen built-in resources, and you can roll your own. In addition Microsoft has just released a handful of custom resources that I’ve not played with yet.

Here is an overview of the process

The flow is very straightforward, you create a configuration and save it as a ps1. Executing the ps1 creates a new function, named for your configuration in memory. Run this new function and a subfolder is created named for the configuration and inside the folder a .MOF file is created named for the target node.

You will need to run the function in order to create the directory and proper MOF files

BasicWebServer -ComputerName webserver01

To apply that configuration to the local machine you simply run the following

Start-DSCConfiguration -Path .\BasicWebServer

This will run as a job, if you would like to see it happen, you can add –wait and –verbose to the command above and it will display everything it’s doing.

Start-DSCConfiguration -Wait -Verbose -Path .\BasicWebServer

This configuration is stored on the computer and you can test to see if the configuration has drifted any by running the following

Test-DSCConfiguration

It will return True if it’s happy or False if something is missing. This configuration is stored with the computer and survives reboots, so you can always run

Get-DSCConfiguration

That will return a collection of configurations that are to be applied to the computer. If you would like to bring the target node back in line with its configuration you simply run the following

Restore-DSCConfiguration

The end result of this command is that your server will now have all the features its supposed to have available again.