# Using PowerShell DSC in Release Management: The Hidden Manual

Just in case you missed it, Release Management Update 3 CTP now supports deploying using PowerShell DSC. I think this is a great feature and adds to the impressive toolset that Microsoft is putting out into the DevOps area. So I decided to take this feature for a spin!

## Bleeding Edge

<rant>I had a boss once who hated being on the bleeding edge – he preferred being at “latest version – 1” of any OS, SQL Server or VS version (with a few notable exceptions). Being bleeding edge can mean risk and churn, but I prefer being there all the same. Anyway, in the case of the Release Management (RM) CTP, it was a little painful – mostly because the documentation is poor. Hopefully this is something the Release Management team will improve on. I know the release is only CTP, but how can the community provide feedback if they can’t even figure out how to use the tool?</rant>

On top of the Release Management struggles, PowerShell DSC itself isn’t very well documented (yet) since it itself is pretty new technology. This is bleeding BLEEDING edge stuff.

Anyway, after struggling on my own for a few days I mailed the product group and got “the hidden manual” as a reply (more on this later). At least the team responds fairly quickly when MVPs contact them!

### Issues

So here’s a summary of the issues I faced:

• The DSC feature only works on domain joined machines. I normally don’t use domains on my experimental VMs, so I had to make one, but most organizations nowadays use domains anyway, so this isn’t such a big issue.
• Following the RM DSC manual, I wanted to enable CredSSP. I ran the Enable-WSManCredSSP command from the manual, but got some credential issues later on.
• The current public documentation on DSC in RM is poor – in fact, without mailing the product group I would never have gotten my Proof-of-Concept release to work at all (fortunately you now have this post to help you!)
• You have to change your DSC scripts to use in Release Management (you can’t have the exact same script run in RM and in a console – the mof compilation is invoked differently, especially with config data)

## Proof of Concept – A “Start of Release” Walkthrough

I want to eventually build up to a set of scripts that will allow me to deploy a complete application (SQL database and ASP.NET website) onto a set of “fresh” servers using only DSC. This will enable me to create some new and unconfigured servers and target them in the Release – the DSC will ensure that SQL gets installed and configured correctly, that IIS, ASP.NET, MVC and any other prerequisites get set up correctly on the IIS server and finally that the database and website are deployed correctly. All without having to install or configure anything manually. That’s the dream. The first step was to create a few DSC scripts and then to get Release Management to execute them as part of the deployment workflow.

I had to create a custom DSC resource (I may change this later) – but that’s a post for another day. Assume that I have the resource files ready for deployment to a node (a machine). Here’s the script to copy an arbitrary resource to the modules folder of a target node so that subsequent DSC scripts can utilize the custom resource:

Configuration CopyDSCResource {
param (
[Parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [String]$ModulePath = "$env:ProgramFiles\WindowsPowershell\Modules" ) Node$AllNodes.NodeName
{
#
# Copy the custom DSC Resource to the target server
#
File DeployWebDeployResource
{
Ensure = "Present"
SourcePath = "$($Node.SourcePath)\$($Node.ModuleName)"
DestinationPath = "$ModulePath\$($Node.ModuleName)" Recurse =$true
Force = $true Type = "Directory" } } } CopyDSCResource -ConfigurationData$configData -Verbose


The last  of the script “compiles” the DSC script into a mof file that is then used to push this configuration to the target node. I wanted to parameterize the script, so I tried to introduce the RM parameter notation, which is __ pre- and post-fix (such as __ModuleName__). No such luck. I have to hardcode configuration data in the configuration data file.

To accomplish that I’m using configuration data for executing this script. This is standard DSC practice – however, there’s one trick. For RM, you need to put the configuration data into a variable. Here’s what an “ordinary” config data script looks like:

@{
AllNodes = @(
@{
NodeName = "*"
SourcePath = "\\rmserver\Assets\Resources"
ModuleName = "DSC_ColinsALMCorner.com"
},

@{
NodeName = "fabfiberserver"
Role = "WebServer"
}
);
}


To get this to work with RM, you need to change the 1st line to this: $configData = @{ This puts the configuration hashtable into a variable called “$configData”. This is the variable that I’m using in the CopyDSCResource DSC script to specify configuration data (see the last line of the previous script).

Meanwhile, in RM, I’ve set up an environment (using “New Standard Environment”) and added my target server (defaulting to port 5985 for PSRemoting). I’ve configured a Release Path and now I want to configure the Component that is going to execute the script for me.

I click on “Configure Apps” –> Components and add a new component. I give it a name and specify the package path:

### Cannot Find Mof File

Symptom: You get the following error message in the deployment log: System.Management.Automation.RemoteException: Unable to find the mof file.

Fix: This could mean that you’ve got an “-OutputPath” specified when you invoke your config (the last line of the config script) so that the mof file ends up in some other directory. Or you have the name of your node incorrect. I found that specifying “fabfiberserver.fab.com” caused this error in my scenario – but when I changed the name to “fabfiber” I didn’t get this error. You’ll have to try the machine name or the FQDN to see which one RM is happy with.

## Challenges

The ability to run DSC during Releases is a promising tool – but there are some challenges. Here is my list of pros and cons with this feature:

### Pros of DSC in Release Management

• You don’t have to install a deployer agent on the target nodes
• You can use existing DSC PowerShell scripts (with some small RM specific tweaks) in your deployment workflows

### Cons of DSC in Release Management

• Only works on domain machines at present
• Poor documentation makes figuring out how to structure scripts and assets to RM’s liking a challenge
• You have to change your “normal” DSC script structure to fit the way RM likes to invoke DSC
• You can’t parameterize the scripts (so that you can reuse scripts in different workflows)

## Conclusion

The ability to run DSC in Release Management workflows is great – not having to install and configure the deployer agent is a bonus and being able to treat “config as code” in a declarative manner is a fantastic feature. However, since DSC is so new (and poorly documented) there’s a steep learning curve. The good news is that if you’ve already invested in DSC, the latest Release Management allows you to leverage that investment during deployments. This is overall a very exciting feature and I look forward to seeing it grow and mature.

I’ll be posting more in this series as I get further along with my experimentation!

Happy releasing!