- Install Ansible on Windows - Thu, Jul 20 2023
- Use Azure Bastion as a jump host for RDP and SSH - Tue, Apr 18 2023
- Azure Virtual Desktop: Getting started - Fri, Apr 14 2023
By the end of Part 3, you understand the basic mechanics of DSC. Today, we’ll put the proverbial cherry on top of the DSC sundae (so to speak) by installing an HTTP pull server to make DSC deployment and maintenance fully automated.
Our lab environment
I have two servers in my lab:
- dc1.company.pri: Windows Server 2012 R2 domain controller, DSC administration node, will be our pull server.
- ws2012r2.company.pri: Windows Server 2012 R2 is the member server.
On each server, I downloaded and installed the latest batch of DSC resources from the TechNet Script Center. If you have any Windows Server 2008 R2 boxes that you want to add to the mix, then you’ll also install the .NET Framework 4.5 and the Windows Management Framework (WMF) 4.0 to support DSC.
How an HTTP pull server works
Recall that DSC works in a push scenario, by default, in which you use Start-DSCConfiguration to send a configuration script to one or more target nodes. In turn, these target nodes will re-check their configuration every 15 minutes.
If you’ve been following this series, you also know that we can tweak the Local Configuration Manager (LCM) on target nodes to specify different update settings. We’ll need to do just that in order to instruct my ws2012r2 server to pull configuration from dc1.
The pull server has two HTTP web services that manage (a) the configuration(s) hosted on that server; and (b) DSC compliance, from which we can periodically check whether the configurations of the nodes are in sync with the pull server. These services each listen on an “off” TCP port (in my case, 8080 for the pull server and 9080 for the compliance server).
The target nodes are assigned a globally unique identifier (GUID) that they use to poll and pull configuration from the pull server.
Are you ready? Fasten your seat belt and let’s dive in.
Installing the DSC pull server
On dc1, I fired up the Windows PowerShell ISE and built a configuration script named ConfigurePullServer.ps1. Thanks go to PowerShell MVP Don Jones and the rest of the PowerShell community for blueprinting these scripts and configurations. Although DSC is part of a generally available PowerShell release, the documentation is a bit “all over the place,” even today.
Function myFunction { $input } Get-Content d:\iso\en_windows_8_enterprise_x64_dvd_917522.iso | myFunction Configuration ConfigurePullServer { param ( [string[]]$ComputerName = "localhost" ) Import-DSCResource -ModuleName xPSDesiredStateConfiguration Node $ComputerName { WindowsFeature DSCServiceFeature { Ensure = "Present" Name = "DSC-Service" } xDscWebService PSDSCPullServer { Ensure = "Present" EndpointName = "PSDSCPullServer" Port = 8080 PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\PSDSCPullServer" CertificateThumbPrint = "AllowUnencryptedTraffic" ModulePath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules" ConfigurationPath = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration" State = "Started" DependsOn = "[WindowsFeature]DSCServiceFeature" } xDscWebService PSDSCComplianceServer { Ensure = "Present" EndpointName = "PSDSCComplianceServer" Port = 9080 PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\PSDSCComplianceServer" CertificateThumbPrint = "AllowUnencryptedTraffic" State = "Started" IsComplianceServer = $true DependsOn = ("[WindowsFeature]DSCServiceFeature","[xDSCWebService]PSDSCPullServer") } } } ConfigurePullServer -ComputerName dc1.company.pri
Do you see what this configuration script does? Three things:
- Installs the DSC service on the localhost
- Creates a pull server web service
- Creates a compliance server web service
Remember that we need to run Start-DSCConfiguration to “make it so”:
PS C:\>Start-DSCConfiguration -Path "C:\ConfigurePullServer" -Wait -Verbose
NOTE: I initially had problems running the pull server configuration script (errors and such) on my Windows Server 2012 R2 computer. To fix this, I installed KB2883200, rebooted, and ran Start-DSCConfiguration again with the -Force switch parameter. Success!
Creating a pull configuration
I’ll create a simple sample DSC configuration that installs the Windows Server Backup tool on target nodes. Here is my InstallBackup.ps1 configuration script:
Configuration InstallBackup { param ( [string[]]$ComputerName = "localhost" ) Node $ComputerName { WindowsFeature Backup { Ensure = "Present" Name = "Windows-Server-Backup" } } } InstallBackup -ComputerName ws2012r2.company.pri
After running the above script, I had a folder in the path C:\InstallBackup with a Managed Object Format (MOF) file named ws2012r2.company.pri.mof. Unfortunately, the pull server won’t accept this file. Instead, we need to generate a GUID, rename the config file, and move it to the appropriate DSC pull server folder.
First, we invoke the NewGuid() function of the GUID .NET type accelerator to make the GUID:
PS C:\> $guid = [guid]::NewGuid() PS C:\> $guid Guid ---- caa3357b-7ec4-417d-b9d4-a5c508edbc56
Second, we rename the original MOF file and move it to the following path on the pull server:
C:\Program Files\WindowsPowerShell\DscService\Configuration
A GUID is the “key” that matches a target node to a configuration MOF on the pull server.
For client-side file integrity checking, we also need a checksum file in the DSC service’s configuration folder. We use New-DscCheckSum for that:
PS C:\>New-DscCheckSum -ConfigurationPath "C:\Program Files\WindowsPowerShell\DscService\Configuration"
The previous command created a new file in my DSC pull configuration folder:
caa3357b-7ec4-417d-b9d4-a5c508edbc56.mof.checksum
Deploying the pull configuration to the target node
We’re almost done, I promise. 🙂 Here is my SetPullMode configuration script for our ws2012r2 target node:
Configuration SetPullMode { # param([string]$guid) Node ws2012r2.company.pri { LocalConfigurationManager { ConfigurationMode = "ApplyAndAutoCorrect" ConfigurationModeFrequencyMins = 15 ConfigurationID = "caa3357b-7ec4-417d-b9d4-a5c508edbc56" RefreshMode = 'Pull' DownloadManagerName = 'WebDownloadManager' DownloadManagerCustomData = @{ ServerUrl = 'http://dc1.company.pri:8080/PSDSCPullServer.svc'; AllowUnsecureConnection = 'true' } } } } SetPullMode Set-DSCLocalConfigurationManager -Computer ws2012r2.company.pri -Path "C:\SetPullMode" -Verbose
Here are some notes regarding the previous script:
- I commented out the parameter because I chose to hard-code the GUID.
- I’m using the ApplyAndAutoCorrect configuration mode to strongly enforce DSC configuration.
- I reduced the ConfigurationModeFrequencyMins interval to 10 minutes to see changes faster in my lab.
- For simplicity, I’m using HTTP instead of HTTPS (denoted by the true value for AllowUnsecureConnection).
Testing the push configuration
After you run the previous script, Windows PowerShell remoting and web services take over, and the target node will ingest the configuration and take off running. Before I sent the script, however, I wanted to ensure that ws2012r2 didn’t have Backup already installed:
PS C:\> Get-WindowsFeature -Name *backup* Display Name Name ------------ ---- [ ] Windows Server Backup Windows-Server-Backup
After sending the LCM config to the target, I verified that its settings were accurate and current:
PS C:\> Get-DscLocalConfigurationManager ActionAfterReboot : ContinueConfiguration AllowModuleOverwrite : False CertificateID : ConfigurationID : caa3357b-7ec4-417d-b9d4-a5c508edbc56 ConfigurationMode : ApplyAndAutoCorrect ConfigurationModeFrequencyMins : 15 Credential : DebugMode : {NONE} DownloadManagerCustomData : {MSFT_KeyValuePair (key = "ServerUrl"), MSFT_KeyValuePair (key = "AllowUnsecureConnection")} DownloadManagerName : WebDownloadManager LCMCompatibleVersions : {1.0} LCMState : Idle LCMVersion : 1.0 RebootNodeIfNeeded : False RefreshFrequencyMins : 30 RefreshMode : Pull
And, yes, the Windows Server Backup tool was installed. Cool beans!
PS C:\> Get-WindowsFeature -Name *backup* Display Name Name ------------ ---- [X] Windows Server Backup Windows-Server-Backup
Sweeping up the shavings
Multiple DSC target nodes can “share” the same GUID if they need to receive an identical configuration. Configuring DSC pull to work over HTTPS isn’t too difficult. Finally, you can use Server Message Blocks (SMBs) as an alternative to HTTP(S) pull. For all this information and more, check out Don’s The DSC Book. I hope you found this article useful. More power to the shell!
NewDscCheckSum code sample is missing the dash after New
Peter, thanks for the hint! I corrected it now.
Great Article!!!
3 quick questions:
#1 Does PowerShell DSC have the Report Server that shows the status, executed results etc of target nodes?
#2 Does one PowerShell DSC manage thousands of client target nodes?
#3 Must one target client node map to only mof file that is configured on the Pull Server by the UUID key? In the other words, Does more than one target client node used the same <UUID>.mof file on the DSC pull server?