Understanding CONFIGURATION keyword in Desired State Configuration

Desired State Configuration is a new management platform in Windows Powershell that enables devOps scenarios on Windows. It enables system administrators and devOps to configure a system declaratively, enforce the configuration and reuse configuration. One core aspect of it is the language extension for Configuration keyword in Powershell.

You can express configurations of your machine using configuration keyword as shown below which is taken from the MSDN documentation

Configuration MyWebConfig
   # A Configuration block can have zero or more Node blocks
   Node “Server001″
      # Next, specify one or more resource blocks

      # WindowsFeature is one of the built-in resources you can use in a Node block
      # This example ensures the Web Server (IIS) role is installed
      WindowsFeature MyRoleExample
   # To uninstall the role, set Ensure to “Absent”
          Ensure = “Present”
          Name   = “Web-Server” 

      # File is a built-in resource you can use to manage files and directories
      # This example ensures files from the source directory are present
      File MyFileExample
   # You can also set Ensure to “Absent”
         Ensure = “Present” 
   # Default is “File”
         Type = “Directory”
         Recurse = $true
         SourcePath = $WebsiteFilePath
         DestinationPath = “C:\inetpub\wwwroot”
  #This ensures that MyRoleExample completes successfully before
         DependsOn = “[WindowsFeature]MyRoleExample”       

From the sample you can see that we added one keyword, configuration, that can be used to declaratively define configurations and there is one dynamic keyword Node you can use inside configuration and a set of resources which are also act like keywords. You can find the list of resources and their properties by using Get-DscResource cmdlet. Here is the output I have when using it on a Windows Server 2012 R2 machine.

ImplementedAs   Name                      Module                         Proper
————-   —-                      ——                         ——
Binary          File                                                     {De…
PowerShell      Archive                   PSDesiredStateConfiguration    {De…
PowerShell      Environment               PSDesiredStateConfiguration    {Na…
PowerShell      Group                     PSDesiredStateConfiguration    {Gr…
Binary          Log                       PSDesiredStateConfiguration    {Me…
PowerShell      Package                   PSDesiredStateConfiguration    {Na…
PowerShell      Registry                  PSDesiredStateConfiguration    {Ke…
PowerShell      Script                    PSDesiredStateConfiguration    {Ge…
PowerShell      Service                   PSDesiredStateConfiguration    {Na…
PowerShell      User                      PSDesiredStateConfiguration    {Us…
PowerShell      WindowsFeature            PSDesiredStateConfiguration    {Na…
PowerShell      WindowsProcess            PSDesiredStateConfiguration    {Ar…

Configuration is a keyword with simple name, which means it can have constant string or variables as its name. It is the only new keyword added by default for desired state configuration. The syntax of it looks like function which means it can be followed by a scriptblock with some restriction. You can only have parameter block and default process block. Overall configuration definition syntax looks like function definition. Indeed it creates a command with the name you just specified and you can invoke it with some additional parameters such as output directory and configuration data. However since it has different semantics with functions we created a new command type called Configuration. If you save above sample as sample.psm1 and invoke import-module .\sample.psm1, you will see new configuration command listed in the output of get-command

PS D:\dsctest> Get-Command-CommandTypeConfiguration
CommandType     Name                                               ModuleName                                                                                                                                                                                   
———–     —-                                               ———-                                                                                                                                                                                    Configuration   MyWebConfig                                        sample                                                                                                                                                                                       
PS D:\dsctest> Get-Help MyWebConfig
    MyWebConfig [[-InstanceName] <string>] [[-OutputPath] <string>]
    [[-ConfigurationData] <hashtable>] 


After that, you can invoke MyWebConfig as other command by typing MyWebConfig. This command will generate a MOF file that can be send to the targeting machine to configure it. MOF is a Distributed management task force standard for Common Information Model(CIM)

PS D:\dsctest> MyWebConfig

    Directory: D:\dsctest\MyWebConfig

Mode                LastWriteTime     Length Name                                                                                                                                                                                                                
—-                ————-     —— —-                                                                                                                                                                                                                
-a—        10/14/2013   3:27 PM       2020 Server001.mof                                                                                                                                                                                                       


Now we know this new Configuration keyword let’s dig into the configuration body to know what we can specify inside. Powershell will add two dynamic keywords, Node and Import-DscResource, by default once inside the configuration block. Node conceptually represents a machine you want to configure. You can specify a set of resources inside each Node block. Each resource specification starts with the resource name and contains a hashtable body that represent concrete configuration settings as shown in the example at the very beginning. You can find more information about DSC resources from technet site.
We can discover the set of resources that are available on the machine using Get-DscResource cmdlet. These resources are the resources you can use inside node block. However there is a little caveat here user needs to be aware. PowerShell will automatically load the resource as keyword If the resource’s parentPath is under system path such as $pshome\modules or $env:systemRoot\system32\configuration. If it is under $env:PSModulePath other than system path,  we will need to use Import-DscResource to load the resource so powershell parser can understand it. We can see the detailed information of a resource using below commands.

PS D:\dsctest> Get-DscResource -name file | fl

ResourceType  : MSFT_FileDirectoryConfiguration
Name          : File
FriendlyName  : File
Module        :
Path          :
ParentPath    : C:\WINDOWS\system32\Configuration\Schema\MSFT_FileDirectoryConf
ImplementedAs : Binary
CompanyName   :
Properties    : {DestinationPath, Attributes, Checksum, Contents…}


All these resources are loaded as dynamic keywords which we will not have enough time to discuss this time. Hopefully we can get to them in the next post.

In addition to resources provided by the Desired State Configuration, user can build their own resources and there is a good TechNet documentation for it. That document mainly talked about powershell module based resources. User can actually add a resource using configuration itself as well. Here is an example:

configuration  scriptdsc
    param ($one, $two)

    Log scriptDscLogResource
        Message = “This is the message from the embedded log resource: one=$one two=$two three=$three

      File MyFileExample
         Ensure = “Present” 
         Type = “Directory“ # Default is “File”
         Recurse = $true
         SourcePath = $one # This is a path that has web files
         DestinationPath = $two # The path where we want to ensure the web files are present

Export-ModuleMember -Function scriptdsc
This file has to be named resourceName.Schema.psm1 and have a companion resourceName.psd1 file. After that, you can deploy it as any other Powershell resources. This capability enable the user to compose configurations and leverage existing configurations created by others like below.

Configuration MyConfig
   Node “Server001″
      scriptdsc MyExample
          One = “\\share\file.txt”
          Two = “d:\file.txt” 

In this post we gave a quick introduction to the configuration keyword in powershell. I will talk more about customizing configuration using configurationData, specify embedded objects in configuration and $using variables in the future blog. We will also dig into the implementation of dynamic keywords if that is interesting to more people.


Joe Zhou