PowerShell Desired State Configuration (DSC)

It has been awhile since my last blog entry, hope you find this one worth the wait! I recently started working for Infront Consulting Group, and one of my first big projects has been to rebuild some System Center labs using the 2012 R2 Preview release. Those that have followed some of my other posts know that I am a huge fan of the PowerShell Deployment Toolkit (PDT). PDT allows you to deploy a fully baked System Center 2012 R2 environment with all roles and SQL Servers configured.

As good as PDT is, it still leaves quite a few manual tasks to complete before you have a completely functioning lab environment. This is where PowerShell Desired State Configuration (DSC) comes into play.

PowerShell Desired State Configuration (DSC) is a new PowerShell extension that ships with Microsoft Windows Server 2012 R2 and Windows 8.1. DSC is a new management platform in Windows PowerShell that enables deploying and managing configuration data for software services and managing the environment in which these services run.

So what can DSC do?

  • Install or remove server roles and features
  • Manage registry settings
  • Manage files and directories
  • Start, stop, and manage processes and services
  • Manage local groups and user accounts
  • Install and manage packages such as .msi and .exe
  • Manage environment variables
  • Run Windows PowerShell scripts
  • Fix a configuration that has drifted away from the desired state
    Discover the actual configuration state on a given node

More information about DSC

 

The best way to explain how DSC works is to dive in and show some examples. The meat of DSC scripts are Configuration blocks

Configuration MyCfg

}

If you want to enact a configuration on a specific computer, you can add a Node value

Configuration MyCfg
{
Node SCOM01

}
}

If you want to enact a configuration on a list of computers, you can do that as well…

Configuration MyCfg
{
Node (“SCOM01”, “SCVMM01”,”SCSM01”)

}
}

Here are the built-in DSC Resources you can use within the Configuration blocks. You can also write your own.

  • Archive – for working with compressed archive files
  • Environment – for managing the local computer environment
  • File – for managing files and directories
  • Group – for managing local groups on a target node
  • Log – write messages to the DSC event log
  • Package – install msi or exe packages
  • Process – manage processes on a target node
  • Registry – manage registry keys and values
  • Role – install windows roles and features
  • Script – run PowerShell script blocks
  • Service – manage services
  • User – manage local user accounts on target nodes.

Here is an example Configuration that will enable the Hyper-V role and install a VMSwitch called “CorpNet01”

Configuration HyperVCfg
{
Node Localhost
{
WindowsFeature HyperVFeature
{
Ensure = “Present”
Name = “Hyper-V”
}

Script CreateVMSwitch
{
SetScript = {New-VMSwitch -Name CorpNet01 -SwitchType Internal}
TestScript = {((Get-VMSwitch|Where-Object {$_.Name -eq “CorpNet01”}).Name -eq “CorpNet01”) }
GetScript = {(Get-VMSwitch|Where-Object {$_.Name -eq “CorpNet01”}).Name}
Requires = “[WindowsFeature]HyperVFeature”
}

Script VMSwitchType
{
SetScript = {Set-VMSwitch -Name CorpNet01 -SwitchType Internal}
TestScript = {((Get-VMSwitch|Where-Object {$_.Name -eq “CorpNet01”}).SwitchType -eq “Internal”)}
GetScript = {(Get-VMSwitch|Where-Object {$_.Name -eq “CorpNet01”}).SwitchType}
Requires = “[Script]CreateVMSwitch”
}

}
}

The previous example is using  2 different DSC Resources, WindowsFeature and Script. Ensure = “Present” tells the Resource it should be installed. Name = “Hyper-V” is the role to be installed. This example also uses a Node of Localhost, so it will run on the node it is executed on. You could also remove the Node block. You will also notice the Requires property. The new VMSwitch will not be created until the Hyper-V role is installed

The Script resource has 3 required, and several option properties.

  • SetScript – this is the script block that is run when you execute Start-DscConfiguration (will cover that soon)
  • TestScript – this block when evaluated as False will cause the SetScript block to execute. If the statement in the block evaluates to True, the configuration will be assumed valid.
  • Get-Script – this block is run when you invoke the Get-DscConfiguration command.

You can also combine Configuration blocks. This is helpfully if you have different sets of nodes that have a common configuration.

Configuration MyWebServerCfg
{
Node (“WEB01”, “WEB02”,…)
{     Resource1…

Resource2…

}
}

Configuration MySQLServerCfg
{
Node (“SQL01”,”SQL02”,…)
{

}
}

Each Configuration block must be compiled into a MOF file before it can be executed on the target node. Using the example above.

Configuration MyWebServerCfg
{
Node (“WEB01”, “WEB02”,…)
{     Resource1…

Resource2…

}
}

Configuration MySQLServerCfg
{
Node (“SQL01”,”SQL02”,…)
{

Resource1…

Resource2…

}
}

# Compile MOFs
MyWebServerCfg –OutputPath $PSScriptRoot\MyWebCfg
MySQLServerCfg –OutputPath $PSScriptRoot\MySQLCfg

You will notice you are using the Configuration block name .

Once you have compiled the MOF files, you can execute them on the target nodes using the following the Start-DscConfiguration command…

Using the previous example, lets put it all together.

Configuration MyWebServerCfg
{
Node (“WEB01”, “WEB02”,…)

Resource1…

Resource2…

}
}

Configuration MySQLServerCfg
{
Node (“SQL01”,”SQL02”,…)
{

Resource1…

Resource2…

}
}

# Compile MOFs
MyWebServerCfg –OutputPath $PSScriptRoot\MyWebCfg
MySQLServerCfg –OutputPath $PSScriptRoot\MySQLCfg

# Make it so!
Start-DscConfiguration -Path $PSScriptRoot\MyWebCfg -Wait -Verbose -ErrorAction Continue
Start-DscConfiguration -Path $PSScriptRoot\MySQLCfg  -Wait -Verbose -ErrorAction Continue

The Start-DscConfiguration path is pointing to the directory where the MOF files were compiled. The target nodes are defined within the MOF files.

Here are a few more complete examples. How to install an MSI package on 2 remote web servers

$Files = “C:\DATA” 

Configuration MyWebCfg
{
Node (“WEB01”, “WEB02”,…)
{

Package zip7Package
{
Ensure = “Present”
Path = “$Files\7z920-x64.msi”
Name = “7-Zip 9.20 (x64 edition)”
ProductId = “23170F69-40C1-2702-0920-000001000000”
}

}
}

# Compile MOF
MyWebCfg –OutputPath $PSScriptRoot\MyWebCfg

# Make it so!
Start-DscConfiguration -Path $PSScriptRoot\MyWebCfg -Wait -Verbose -ErrorAction Continue

Disable IE Enhanced Security and unzip ZoomIt to a local path..

$Files = “C:\DATA”
$FileShr = “\\DC01\Data\Files” 

Configuration MyWebCfg
{
Node (“WEB01”, “WEB02”,…)
{

Registry IESecReg
{
Ensure = “Present”
Key = “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}”
ValueName = “IsInstalled”
ValueType = “DWord”
ValueData = “0”
}

Archive ZoomItArch
{
Ensure = “Present”
Path = “$FileShr\Zoomit.zip”
DestinationPath = “$ToolsDir\Zoomit”
}

}
}

# Compile MOF
MyWebCfg –OutputPath $PSScriptRoot\MyWebCfg

# Make it so!
Start-DscConfiguration -Path $PSScriptRoot\MyWebCfg -Wait -Verbose -ErrorAction Continue

Here is one more expanding on the last example and including another Configuration block.

$Files = “C:\DATA”
$FileShr = “\\DC01\Data\Files” 

Configuration MyWebCfg
{
Node (“WEB01”, “WEB02”,…)
{

Registry IESecReg
{
Ensure = “Present”
Key = “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}”
ValueName = “IsInstalled”
ValueType = “DWord”
ValueData = “0”
}

Archive ZoomItArch
{
Ensure = “Present”
Path = “$FileShr\Zoomit.zip”
DestinationPath = “$ToolsDir\Zoomit”
}

}
}

Configuration LabGWCfg
{

Node “Gateway01”
{
WindowsFeature RRASFeature
{
Ensure = “Present”
Name = “RemoteAccess”
}

WindowsFeature RoutingFeature
{
Ensure = “Present”
Name = “Routing”
Requires = “[WindowsFeature]RRASFeature”
}
}

}

# Compile MOFs
MyWebCfg –OutputPath $PSScriptRoot\MyWebCfg
LabGWCfg  –OutputPath $PSScriptRoot\LabGWCfg

# Make it so!
Start-DscConfiguration -Path $PSScriptRoot\MyWebCfg -Wait -Verbose -ErrorAction Continue
Start-DscConfiguration -Path $PSScriptRoot\LabGWCfg -Wait -Verbose -ErrorAction Continue

PowerShell DSC looks like a powerful tool to not only help you setup and configure your lab and production environments, but insure they keep the configuration they started with. Until next time…

2 thoughts on “PowerShell Desired State Configuration (DSC)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.