Monday, 13 November 2017

Learn PowerShell DSC - Part 6

Introduction

In Part 5, started looking at DSC Pull using an SMB share. If you need a refresher, click here. In this part, we’ll run through the setup of HTTP/HTTPS pull which is a little more complex but makes life a little easier especially as it requires fewer firewall ports open and is more secure.

Other parts in this series:

What is DSC HTTP/HTTPS Pull?

HTTP/HTTPS pull allows you to store your DSC configurations (.MOF) on a web server which the target machines can connect to, download and apply their configurations. They do this over the standard ports: TCP port 80 for HTTP and TCP port 443 for HTTPS.

The setup steps we will run through are:

  1. Install the required DSC module on the DSC pull server
  2. Install a certificate on the DSC pull server
  3. Create a DSC configuration to deploy the DSC pull server
  4. Create a MOF file
  5. Deploy the DSC configuration to the DSC pull server

The steps are almost the same whether you want to set up an HTTP or an HTTPS pull server but there are some differences.

Set up a DSC HTTP/HTTPS pull server

1) Install the required DSC module on the DSC pull server

We need to use some of the DSC Resources which are available in the xPSDesiredStateConfiguration DSC module which is not included in Windows. To install this module, we run the command:

Install-Module xPSDesiredStateConfiguration

2) Install a certificate on the DSC pull server

The next step is to install a certificate on the HTTPS pull server. If you don’t need to have encrypted traffic and therefore don’t need to use HTTPS then you can skip this step. The certificate needs to have the correct Subject Name. Now, adding the certificate

In my case, my DSC pull server is called contchidsc01.contoso.com so this is what I need on my certificate. I’ll just confirm that contchidsc01 has a certificate with the correct subject:

Enter-PSSession contchidsc01
Get-ChildItem Cert:\LocalMachine\My\ | fl Thumbprint,Subject

image

We also need to note down the certificate thumbprint as we’ll need this in the next step. In my case it’s F8E20068359E75922F3EC35F58282C348D4511CF.

3) Create a DSC configuration to deploy the DSC pull server

The most interesting part! Deploying a DSC pull server requires a number of steps and so we’ll use DSC to configure the DSC pull server. The steps are below:

The full DSC configuration we need is below:

configuration HTTPSPullServer
    {
        Param (
            [Parameter(Mandatory = $true)]
            [string] $ComputerName,
            [ValidateNotNullOrEmpty()] 
            [string] $certificateThumbPrint,
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string] $RegistrationKey
        )

        Import-DSCResource -ModuleName xPSDesiredStateConfiguration
        Import-DSCResource -ModuleName PSDesiredStateConfiguration

        Node $ComputerName
            {
                WindowsFeature DSCServiceFeature
                    {
                        Ensure = "Present"
                        Name   = "DSC-Service"
                    }

                WindowsFeature IISConsole 
                    {
                        Ensure = "Present"
                        Name   = "Web-Mgmt-Console"
                    }

                xDscWebService PSDSCPullServer
                    {
                        Ensure                  = "Present"
                        EndpointName            = "PSDSCPullServer"
                        Port                    =  443
                        PhysicalPath            = "$env:SystemDrive\inetpub\wwwroot\PSDSCPullServer"
                        CertificateThumbPrint   =  $certificateThumbPrint
                        ModulePath              = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
                        ConfigurationPath       = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
                        State                   = "Started"
                        UseSecurityBestPractices=  $false
                        DependsOn               = "[WindowsFeature]DSCServiceFeature"
                    }

                File RegistrationKeyFile
                    {
                        Ensure          = 'Present'
                        Type            = 'File'
                        DestinationPath = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt"
                        Contents        = $RegistrationKey
                    }
            }
    }

Let’s go through what this actually does.

This first part collects parameters for the ComputerName, certificateThumbPrint and the RegistrationKey when we run the configuration to create a MOF file:

        Param (
            [Parameter(Mandatory = $true)]
            [string] $ComputerName,
            [ValidateNotNullOrEmpty()] 
            [string] $certificateThumbPrint,
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string] $RegistrationKey
        )

  • ComputerName = The name of the target machine which we will configure to be a DSC HTTP/HTTPS pull user
  • certificateThumbprint = The thumbprint of the certificate which we installed on the DSC pull server
  • RegistrationKey = A key which target machines will use to do the initial registration with the pull server. After this initial registration, the target machine will generate a self-signed certificate which will be used to authenticate with the pull server.

This next part installs the DSC Service and IIS Management Console Windows features we need installed on our pull server:

                WindowsFeature DSCServiceFeature
                    {
                        Ensure = "Present"
                        Name   = "DSC-Service"
                    }

                WindowsFeature IISConsole 
                    {
                        Ensure = "Present"
                        Name   = "Web-Mgmt-Console"
                    }

The next part configures the DSC Web Service so that it works as a pull server. We need to specify a number of parameters here:

  • Port = Port number to use for the pull server.
  • PhysicalPath = Path on disk for the virtual directory that will be set up in IIS.
  • CertificateThumbprint = The certificate thumbprint for the certificate we installed on the pull server. As we have a parameter for this, we’ll set this to $certificateThumbPrint in the configuration. If you don’t want to use HTTPS then you can set this value to “AllowUnencryptedTraffic” and the pull server will use HTTP.
  • ModulePath = The path where DSC modules will be stored. The target machines can download any required modules if they don’t already have these installed.
  • ConfigurationPath = The path where DSC configurations will be stored.

                xDscWebService PSDSCPullServer
                    {
                        Ensure                  = "Present"
                        EndpointName            = "PSDSCPullServer"
                        Port                    =  443
                        PhysicalPath            = "$env:SystemDrive\inetpub\wwwroot\PSDSCPullServer"
                        CertificateThumbPrint   =  $certificateThumbPrint
                        ModulePath              = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
                        ConfigurationPath       = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"
                        State                   = "Started"
                        UseSecurityBestPractices=  $false
                        DependsOn               = "[WindowsFeature]DSCServiceFeature"
                    }

The final part of the configuration is to store the registration key in a text file. We use the File DSC Resource to create a new text file and set the contents to $RegistrationKey

                File RegistrationKeyFile
                    {
                        Ensure          = 'Present'
                        Type            = 'File'
                        DestinationPath = "$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt"
                        Contents        = $RegistrationKey
                    }

4) Generate the MOF file

To generate our MOF file, we need to specify our parameters:

  • ComputerName = contchidsc01
  • certificateThumbprint =  F8E20068359E75922F3EC35F58282C348D4511CF 
  • RegistrationKey =  (New-Guid).Guid

We then call our configuration, specify the output path and the parameters:

HTTPSPullServer -OutputPath C:\DSC\HTTPS -ComputerName contchidsc01 `
-certificateThumbPrint F8E20068359E75922F3EC35F58282C348D4511CF -RegistrationKey (New-Guid).Guid

5) Deploy the DSC configuration to the DSC pull server

The final step is to deploy the DSC configuration to the pull server using Start-DscConfiguration:

Start-DscConfiguration -Path C:\DSC\HTTPS -Verbose -Wait

If we use the -Verbose and -Wait parameters, we can see detailed output as below:

image

image

6) Test the configuration

Before moving on, let’s just test our configuration. We can do this using Test-DscConfiguration and we can see that contchidsc01 is in the desired state:

Test-DscConfiguration -Path C:\DSC\HTTPS

image

We can also see the PSDSCPullServer virtual directory in IIS:

image

….and we can confirm that our Registration Key was saved to the file we specified:

image

We’ll move on to configuring a target machine to use the new pull server.

Configure a target machine to use our DSC HTTPS pull server

We need to configure our target machine Local Configuration Manager (LCM) with the DSC pull server URL and the registration key so it can complete the initial registration.

We’ll be configuring our target machine contchich01. In this configuration, we’re specifying the settings below:

  • ConfigurationID: This is the ID of the LCM on the target machine and is used to find the correct configuration to apply as there may be many configurations for other machines on the same pull server
  • RefreshMode: This sets our LCM to pull instead of push which is the default
  • ConfigurationRepositoryWeb ServerURL: This is the URL of the pull server
  • ReportServerWeb ServerURL: This is the URL of the pull server
  • RegistrationKey: We specify this for both the report server and the configuration repository so the target machine can register against the pull server

[DSCLocalConfigurationManager()]
configuration ConfigurePullClient
{
     Param (
        [Parameter(Mandatory = $true)]
        [string] $ComputerName,
        [Parameter(Mandatory = $true)]
        [string] $RegistrationKey,
        [Parameter(Mandatory = $true)] 
        [string] $GUID
     )

    Node $ComputerName
    {
        Settings
        {
            RefreshMode          = 'Pull'
            ConfigurationID = $guid
        }

        ConfigurationRepositoryWeb CONTOSO-PullSrv 
        {
            ServerURL          = 'https://contchidsc01.contoso.com/PSDSCPullServer.svc/'
            RegistrationKey    = $RegistrationKey
        }  

        ReportServerWeb CONTOSO-PullSrv 
        {
            ServerURL       = 'https://contchidsc01.contoso.com/PSDSCPullServer.svc/'
            RegistrationKey =  $RegistrationKey
        }
    }
}

Once we have the LCM configuration, we need to push this out specifying the RegistrationKey, ComputerName and a GUID for the ConfigurationID:

$RegistrationKey = Get-Content '\\contchidsc01\c$\Program Files\WindowsPowerShell\DscService\RegistrationKeys.txt'

$ComputerName = "contchich01"
$GUID = (New-Guid).Guid
ConfigurePullClient -ComputerName $ComputerName -RegistrationKey $RegistrationKey -OutputPath C:\DSC\Configs -GUID $GUID

Next, we need to set the LCM using Set-DscLocalConfigurationManager:

Set-DscLocalConfigurationManager -ComputerName $ComputerName -Path C:\DSC\Configs -Verbose

image

We then run these commands to confirm the configuration:

$Settings = Get-DscLocalConfigurationManager -CimSession $ComputerName 
$Settings | fl PSComputerName,RefreshMode,RefreshFrequencyMins,RebootNodeIfNeeded,ConfigurationID
$Settings.ConfigurationDownloadManagers[0]

image

As you see above, we have the LCM set to pull and the ServerURL set to our new pull server.

Create a DSC configuration for an HTTPS pull target machine

This is basically the same as creating a normal DSC configuration but instead of naming the mof file according to our target machine i.e. contchich01.mof, we need to name it using the ConfigurationID of the LCM. The simple configuration is below and this creates a test file on the C drive called testfile.txt:

Configuration TestDSCPull {
   
    Param (
    [Parameter(Mandatory=$true)]
    [string]$ComputerName
    )
   
    Import-DscResource -ModuleName PSDesiredStateConfiguration

    Node $ComputerName {
   
        File TestFile {

            DestinationPath = 'C:\testfile.txt'
            Type = 'File'
            Ensure = 'Present'
            Contents = 'Test file contents'
            }
        }

}

Create your MOF file as normal:

$ComputerName = "contchich01"
TestDSCPull -ComputerName $ComputerName -OutputPath C:\DSC\Configs

In the next section, we get the ConfigurationID from the target machine and then copy the MOF file over to the configuration repository on the DSC pull server and rename it to <guid>.mof:

$guid=(Get-DscLocalConfigurationManager -CimSession $ComputerName).ConfigurationID
$DestinationFile = '\\contchidsc01\c$\Program Files\WindowsPowerShell\DscService\Configuration\' + $guid + '.mof'
copy C:\DSC\Configs\$ComputerName.mof $DestinationFile -Force

We also need a checksum file so create one using New-DscChecksum (use -Force to overwrite a checksum if there is already one there):

New-DscChecksum $DestinationFile -Force

To get the machine to pull the configuration, we then use Update-DscConfiguration:

Update-DscConfiguration -ComputerName $ComputerName -Wait -Verbose

image

…..and there we have it, the target machine pulled the configuration and we can confirm the test file exists and that the contents are correct:

image

Conclusion

If you’ve made it this far then take a break - you deserve it! It takes a little bit of time to get it all set up but once you’re done, all your servers can be configured to automatically pull their configuration from the pull server and you have a central repository for your configurations so all you have to do is create configurations.

No comments:

Post a Comment