Creating a Desired State Configuration Pull Server

2015-10-07T17:30:00Z

Previously I've discussed using DSC in a push configuration where by an administrator applies configuration changes to a node by compiling a DSC script into a MOF (Managed Object File) and running Start-DSCConfiguration against a target node from their workstation.

Pushing DSC configuration is hardly zero-touch as it relies on someone somewhere to do something. If you want nodes to automatically retrieve and apply their configuration changes, you need a DSC pull server.

I'm currently tasked with implementing a DSC Pull server to provision our developer workstations. This article covers what I've learned thus far when it comes to running a DSC pull configuration. If you're following this as a tutorial, your DSC pull server will be a running at Windows Server 2008 r2 with at least Windows Management Framework 4.0 installed.

Installing and Configuring the DSC Pull Server

We will use a DSC script that will configure a DSC pull server. Before we do so, we need to install the required DSC Resources. You will need to download and install the xPSDesiredStateConfiguration module. If you aren't sure how to do this, have a look at the resources section section in the previous article. Don't forget you need to make this DSC resource available on both your DSC pull server and the workstation from which you will be applying the configuration.

Once you have that module installed, you can use a PowerShell to install the DSC Web Service and configure your DSC pull server. Firstly run the following script to define a DSC configuration. (Hint: If you have the script file saved, you can run it by dot sourcing the script file, e.g. . ./myDscScripts/DSCPullServer.ps1)

Configuration DSCPullServer
{       
    Import-DSCResource -ModuleName xPSDesiredStateConfiguration

    Node <YourDSCServer>
    {
        WindowsFeature DSCServiceFeature
        {
            Ensure = "Present"
            Name = "DSC-Service"
        }

        xDscWebService  DSCPullServer
        {
            Ensure = "Present"
            EndPointName = "DSCPullServer"
            Port = 8080
            PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\DSCPullServer"
            CertificateThumbPrint = "AllowUnencryptedTraffic"
            ModulePath = "C:\DSCPullServer\Modules"
            ConfigurationPath = "C:\DSCPullServer\Configuration"
            State = "Started"
            DependsOn = "[WindowsFeature]DSCServiceFeature"
        }

        xDscWebService  DSCComplianceServer
        {
            Ensure = "Present"
            EndPointName = "DSCComplianceServer"
            Port = 8081
            PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\DSCComplianceServer"
            CertificateThumbPrint = "AllowUnencryptedTraffic"
            State = "Started"
            IsComplianceServer = $true
            DependsOn = "[WindowsFeature]DSCServiceFeature"
        }
    }
}

Substitute <YourDSCServer> for the name of the server that will run your DSC Service. Note that at this stage, we're setting up our server to use an unencrypted HTTP web service.

Run the above DSC configuration to create a managed object file:

PS \> DSCPullServer

Then apply your configuration with the Start-DSCConfiguration commandlet:

PS \> Start-DSCConfiguration -Path .\DSCPullServer -verbose -wait

Once the configuration job is complete, you should have a working DSC pull server. You can check this quickly and easily using a web browser:

1

Creating DSC Configuration

At this stage we're ready to create a DSC configuration file that will be applied to a nodes configured to use the push server to obtain its configuration. My starting point might be a simple DSC script that installs IIS:

Configuration IisWebServer
{
    Node 8f5016dc-052c-4a01-9c84-8dcea37c9ab1 
    {
        WindowsFeature IIS
        {
            Ensure="Present"
            Name="Web-Server"
        }
        WindowsFeature Mgmt-Tools 
        {
            Ensure  = "Present"
            Name    = "Web-Mgmt-Tools" 
        }
        WindowsFeature Mgmt-Console 
        {
            Ensure  = "Present"
            Name    = "Web-Mgmt-Console" 
        }
        WindowsFeature Mgmt-Service 
        {
            Ensure  = "Present"
            Name    = "Web-Mgmt-Service" 
        }

    }
}

You will notice one distinct difference between this DSC script and those created in the last article for use in the push configuation. Instead of "Node" specifying the hostname of target computer name, I'm using a GUID. You will see how this is used later, but in the meantime generating a GUID for use in a pull configuration is quick and easy using PowerShell:

PS \> [guid]::NewGuid()
8f5016dc-052c-4a01-9c84-8dcea37c9ab1

We now need to create a managed object file from our configuration. Simply execute the DSC script (by either pressing F5 in the PowerShell Integrated Scripted Environment or dot sourcing in the script file, as per the earlier example). Then execute the dsc function:

PS \> IisWebServer

This will create a folder in your current directory called "IisWebServer". The folder will contain a managed object file named for the GUID used in your DSC script. Now we need to create a checksum that we will store with our managed object file.

PS \> New-DSCChecksum -ConfigurationPath .\IisWebServer -OutPath .\IisWebServer -Verbose -Force

Now we can copy the configuration file and the checksum to the DSC Pull Server

PS \>  Copy-Item -Path .\IisWebServer\* -Destination \\win2k12r2-dc1\c$\DSCPullServer\Configuration\

Configuring a Node to use the DSC Pull Server

Finally, we need to tweak the local configuration manager on a DSC client node to use the pull server we've just set-up. For this we write another DSC script:

Configuration SetPullMode
{
    Node <NodeName>
    {
        LocalConfigurationManager
        {
            ConfigurationMode = 'ApplyAndAutocorrect'       # Necessary to push updates to the compliance server
            RefreshFrequencyMins = 5                        # For testing purposes - means we don't have to wait
                                                            # too long to see results in the compliance server
            ConfigurationID = "8f5016dc-052c-4a01-9c84-8dcea37c9ab1"
            RefreshMode = ‘Pull’
            DownloadManagerName = ‘WebDownloadManager’
            DownloadManagerCustomData = @{
                ServerUrl = ‘http://PullServerName>/PSDSCPullServer.svc/’;
                AllowUnsecureConnection = ‘true’ }
            AllowModuleOverwrite = 'True'                   # Prevent errors when refreshing modules
        }
    }
}
PS \>  SetPullMode
PS \>  Set-DSCLocalConfigurationManager –ComputeName <NodeName> -Path ./SetPullMode –Verbose

There's a few things to note here:

Five or so minutes after configuring our DSC client to use the pull server, we should be able to check back and see that the IIS role has been installed.

Further Questions

Having read and experimented this far with a DSC Pull Server, you like me probably have a number of questions. Here are some of the questions I'll be trying to answer before implementing a DSC Pull Server to provision a suite of developer workstations: