In the third installment of my Desired State Configuration (DSC) series, I will explain how to deploy a DSC configuration, how to test if it matches the desired configuration, and how to remove a DSC configuration.
Avatar
Latest posts by Timothy Warner (see all)

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

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

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

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 work as expected

DSC doesnt 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.

2 Comments
  1. Avatar
    Rick 5 years ago

    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

    Configuration InstallGoogleChrome {
    	param (
        	[string[]]$MachineName = "localhost",
        	[Parameter(Mandatory)]$Language,
        	[Parameter(Mandatory)]$LocalPath
    	)
    
    Import-DscResource -ModuleName PSDesiredStateConfiguration	
    Import-DscResource -ModuleName xChrome
    
    	Node $MachineName {
    
    
                [DSCLocalConfigurationManager()]
                configuration LCMConfig { 
                RefreshMode = Push         
                ConfigurationModeFrequencyMins = 5
                ConfigurationMode = ApplyAndAutocorrect
             }
            
    		MSFT_xChrome chrome {
    			Language = $Language
    			LocalPath = $LocalPath
    		}
    
    	}
    
    
    }
    
    InstallGoogleChrome -MachineName "member66"  `
    -Language "en" -LocalPath "C:\GoogleChromeStandaloneEnterprise64.msi"

     

  2. Avatar
    Rick (Rank 1) 5 years ago

    Ok I figured out what I did wrong.

    I didn't have the NuGetProvider or DSC installed on the remote client.

    Thank you

     

    avatar

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account