Desired State Configuration (DSC) in Windows PowerShell v4 is creating quite a buzz, and for good reason. In my opinion, DSC will likely become the de facto way we Windows systems administrators manage our servers.
Latest posts by Timothy Warner (see all)

My goals in writing this blog post are twofold. First, I want to give you a nutshell summary of how DSC can help your business. Second, I want to explain how DSC configuration works at an architectural level. In subsequent blog posts, I’ll walk you through a practical example so you can translate theory into action.

DSC business goals

Have you ever heard of “configuration drift”? Although you may not yet be familiar with this term, I’m sure you’ve observed the net result of configuration drift in your organization. I’m talking about server configuration settings that change over time, typically by the “Not Me” ghost from Bil Keane’s Family Circus cartoon.

For instance, you might have SQL Server database servers that need to maintain static configurations for stability and security reasons. Over time, you notice that other administrators have “tweaked and tuned” the servers over months and years such that their configuration is no longer in line with the IT department’s requirements.

The bottom line is that, when our servers fall out of compliance, they reduce system security and potentially open up your business to service level agreement (SLA) violations and potentially legal ramifications. How in the world can we configure our servers and enforce their settings?

What about Group Policy?

You may have answered my previous question with, “I use Group Policy to enforce server configuration.” That’s well and good, but, in my experience, even Group Policy Objects (GPOs) suffer configuration drift. Moreover, GPOs are typically difficult to manage and troubleshoot, especially for larger organizations with disparate configuration requirements.

Back in the Windows NT days, we had System Policy, whose settings permanently “tattooed” target systems’ Registries. GPOs, on the other hand, can be selectively applied and their settings overridden, blocked, or removed with a couple of mouse clicks.

Introducing Desired State Configuration

Thus far, I’ve introduced some IT-related business problems and briefly outlined why Group Policy isn’t the “be all, end all” solution to those issues. I’m obviously leading you in the direction of DSC. What is this new technology, anyway?

DSC completes the Windows PowerShell vision outlined by PowerShell creator Jeffrey Snover in his 2002 white paper “The Monad Manifesto.” With DSC, we have a declarative model for system configuration management.

“Declarative” means that we can literally specify how we want a server to look, and we let Windows PowerShell and the Windows Workflow engine “make it so” on target nodes. By contrast, imperative configuration management requires that we spell out, step by step, how a given configuration management process takes place.

DSC architecture

Take a look at the following Visio diagram I created, and I’ll walk you through DSC architecture:

Bird's eye perspective of Windows PowerShell DSC

Bird’s-eye perspective of Windows PowerShell DSC

First, notice that both the authoring computer (which can run a client or server OS, and doesn’t even have to be Windows) and the target nodes must have the relevant DSC resources installed in the PSModulePath location:

PS C:\> Get-ChildItem -Path Env:\PSModulePath | Format-List

Name  : PSModulePath
Value : C:\Users\Tim\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\
Modules\

We can consider DSC resources as specialized PowerShell script modules that expose particular configuration functionality. For instance, the xChrome resource allows us to manage the installation, configuration, and enforcement of the Google Chrome browser.

Windows PowerShell v4 and v5 include several in-box DSC resources, but you can (and should) download additional resources from the TechNet ScriptCenter. PowerShell periodically releases these DSC “waves,” adding more and more products and features that can fall within the reach of DSC. For instance, look at the following output from my Windows 8.1 workstation, which I’ve loaded up with all resources from wave 1 to wave 9:

NOTE: Remember that we’re just hitting the high points here; I’ll cover the step-by-step procedure for DSC setup, configuration, and deployment in future blog posts here at 4sysops.

PS C:\>Get-DSCResource | Select-Object –Property Name | Format-Wide –Column 2

File                                    Settings
cCreateFileShare                        cSetSharePermissions
Archive                                 Environment
Group                                   Log
Package                                 Registry
Script                                  Service
User                                    WaitForAll
WaitForAny                              WaitForSome
WindowsFeature                          WindowsOptionalFeature
WindowsProcess                          xADDomain
xADDomainController                     xADDomainTrust
xADUser                                 xWaitForADDomain
xAdcsCertificationAuthority             xAdcsWebEnrollment
xAzureAffinityGroup                     xAzureQuickVM
xAzureService                           xAzureSqlDatabase
xAzureSqlDatabaseServerFirewallRule     xAzureStorageAccount
xAzureSubscription                      xAzureVM
xAzureVMDscConfiguration                xAzureVMDscExtension
xAzurePackAdmin                         xAzurePackDatabaseSetting
xAzurePackFQDN                          xAzurePackIdentityProvider
xAzurePackRelyingParty                  xAzurePackResourceProvider
xAzurePackSetup                         xAzurePackUpdate
xBLAutoBitlocker                        xBLBitlocker
xBLTpm                                  MSFT_xChrome
xComputer                               xCredSSP
xDatabase                               xDBPackage
xDhcpServerOption                       xDhcpServerReservation
xDhcpServerScope                        xDismFeature
xDnsServerSecondaryZone                 xDnsServerZoneTransfer
xExchActiveSyncVirtualDirectory         xExchAutodiscoverVirtualDirectory
xExchAutoMountPoint                     xExchClientAccessServer
xExchDatabaseAvailabilityGroup          xExchDatabaseAvailabilityGroupMemb
xExchDatabaseAvailabilityGroupNetwork   xExchEcpVirtualDirectory
xExchExchangeCertificate                xExchExchangeServer
xExchImapSettings                       xExchInstall
xExchJetstress                          xExchJetstressCleanup
xExchMailboxDatabase                    xExchMailboxDatabaseCopy
xExchMapiVirtualDirectory               xExchOabVirtualDirectory
xExchOutlookAnywhere                    xExchOwaVirtualDirectory
xExchPopSettings                        xExchPowerShellVirtualDirectory
xExchReceiveConnector                   xExchUMCallRouterSettings
xExchUMService                          xExchWaitForADPrep
xExchWaitForDAG                         xExchWaitForMailboxDatabase
xExchWebServicesVirtualDirectory        xCluster
xWaitForCluster                         MSFT_xFirefox
MSFT_xFileDirectory                     xVHD
xVhdFile                                xVMHyperV
xVMSwitch                               xInternetExplorerHomePage
xJeaEndPoint                            xJeaToolKit
xMySqlDatabase                          xMySqlGrant
xMySqlProvision                         xMySqlServer
xMySqlUser                              xDNSServerAddress
xFirewall                               xIPAddress
xPendingReboot                          xPowerShellExecutionPolicy
xArchive                                xDSCWebService
xFileUpload                             xGroup
xPackage                                xPSEndpoint
xRemoteFile                             xService
xWindowsOptionalFeature                 xWindowsProcess
xRemoteDesktopAdmin                     xRDRemoteApp
xRDSessionCollection                    xRDSessionCollectionConfiguration
xRDSessionDeployment                    xSCDPMConsoleSetup
xSCDPMDatabaseServerSetup               xSCDPMServerSetup
xSCOMAdmin                              xSCOMConsoleSetup
xSCOMConsoleUpdate                      xSCOMManagementPack
xSCOMManagementServerSetup              xSCOMManagementServerUpdate
xSCOMReportingServerSetup               xSCOMWebConsoleServerSetup
xSCOMWebConsoleServerUpdate             xSCSMAPowerShellSetup
xSCSMARunbookWorkerServerSetup          xSCSMAWebServiceServerSetup
xSCSPFServerSetup                       xSCSPFServerUpdate
xSCSRServerSetup                        xSCSRServerUpdate
xSCVMMAdmin                             xSCVMMConsoleSetup
xSCVMMConsoleUpdate                     xSCVMMManagementServerSetup
xSCVMMManagementServerUpdate            xSmbShare
xSqlHAEndPoint                          xSqlHAGroup
xSqlHAService                           xSqlServerInstall
xWaitForSqlHAGroup                      xSQLServerFailoverClusterSetup
xSQLServerFirewall                      xSQLServerRSConfig
xSQLServerRSSecureConnectionLevel       xSQLServerSetup
xIEEsc                                  xUac
xTimeZone                               xWebApplication
xWebVirtualDirectory                    xSystemRestore
xSystemRestorePoint                     xHotfix
xWinEventLog                            xWordPressSite

On the DSC authoring side, you can use Windows PowerShell or any other tool/technology to produce Managed Object Format (MOF) files that are ultimately deployed to target nodes.

That’s right—you can create Windows PowerShell DSC configuration scripts or use any other tool (even Notepad), as long as the output is a valid MOF file. MOF is an open standard, and contains easy-to-comprehend syntax. As a matter of fact, your system’s Windows Management Instrumentation (WMI) repository consists of a bunch of MOF files in plain text. To illustrate the DSC implementation of MOF, here’s a sample MOF schema file from the xChrome DSC resource:

Configuration MSFT_xChrome
{
    param
    (
	[string]$Language = "en",
	[string]$LocalPath = "$env:SystemDrive\Windows\DtlDownloads\GoogleChromeStandaloneEnterprise.msi"
    )
    Import-DscResource -ModuleName xPSDesiredStateConfiguration

    xRemoteFile Downloader
    {
        Uri = "https://dl.google.com/tag/s/appguid={8A69D345-D564-463C-AFF1-A69D9E530F96}&iid={00000000-0000-0000-0000-000000000000}&lang="+$Language+"&browser=3&usagestats=0&appname=Google%2520Chrome&needsadmin=prefers/edgedl/chrome/install/GoogleChromeStandaloneEnterprise.msi" 
        DestinationPath = $LocalPath
    }
	 
    Package Installer
    {
	Ensure = "Present"
	Path = $LocalPath
	Name = "Google Chrome"
	ProductId = ''
        DependsOn = "[xRemoteFile]Downloader"
    }
}

The MOF format is vendor-neutral and has easy-to-comprehend source code.

You have two choices for delivering the MOF configuration files to your target nodes. You can set up a pull server, or you can manually transfer (push) the files to target nodes. Each method has its advantages and disadvantages; we’ll cover those in a future installment.

The Local Configuration Manager (LCM) is the “client-side” component of the DSC architecture. Of course, administrators can deploy MOF files to control those settings as well. Here’s the configuration of my Windows 8.1 workstation:

PS C:\> Get-DscLocalConfigurationManager

ActionAfterReboot              : ContinueConfiguration
AllowModuleOverWrite           : False
CertificateID                  :
ConfigurationDownloadManagers  : {}
ConfigurationID                :
ConfigurationMode              : ApplyAndMonitor
ConfigurationModeFrequencyMins : 15
Credential                     :
DebugMode                      : False
DownloadManagerCustomData      :
DownloadManagerName            :
LCMCompatibleVersions          : {1.0, 2.0}
LCMState                       : Ready
LCMVersion                     : 2.0
MaxPendingConfigRetryCount     :
StatusRetentionTimeInDays      : 7
PartialConfigurations          : {}
RebootNodeIfNeeded             : False
RefreshFrequencyMins           : 30
RefreshMode                    : PUSH
ReportManagers                 : {}
ResourceModuleManagers         : {}
PSComputerName                 :

In the previous output, pay attention to ConfigurationMode; this property determines how rigorous the target node is concerning its applied configurations. ApplyAndMonitor, for instance, instructs the machine to apply all its DSC configurations and enforce their settings every 30 minutes by default.

For instance, if a target node has a DSC MOF that specifies that Google Chrome be installed and the user uninstalls the software, then DSC silently reinstalls Chrome after the next refresh cycle. The refresh cycle is governed by the RefreshFrequencyMins property and differs depending upon whether you’re using push or pull mode.

Wrap-up

I just threw a whole bunch of complex information at you, for sure. Take heart, though—you don’t need to digest it all at once. For now, I’m happy if you understand (a) the business value that DSC offers, and (b) how the technology works from a high level.

In the next blog post in this series, we’ll set up our DSC authoring and production environments.

4 Comments
  1. t 9 years ago

    This is great. I’m looking forward to more posts on DSC.

  2. Rafael 9 years ago

    Nice Timothy. Looking forward to the next installments

  3. Iain Brighton 9 years ago

    Hi Timothy – A good introductory article!

    However, I think you have a typo in the LCM configuration mode explanation. “ApplyAndMonitor” won’t automatically correct unless set “ApplyAndAutocorrect” instead.

    Thanks, Iain

  4. eldorado77 (Rank 1) 4 years ago

    Hello!

    I've got a trouble:

    Deploying Azure VM's with Terraform and DSC, there are two Network interfaces on each VM with DHCP assigned IP addresses, and should be two sites on each VM's – "Site1" and "Site2", all is ok except one thing – here is a part of DSC template:

    xWebSite Site1Site
    {
    DependsOn = @("[xWebAppPool]Site1AppPool","[File]Site1Folder","[File]AutoRedirect","[File]SeattleHTML")
    Ensure = "Present"
    Name = "Site1"
    State = "Started"
    BindingInfo = @( MSFT_xWebBindingInformation
    {
    MSFT_xWebBindingInformation
    {
    Protocol = "HTTPS"
    Port = 443
    CertificateThumbprint = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    IPAddress = "*"
    }
    )
    ...........................................
    Name = "Site2"
    State = "Started"
    BindingInfo = @( MSFT_xWebBindingInformation
    {
    MSFT_xWebBindingInformation
    {
    Protocol = "HTTPS"
    Port = 443
    CertificateThumbprint = "yyyyyyyyyyyyyyyyyyyyyy"
    IPAddress = "*"
    }
    ..........................................
    
    So, this DSC never can be executed properly due to duplicate binding for port 433 - IPAddress = "*"
    
    how to get next, to be executed inside DSC template (something like that or other with same result):
    
    #for Site1
    IPAddress = (gip).IPv4Address.IPAddress[0]
    #getting first Network adapter IP address
    
    #and for Site2
    IPAddress = (gip).IPv4Address.IPAddress[1]
    #getting second Network adapter IP address

    inside binding section..

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