PowerShell Desired State Configuration – a Primer

Over the past decade, configuring machines remotely progressed from PSExec to Windows Remote Management in more recent years.  The concept of writing a reliable script and having it executed remotely has remained the same.  Most of that time, all we’ve needed to do is edit the registry or run some relatively basic configuration commands.  If you took enough time to build error trapping into your script you could get a pretty reliable outcome.

Desired State Configuration is a framework built on Windows Remote Management.  It simplifies the need for engineers to develop custom error trapping and network handling when trying to achieve configuration tasks on a remote machine.  DSC is natively available with Windows 8.1 & Windows Server 2012 R2 and deployable on Windows 7 and Server 2008 with Windows Management Framework 4.0 (http://www.microsoft.com/en-us/download/details.aspx?id=40855).

A Basic Script Example

The Image below represents one of the most basic and commonly used element of configuration management.  The configuration block contains a single element which happens to be a Registry configuration item. 

When the configuration item is called, it creates a deployable Management Object File from the configuration data.

Deploying the created MOF file to your local machine occurs with PowerShell

Eg.      Start-DscConfiguration "c:\temp\myconfig" -Wait -Verbose -Force

Core DSC Classes

Out of the box, Desired State Configuration can be used to configure Registry Items, Services, install Packages, extract archives, create user accounts and groups, copy files, enable Features (with Server 2012) and even run PowerShell scripts.  A number of available resources are pre-deployed with PowerShell under the local (C:\Windows\System32\WindowsPowerShell\v1.0\Modules) Modules folder.

Commonly used class examples are listed below.

Services

  Service ServiceExample
   {
     Name = "AdobeARMservice"
     StartupType = "Disabled"
   } 

Files

  File CopyFiles
   {
      SourcePath = "\\Server\Apps\files.cab"
      DestinationPath = "C:\temp\files.cab"
      Ensure = "Present"
   }

Registry 

 Registry EnableRdp
   {
      Key = "HKLM:SYSTEM\CurrentControlSet\Control\Terminal Server"
      ValueName = "fDenyTSConnections"
      ValueData = "0"
      ValueType = "DWord"
      Ensure    = "Present"
   }

MSI Package Install

  Package MSIInstall
    {
      Name = "OrcaInstall"
      ProductId = "039694F1-2108-4B3E-8575-85C245210F94"
      Path = "C:\Temp\Orca.msi"
      Ensure = "Present"
    } 

Logging

  Log loginfo
    {
       Message = "Process progressed to completion"
    } 

Elements that require credentials are a little more problematic as storing credentials in plain text is now banned.  DSC can be called with an additional parameter (-configurationdata) to allow plain text credential objects to be created.

User Resource

$ConfigurationData = @{
  AllNodes = @(
  @{
    NodeName="*"
    PSDscAllowPlainTextPassword=$true
  }
  @{
    NodeName="server.domain.com"
   }
  )
}
 
Configuration MyConfig
{
   param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullorEmpty()]
        [PsCredential]$credential
        )
 
Node $AllNodes.NodeName
{
   User UserExample
   {
     Ensure   = "Present"
     UserName = "SVC-Rhubarb"          
     Password = $Credential
   }
}
}
 
$NewPasswordCred = New-Object System.Management.Automation.PSCredential ("fred",  (ConvertTo-SecureString "MyPassword123" -AsPlainText -Force))
 
MyConfig -configurationdata $configurationdata -credential $NewPasswordCred -OutputPath c:\temp\myconfig
 
Start-DscConfiguration -Path c:\temp\myconfig -force -verbose -Wait

 

Desired State Configuration also incorporates the communication requirement of applying setting to a remote machine.  Natively, this removes the need to separately code checks for ensuring a machine is online or managing the closure of sessions.  For a particular machine to be targeted, the basic DSC script is modified to nest configuration parameters under a “node” element.  For reusability, instead of hardcoding a machine name into the script, the machine name can be parameterized with the $Computername variable which is passed during the creation and deployment of the Desired State Configuration. 

Targeting Specific Machines

  configuration MyConfig
{
    Param(
        [Parameter(Mandatory=$True)]
        [String[]]$ComputerName
    )
 
    node $ComputerName
    {
         Registry EnableRdp
        {
            Key = "HKLM:SYSTEM\CurrentControlSet\Control\Terminal Server"
            ValueName = "fDenyTSConnections"
            ValueData = "0"
            ValueType = "DWord"
            Ensure    = "Present"
        }
    }
}
 
# Create the MOF
MyConfig -ComputerName "myserver.domain.com" -OutputPath "c:\temp\myconfig"
 
 
# Deploy the MOF
Start-DscConfiguration "c:\temp\MyConfig" -Computername "myserver.domain.com" -Wait -Verbose -Force

Every time the Desired State Configuration is constructed for a different machine, a machine specific MOF file is created under the common output path.

When the deployment of a DSC configuration is called, a corresponding match for the remote server is looked for and then deployed.

Extended DSC Classes / Resources

At the start of the holidays, Microsoft had made available 172 different resources for configuring all elements of the Microsoft product range, including hosted MySQL and even installing Firefox and Chrome.  The technical community is encouraged to develop and share new Desired State Configuration elements.

http://blogs.msdn.com/b/powershell/archive/2014/12/17/another-holiday-present-from-the-powershell-team-dsc-reskit-wave-9.aspx

Additional resources are enabled by copying modules into the (C:\Windows\System32\WindowsPowerShell\v1.0\Modules) directory of the serving and client machines. 

Importing modules occurs through using the command “Import-DSCResource”.  The example below uses two of the contributed DSC resource extensions.

configuration MyConfig
{
    Param(
        [Parameter(Mandatory=$True)]
        [String[]]$ComputerName
    )
 
    Import-DscResource -ModuleName xInternetExplorerHomePage
    Import-DscResource -ModuleName xChrome
 
    node $ComputerName
    {
        MSFT_xChrome chrome
        {
              Language = "en"
              LocalPath = "$env:SystemDrive\Windows\DtlDownloads\GoogleChromeStandaloneEnterprise.msi"
        }
 
        xInternetExplorerHomePage IEHomePage
        {
            StartPage = "www.laurierhodes.info"
            SecondaryStartPages = "www.google.com"
            Ensure = "Present"
        }
    }
}
 
 
# Create the MOF
MyConfig -ComputerName "myserver.domain.com" -OutputPath "c:\temp\myconfig"
 
# Deploy the MOF
Start-DscConfiguration "c:\temp\MyConfig" -Computername "myserver.domain.com" -Wait -Verbose -Force

Linux Support

Part of the SCCM Client install for Linux introduces Open Management Infrastructure (OMI), which is a Windows Management Interface equivalent for ‘nix platforms.  OMI currently enables the use of Desired State Configuration for a range of Linux distributions.  The current class / resource types that can be pushed to Linux clients are similar to the default Windows resources:

  • nxFile
  • nxScript
  • nxUser
  • nxGroup
  • nxService

Linux management has been an area of difficulty with Microsoft tools in the past.  If anything, the introduction of DSC for Linux hints at the intended scope Microsoft expects the framework to have in the future.