Blog

The musings of an independent consultant specialising in the intersection of DevOps and ALM.

Configuring PowerShell DSC Pull Mode

After a few weeks preoccupation on non-tech stuff I finally got some time to go back to my playtime with Desired State Configuration. However, now the RTM version of Windows Server 2012 R2 is now available so I thought it sensible to use the latest bits.

I was really interested in getting the Pull Mode functionality working, as this simplifies the process of distributing your custom DSC Resource Providers (amongst other benefits). If you want to know more about Pull mode then I'd recommended checking-out some of these links:

Between the general lack of documentation covering how to do this and the various changes between the Preview and RTM versions (obsoleting much of what documentation did exist), this turned out to be a bit of a battle.

Getting Started

I used the TechEd demoes as my starting point, they are available here:

Specifically I downloaded the Windows 2012 R2 Preview demos http://blogs.msdn.com/cfs-file.ashx/_key/communityserver-blogs-components-weblogfiles/00-00-00-63-74-metablogapi/3124.Demo5F00WindowServer2012R22D00Preview5F00_4677B514.zip, once unzipped you should have the following directory structure:

DSC-Pull-DemoFolders.png

Updating the Scripts for Windows Server 2012 RTM

Navigating to PullServer\Setup\Scripts you should see:

DSC-Pull-SetupScripts.png

This provides a script for installing the web-based PullServer, however, due to the changes between Preview and RTM the InstallPullServerConfig.ps1 requires some changes to work correctly.

In the RTM release a DLL has been renamed from Microsoft.Powershell.DesiredConfig.PullServer.dll to Microsoft.Powershell.DesiredStateConfiguration.Service.dll, so the reference to it in InstallPullServerConfig.ps1 at line 57 must be updated:

Before:

-dependentBinaries "$pathPullServer\Microsoft.Powershell.DesiredConfig.PullServer.dll"

After:

-dependentBinaries "$pathPullServer\Microsoft.Powershell.DesiredStateConfiguration.Service.dll"

Install the Pull Server Components

Having made the above change and saved the script, you can now run it:

.\InstallPullServerConfig.ps1 -DSCServiceSetup

The -DSCServiceSetup switch tells the script to install the 'DSC-Service' Windows Feature (and associated dependencies).

After a couple of minutes the script should complete and you will be left with fully-configured PullServer setup in IIS - although the IIS management tools are not installed, but you can check that the new site is there using Get-WebSite:

DSC-Pull-PullWebSite.png

Adding Content to the Pull Server

The Pull Server will offer 2 types of content for download:

  • Server configurations: the .mof files generated when executing a DSC configuration script
  • Packaged DSC resources - specially crafted .zip files (and I mean special!)

These files need to be placed in the relevant folder under the following location:

DSC-Pull-ContentDir.png

Let's create a simple DSC configuration script that uses the Demo_Computer custom DSC Resource from the Windows 2012 R2 Preview demos downloaded earlier.

Setup your Dev Environment

NOTE: These steps assume that you are doing your DSC development on Windows 8.1 RTM or Windows Server 2012 R2 RTM (not the preview versions).

In order to generate a configuration script using the Demo_Computer resource we need to do the following:

  1. copy <extractPath>\PreReq\Resources\Demo_Computer $PSHome\Modules\PSDesiredStateConfiguration\PSProviders\Demo_Computer -recurse
  2. cd $PSHome\Modules\PSDesiredStateConfiguration\PSProviders\Demo_Computer
  3. Changes in the RTM version mean we have to patch the Demo_Computer.schema.mof file in the above folder, the following script fragment should do the job:

Now we can create a simple configuration script that references the custom resource:

As per usual, executing the above will give us the generated .mof configuration file inside a folder called 'PullDemo' with the filename Server01.mof.

Prepare the Server(s) to be Managed via DSC Pull Mode

Each machine that needs to use the Pull Server needs to be configured accordingly as well as being allocated a unique identifier (i.e. a GUID). For the purposes of this example I'm just going to assign an arbitrary GUID, however, Johan Åckerström (@Neptune443) has a nice example of using an Active Directory value which could be useful for domain machines that already have a machine domain account http://blog.cosmoskey.com/powershell/desired-state-configuration-in-pull-mode-over-smb/.

This was another area that needed some experimentation after having issues with what was in the Windows 2012 R2 Preview demos. I started with this:

... and eventually ended-up with the following which worked for me (I highly recommend the above linked blog post for more detailed information about these settings):

NOTE: If you are using non-domain connected machines then you may get a WinRM authentication error when trying to run the above (even if you have matching credentials on both machines). You will need to add the remote machine to your WinRM Client's TrustedHosts property:

set-item WSMan:\localhost\Client\TrustedHosts * -force

If all has gone well you should see output similar to this:

DSC-Pull-PrepareServer.png

Preparing the Assets for the Pull Server

As mentioned earlier the pull server will host the generated .mof configuration files for each server and the custom resources, however, each needs to be packaged in a particular way for things to work properly.

Rename the .mof file to match the GUID for the server it relates to:

  1. copy PullDemo\Server01.mof C:\ProgramData\PSDSCPullServer\Configuration\e528dee8-6f0b-4885-98a1-1ee4d8e86d82.mof

  2. Create a checksum file for the above file - the remote server seems to use this file for two purposes:

    • determine whether the configuration file has changed since the last Pull
    • rudimentary validation of the configuration file (i.e. not corrupted during the download etc.)
    • NOTE: If you update the configuration but do not update the checksum then the remote server assumes the configuration file is unchanged.
  3. Package each custom resource into its own ZIP file and copy it to C:\ProgramData\PSDSCPullServer\Modules

  4. Create a checksum file for each of the above ZIP files

The following script will handles steps 2-4:

Run the above script like this:

.\PublishToPullServer.ps1 -resources $PSHome\Modules\PSDesiredStateConfiguration\PSProviders\Demo_Computer

... and it populates the Pull Server area as shown below:

DSC-Pull-ContentFiles.png

Testing It

You can manually force a remote machine to perform a pull using a script provided as part of the Windows Server 2012 R2 Preview Demos, it can be found here:

<extractPath>\PullServer\Invoke-PullonNode.ps1

However, this also needs to be patched to work with the RTM version as the required CIM method has been renamed:

Before:

After:

It is a short script that just requires the name of the remote machine on which to trigger a pull:

.\Invoke-PullonNode.ps1 -computerName Server01

DSC-Pull-InvokePullOutput.png

If you have a poke around the remote machine you'll notice that the DSC resources downloaded from the Pull Server are not installed alongside the the built-in ones, instead they are placed in C:\Program Files\WindowsPowerShell\Modules (which seems to be the new trend I've noticed recently for where to install system modules):

dir 'C:\Program Files\WindowsPowerShell\Modules'

    Directory: C:\Program Files\WindowsPowerShell\Modules

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        01/10/2013     20:07            Demo_Computer

You don't get the same level of output when triggering a Pull operation, however, you can track any errors etc. by querying the event log on the remote machine:

Get-WinEvent -ProviderName Microsoft-Windows-DSC -ComputerName NewHostName | select TimeCreated,LevelDisplayName,Message -first 10 | ft -Wrap -AutoSize

That's about it, I'd be really interested to hear if this works for you or whether I've inadvertently glossed over something specific to my lab environment that makes it work.