- 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
Hey, everyone! I’m sorry that I’ve been away from 4sysops for so long. Where did we leave off in this mini-series on Windows PowerShell Desired State Configuration (DSC)? First of all, if you haven’t already done so, make sure to go back and read Parts 1 and 2:
Ah, yes—today, we’re concerned with DSC deployment!
Revisiting our lab environment
In my lab environment, I have two Windows Server 2012 R2 computers:
- dc1.company.pri: domain controller, DSC administration node
- adfs1.company.pri: member server, DSC target node
Between writing Part 2 and today’s post, I added a local configuration manager (LCM) section to our InstallGoogleChrome.ps1 configuration file. Here, take a look at my entire script:
Configuration InstallGoogleChrome { param ( [string[]]$MachineName = "localhost", [Parameter(Mandatory)]$Language, [Parameter(Mandatory)]$LocalPath ) Import-DscResource -Module xChrome Node $MachineName { LocalConfigurationManager { ConfigurationModeFrequencyMins = 5 ConfigurationMode = "ApplyAndAutocorrect" } MSFT_xChrome chrome { Language = $Language LocalPath = $LocalPath } } } InstallGoogleChrome -MachineName "adfs1" ` -Language "en" -LocalPath "C:\Windows\Temp\GoogleChromeStandaloneEnterprise.msi"
You’ll observe in the LocalConfigurationManager block that I lowered the value for ConfigurationModeFrequencyMins so I can test DSC’s autocorrection without having to wait…and wait…and wait some more. Of course, in a production environment, you’ll want to experiment to find a balance between compliance and performance.
When I ran the configuration script, I found two MOF files in the C:\InstallGoogleChrome folder:
- adfs1.mof
- adfs1.meta.mof
The meta file contains our client “meta” LCM configuration settings.
Deploying a DSC configuration
We use the Start-DSCConfiguration cmdlet to initiate a DSC configuration process. Watch this:
Start-DSCConfiguration –Path "C:\InstallGoogleChrome" -Wait -Verbose
The –Wait and –Verbose options are useful when we’re troubleshooting DSC and/or we want to see everything that DSC does during the configuration process. Be mindful of –Wait, though, because it can tie up your PowerShell session for a long time depending upon your DSC resource load.
Now, let’s switch over to adfs1, our target node, and see what happened. The following screenshot is boring until we remember that DSC silently installed Chrome and is enforcing its configuration!
With DSC, we installed and monitored Google Chrome installation with no need for System Center.
Testing DSC AutoCorrection
Recall in our DSC configuration script that I added a client meta-config block that included the following two statements:
ConfigurationModeFrequencyMins = 5 ConfigurationMode = "ApplyAndAutocorrect"
The ConfigurationModeFrequencyMins parameter defines how long the client waits, in minutes, before the LCM verifies that it is in the desired state.
The ConfigurationMode parameter can be set to ApplyOnly (which applies the configuration once and does no further checking), ApplyAndMonitor (which applies the configuration and audits changes), or ApplyAndAutoCorrect (which we want).
We can use Test-DSCConfiguration on our admin server to remotely check compliance of adfs1. Note that we need to build a Common Information Model (CIM) session with the remote target before we can run the cmdlet:
$session = New-CIMSession -ComputerName adfs1 Test-DSCConfiguration -CimSession $session InDesiredState PSComputerName -------------- -------------- True adfs1
I’ll now pretend that I’m a grumpy systems administrator who personally feels that Chrome doesn’t belong on a member server. Let’s uninstall Chrome by using the Programs and Features Control Panel, as shown in the following image:
I know better than DSC...or do I?
We’ll test compliance again:
Test-DSCConfiguration -CimSession $session InDesiredState PSComputerName -------------- -------------- False adfs1
Uh oh! We have potential configuration drift! Not to worry, however—within five minutes, my adfs1 box silently brought itself back into compliance:
DSC autocorrection mitigates configuration drift.
Editing or removing an existing configuration
Let’s say that we wanted to make the following configuration changes on adfs1:
- Adjust the configuration check frequency to 10 minutes.
- Ensure that the DHCP Server and IIS Web Server server roles and the ASP.NET components are always present.
- Remove Google Chrome.
To accomplish these goals, we need to edit our configuration script for adfs1. Remember that, in Windows PowerShell DSC, each node can have only one configuration. Right now, we have InstallGoogleChrome.ps1 that targets adfs1; so, for convenience, we’ll edit that one.
First, here’s the source code:
Configuration ConfigureADFS1 { param ( [string[]]$MachineName = "localhost" ) Node $MachineName { LocalConfigurationManager { ConfigurationModeFrequencyMins = 10 ConfigurationMode = "ApplyAndAutocorrect" } WindowsFeature IIS { Ensure = "Present" Name = "Web-Server" } WindowsFeature ASP { Ensure = "Present" Name = "Web-Asp-Net45" } WindowsFeature DHCPSERVER { Ensure = "Present" Name = "DHCP" } } } ConfigureADFS1 -MachineName "adfs1"
Second, I’ll explain the changes:
- Changed the configuration name to something more meaningful.
- Edited the LocalConfigurationManager values to reflect a longer interval.
- Removed all references to Chrome from the script, including the parameter. declarations, the resource block, and the function call.
- Added resource blocks for IIS, ASP.NET, and DHCP. You can learn the syntax for DSC resources by checking the documentation.
After I ran the script and initiated the configuration, I was a bit taken aback by the results shown in the following screenshot:
DSC doesn’t always act as expected.
The presence of the DCHP Post-Install Configuration Wizard is a welcome sight and verifies that DSC installed the server role correctly. But what about the Google Chrome icon on the Windows Desktop? Why didn’t removing any reference to the Chrome DSC resource in our configuration script implicitly remove the software from our target node?
You need to understand DSC makes no assumptions. In other words, you have to explicitly “tell” DSC what to do with configured resources in your source script. So in this case, we could manually remove Chrome from adfs1 and take comfort that DSC won't reinstall because the config script doesn't reference Chrome.
A more formal way to go would be to keep the Chrome resource in the script, but use the following statement to ensure its removal:
Ensure = "Absent"
Next steps
In the fourth installment of this Desired State Configuration (DSC) series, we’ll see how to set up a DSC pull server. If you’re thinking about this stuff at depth, I’m sure you wondered “How can I automate DSC automation?”
So actually, what I’ll do next, in addition to covering DSC pull server, is show you how to target multiple nodes with your DSC configuration scripts. Sound good? We’ll see you then.
I'm not sure what I'm doing wrong. I can see the job running but nothing happens.
PS C:\> Test-DSCConfiguration -CIMSession $session
WARNING: [MEMBER66]: [] The TEST operation will be carried against a pending configuration since the latest configuration has not converged yet.
The PowerShell DSC resource MSFT_xRemoteFile from module <xPSDesiredStateConfiguration,8.6.0.0> does not exist at the
PowerShell module path nor is it registered as a WMI DSC resource.
+ CategoryInfo : InvalidOperation: (root/Microsoft/…gurationManager:String) [], CimException
+ FullyQualifiedErrorId : DscResourceNotFound
+ PSComputerName : member66
Ok I figured out what I did wrong.
I didn't have the NuGetProvider or DSC installed on the remote client.
Thank you