We've taken a basic configuration script to create an SCCM distribution point, and using that as a reference, we've started to create our Desired State Configuration (DSC). In my last post, we verified that our syntax is good by successfully generating a .mof file, but we need to make sure that it actually works.

As I mentioned previously, I've added the remaining WindowsFeature configurations to save a little time. So now, the configuration should look like this:

Now we're going to push the configuration to our test system to verify that it works. I recommend you do this for each DSC resource that you add to your configuration (not each item you add). This way you're testing in blocks and verifying that you're configuring the resource providers correctly without throwing one giant hair-balled mess at the target all at once.

I treat DSC like I treat PowerShell…like LEGOs. I start with one piece, then add another, then another. We're doing the same here. Add a DSC resource, test it, push it, add another. Do it all over again until you have a finished product.

Setting the Local Configuration Manager

Before I once again generate a fresh .mof file, we're going to add one more thing to the mix, and that's to update the DSC Local Configuration Manager (LCM) settings. As you likely know, most Windows components that get installed require a reboot. So we want to make sure that when the configuration is finished, the LCM on the target machine will reboot the system. Before we begin, let's take a look at the default settings for the LCM on the target machine:

By default, the LCM RebootNodeIfNeeded setting is configured to False, which means no reboot will take place on this system after the configuration is applied. We want to change this to True. We can do this directly from our configuration, with the Local Configuration Manager meta configuration provider. We'll put this as our first configuration step for logical purposes:

However, it can still be embedded in the configuration script and generate the meta.mof:

/*

@TargetNode='LWINCM02'

@GeneratedBy=LWINAdmin

@GenerationDate=01/04/2016 15:18:49

@GenerationHost=LWINCM01

*/

instance of MSFT_DSCMetaConfiguration as $MSFT_DSCMetaConfiguration1ref

{

ConfigurationMode = "ApplyAndAutoCorrect";

RebootNodeIfNeeded = True;

};

instance of OMI_ConfigurationDocument

{

Version="2.0.0";

MinimumCompatibleVersion = "1.0.0";

CompatibleVersionAdditionalProperties= { };

Author="LWINAdmin";

GenerationDate="01/04/2016 15:18:49";

GenerationHost="LWINCM01";

Name="CMDPConfig";

};

Although we have the LCM configuration in the same script, we'll have to use a separate command to push the update to the LCM.

Pushing the configuration

Let's push our configuration to the target machine. We'll use Set-DscLocalConfigurationManager to run the meta configuration, and pipe the output to Start-DscConfiguration to kick the system configuration:

We can see that the LCM RebootNodeIfNeeded meta configuration is set to True, and that the system is processing a new configuration. If we want to take a look at where the system is in the configuration, we can check the DSC Operational Event Logs. Note that I don't yet have all of the firewall rules in place to allow RPC calls between these systems. I'll be handling that in the next bit. But for now, I'll just wrap this up by using Invoke-Command:

I've done some filtering so I can see my last information message. Unfortunately, before I could run another command to expand the Message property, the system rebooted. But that also means that things are working! So we'll take a look after the reboot and see how the system looks.

What's the first thing we look for? Well, we told the server to remove its UI, so let’s see what happened…

Success!

Verifying the configuration

We could go through each individual setting manually and verify the configuration, or we could do it the DSC way with Test-DscConfiguration. There are a few ways to do this, and I'll quickly go through them.

PS C:\Windows\system32> Test-DscConfiguration -ComputerName lwincm02

True

Running Test-DscConfiguration against the target returns a simple True or False statement. This is OK if you only want to make sure that your configuration is fully compliant, but we get no data from it. So let's use the -Detailed parameter:

What I like about this format is that each configuration item gives you the name of the configuration that applied the setting, the module it's using, and dependencies if you've configured them. There's a wealth of other information in here!

We can also go through the DSC Operational event logs and mine for the data that we want, and maybe set up alerts if the system drifts from its configuration. But for now, we have validation that the system is correctly configured.

Now that we've used one of the out-of-the-box DSC resources and done some basic configurations, we're going to move on to finding and importing additional DSC resources. We'll also cover using the Script DSC resource, and weigh the pros and cons of using this resource over creating your own DSC resources.

‘Til next time!

~Will

Thanks, Will, for another great installment of this series. Will will be back tomorrow with Part 5.

Thanks for the series on DSC.
Is it possible to apply multiple configurations on a single machine? E.g. I would like to add a C:Tools directory with some programs in it and as a second DSC configure the machine as a web server. Can I manage these simultaneously?

As far as rolling back a DSC config, there is Restore-DscConfiguration. This allows you to rollback to a previous configuration, however, if there’s never been a configuration applied, it won’t work. I actually decided to test this on one of my boxes and got
an error:

I suppose you could deploy a dummy config (like add a file and be done with it) so you have something to roll back to, but I would argue that if you’re using a solid test-deploy process, you’d catch any potential issues in your non-prod environment and be able
to correct them before doing any damage in prod.