This all came to me as I was drumming my fingers on the keyboard for an idea to Share at Teched for Speaker Idol.   The idea was simple.

I remember in my last job at we would have Developers create solutions, then fill out a Change Request form (or some type of paperwork, I can never remember WHICH one, there were so many floating about the desk) to bring a Development solution into production.

The typical request might have been something along the lines of

  • Server 2008 R2 Web Edition
  • 1 gb ram
  • 30 GB Hard disk
  • IIS installed

Then of course Infrastructure would spin it up, the application was deployed and inevitably something would fail in the Production solution.

Emails would fly back and forth.

“Hey you didn’t include this feature so that’s why the App doesn’t work!” is something I might hear from our Developer friend.

“Well you didn’t ask for that feature” IT would fire back.

Fingers would point back and forth until finally we all sat down and spoke and got the exact requirements for the application.   By Now all our feathers are ruffled up and Devs and IT Pros are launching Small projectiles created from paperclips and the Odd Co-op student over the wall in anger.

This is of course, not very productive.

I think to now with life in Windows PowerShell and how this could have been different.   In PowerShell we have actually two pretty cool and simple options in a modern Server 2008 R2 and higher environment.

Option 1 – Capture Server Features as an XML and reimport.

This one is the simple of the two to perform but still requires both sides to understand PowerShell.  You can use the Get-WindowsFeature Cmdlet and obtain a list of installed features, and then export them out to a CLIXML file like so

Get-WindowsFeature | Where { $-.Installed } | Export-CLIXML C:Fooconfig.xml

With this one script your Developer could at LEAST capture the presently installed features in his server he was Developing and capture that a Deserialized XML Object.

With this captured object you have a few options.  One is to pull down the exact list of names of all the installed Features and place it into a Text file to paste into the Documentation to aid Infrastructure with a long but detailed list of the very features the server needs.

The other interesting option would be to use this XML file on the Destination server and just simply execute the Install-WindowsFeature using the piped in data like so.

Import-CLIXML C:Fooconfig.xml | Install-WindowsFeature

This would at least create a mirrored feature configuration, limiting some of the mistakes.

Option 2 – Capture Features and build a DSC configuration AND the Change Request document

The other option which is a bit more interesting is to create a very basic DSC configuration file for PowerShell 4.0.    Similar to the first idea, we capture the WindowsFeature as an XML file but we parse and process this data and produce a simple Desired State Configuration File.   At the same time we do this, we can leverage a very interesting concept where we can build an RTF (Rich Text Format) file which contains this detailed list.

Why the document?   In larger environments, process must be followed and it often includes paperwork to match the process.   What you could look into doing is building an RTF file which matches the details of the original Change Request document but have the computer fill out as much of those details as possible.

So here is a sample script that could do this very setup.   Granted there are many ways to improve upon it’s design but it’s process is simple

  • Capture the Get-WindowsFeature Object
  • Parse the information and build a simple PS1 file as a Desired State Configuration
  • Build a Change Request document as an RTF file with Windows PowerShell with an EXACT list of the features needed

# Obtain Name of Server

# Use Present Date and Time as part of the filename for output

$DateTime=(get-date -Format ‘MMddyyyy-hhmmss’).tostring()



$Features=Get-WindowsFeature | Where { $-.Installed }

# Header for the DSC file

Configuration NewDevServer$DateTime
    Node $Servername

# Header for our RTF document

{rtf1ansiansicpg1252deff0nouicompatdeflang1033{fonttbl{f0fnilfcharset0 Consolas;}}
{*generator Riched20 6.2.8102}viewkind4uc1
pardsl276slmult1f0fs22lang9 par
# Our beginning header for the Message

This is a Request for a Deployment of a New Server into Production.parpar
We need the following features enabled in the server.parpar

Add-Content $DSCFile -Value $DSCHeader -Force
Add-Content $ChangeReqFilename -Value $RTFHeader -Force
Add-Content $ChangeReqFilename -Value $MessageHeader

# Get the list of features

Foreach ($Feature in $Features)
$DSCFeatureDisplayname=($Feature.DisplayName).replace(" ","").replace("-","")

# Build the Block in DSC for the Feature.  Each description must be unique

# We will use the Feature’s own name as the Description

        WindowsFeature $DSCFeatureDisplayName
        Ensure = `"Present`"
        Name = `"$FeatureName`"

# The line below is where we add lines to an RTF file. 

# the cool part is an RTF file is Just 100% raw ASCII with special

# Characters to produce the pretty letters.  (Did I just say Pretty?)


# Add Content to each individual file

Add-Content $DSCFile -Value $DSCFeatureBlock
Add-Content $ChangeReqFilename -Value $ChangeReqDescription

# Add the necessary terminators for  both the DSC file and the RTF Document

Add-Content $DSCFile -Value ‘}’
Add-Content $ChangeReqFilename -value ‘}’

If you run this script on any Server 2008 R2 or higher box it will capture the configuration, build a simple RTF document with a detailed list of features and the necessary DSC file to allow the IT Pro to deploy the server Easily and matching his Developer friend’s configuration much more closely.

e advantage (or than it’s PowerShell and it’s free) is a smoother process and happier times for IT Pros and Devs alike.   

…. and perhaps more nights together playing Titanfall rather than tossing CoOp students over the cubicles at each other