Skip to main content

Powershell - Desired State Configuration (DSC) - Is it desired?

ps4Finally found some time to play around with DSC on 2012 R2 and with the release of Windows Management Framework 4, I can finally play with 2008 R2, Windows 7 and Windows 8 clients (if you upgrade to 8.1).

As always with new releases of the Management Framework, some server configurations/applications do not play nicely with the new framework:
  • System Center 2012 Configuration Manager (not including SP1)
  • System Center Virtual Machine Manager 2008 R2 (including SP1)
  • Microsoft Exchange Server 2013, Microsoft Exchange Server 2010 and Microsoft Exchange Server 2007
  • Microsoft SharePoint 2013 and Microsoft SharePoint 2010
  • Windows Small Business Server 2011 Standard
Please also note that .Net 4.5 is required before you install the Framework, otherwise the Framework installation will actually silently fail.

As I previously wrote, if you were hoping for support for Windows Server 2008 support, you are not getting it. You will have to fall back to Windows Management Framework 3.0 for those servers.

"Will it float?"

I have played around with the "push"-model of DSC and it is cool. DSC shipped with a lot more providers than I thought it would when they announced it this summer. So why the heading? From my perspective it looks not quite finished. I feel some of the providers were rushed out the door to make it into the release date of windows 2012 R2. Do not get me wrong, the DSC framework looks solid, however the providers play a key part in the process.

From an Enterprise perspective, a lot is missing before it is a fully featured "state configuration tool with self healing capabilities". Let's just make a list shall we:

  • File and folder copy/delete
  • Process manipulation
  • Service manipulation
  • "Package" installation/removal (only MSI and EXE installers)
  • Registry configuration
  • Archive (zip) manipulation
  • User/group configuration, however only localmachine(!!)
  • Environment configuration
  • Logging tool
  • Configuration by generic script (powershell of couse)
  • Custom provider (create your own provider with a powershell Module)
Look impressive eh? Well it kind of is really. I was hoping for file/registry/service and mabee environmen, however they threw in a few more. The other list:

Absent (wishlist):
  • Active Directory Provider
  • Generic LDAP provider
  • Group Policy Provider (why not!!)
  • Exchange Provider
  • Sharepoint Provider
  • Package Provider which supports batch, vbs, exe, msi, ps1
  • SQL Provider (server and agent jobs)
  • DHCP-server provider
  • DNS-provider
  • Hosts file provider (there is a custom provider on codeplex)
  • Orchestrator Provider
  • Azure Provider
  • Oracle Provider
  • MySQL Provider
  • ODATA Provider
  • WEB-REST Provider
  • XML Provider
  • JSON Provider
Okay I will admitt it. I got a bit carried away here. If you look at the lists, you realize that a lot of those things missing may be plugged into the System Center portifolio and should belong there. In addition System Center Configuration Manager 2012 has a DSC light built in for manipulating client configuration. I do not know if that is a popular feature and if it is widely used by the ConfigMgr dudes/dudettes, however it is going to be exciting to see what will happen.

Custom Providers - May I have one please?

Yes, I know. You can create your own providers and package those up in an Powershell module (.PSM1) together with the corresponding MOF-class definition. MOF-class you say? Well according to Microsoft it is easy, you don't even have to know MOF to create a MOF-file?? Ever done things you don't fully comprehend, then this is for you.

Joking aside. It is actually not that difficult. If you have ever created a class in visual studio (or in a VBSCRIPT, who hasn't?) you are probably going to be fine. Actually I have created my first (well actually two) custom provider - Active Directory User Provider.

My first MOF (that has a nice ring to it, doesn't it):

class FPactiveDirectory : OMI_BaseResource
  [key] string Description;
  [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure;
  [write] string Password;
  [write] string Firstname;
  [write] string Lastname;
  [write] string Username;
  [write] string AddToGroup;
  [write] boolean PasswordNeverExpires;

Why not just create a quick DSC configuration:

configuration TestUser

Node $Computername
 FPad Myuser
            Ensure = "Present"
            Description ="OM user"
            Username = "SVCOM"
            Firstname = "svcom"
            Lastname = "System Center"
            Password = "Yalla45Ikk"
            PasswordNeverExpires = $true
            AddToGroup = "Domain Admins"   

This configuration creates (“Present”) a user with username SVCOM, set the password to the string value provided and joins the user to the group “Domain Admins”. Not a textbook example, however you understand the concept.

In your powershell module where the magic happens, you have to implement 3 functions:

  • Test-TargetResource

  • Get-TargetResource

  • Set-TargetResource
You may also use “private” functions in the module, however those three must be exported from you module. All three must implement the same parameters which must match the MOF class you have created!

Quick tip: Test your module by importing the module file with the Import-Module cmdlet (set the path parameter to the full path of the module file).

In my module I used the cmdlets from the ActiveDirectory module. If you are wondering if you need to reference that module in you custom module, you are wrong. Since Powershell version 3, the module is dynamically loaded if it is available (installed). My assumption was that I could target any computer with the ActiveDirectory module installed and DSC would happily process my configuration on the node targeted in the configuration MOF file. Oh how wrong I was.

The DSC is executed on the target node in the context of the built-in administrator (System-role). The result was a nice “access denied” message from DSC when I executed “make it so”. If I targeted a Domain Controller, everything worked obviously.

DSC – Workgroup edition or domain edition?

My custom provider for Active Directory shows that this is not a fully flexed Enterprise product yet, however much can be done with the current implementation. Adding roles/features to a range of servers works like a dream and is a pleasure. Same must be said for packages that is MSI-based even though EXE-based setup also works, however you cannot set a EXE-package to “Absent”. It just fails utterly.

Some of the providers have a Credential property, for instance the file resource. How is the credential transmitted to the target host? A clear string text field in the configuration MOF file. By the way, out of the box this will not “compute”. You will get a nice message saying that the “Converting and storing an encrypted password as plaintext is allowed only if PSDscAllowPlainTextPassword is set to true” or more correctly an exception of type “System.InvalidOperationException” and “FailToProcessProperty,ConvertTo-MOFInstance”.

Whilst testing the Package resource, I kept receiving an “Access denied” message when I tried to install Operations Manager 2012 with DSC (I am bold, yes I know). Access denied is usually something to do with credentials, So i threw in some domain credentials (remember the context built-in\administrator) and gave it another go. DSC came back with the same exception “Access denied". I fired up ISE and opened the provider (luckily it is in pure text) MSFT_PackageResource.psm1 and started looking for the credential object. To my surprise the credentials is only used for accessing the source installation media if it is not located on the target node. That will never work will it? During installation you need access to Active Directory and a remote SQL-server! Or can I do it?

Stay tuned!



Popular posts from this blog

Serialize data with PowerShell

Currently I am working on a big new module. In this module, I need to persist data to disk and reprocess them at some point even if the module/PowerShell session was closed. I needed to serialize objects and save them to disk. It needed to be very efficient to be able to support a high volume of objects. Hence I decided to turn this serializer into a module called HashData. Other Serializing methods In PowerShell we have several possibilities to serialize objects. There are two cmdlets you can use which are built in: Export-CliXml ConvertTo-JSON Both are excellent options if you do not care about the size of the file. In my case I needed something lean and mean in terms of the size on disk for the serialized object. Lets do some tests to compare the different types: (Hashdata.Object.ps1) You might be curious why I do not use the Export-CliXML cmdlet and just use the [System.Management.Automation.PSSerializer]::Serialize static method. The static method will generate t

Toying with audio in powershell

Controlling mute/unmute and the volume on you computer with powershell. Add-Type -TypeDefinition @' using System.Runtime.InteropServices; [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { // f(), g(), ... are unused COM method slots. Define these if you care int f(); int g(); int h(); int i(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int j(); int GetMasterVolumeLevelScalar(out float pfLevel); int k(); int l(); int m(); int n(); int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev); } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), Inte

Something completely different – PoshARM

I needed a project for my Xmas holiday and I needed something remotely work related. Thus the dubious PoshARM PowerShell module was born and brought to life during my Xmas holiday. Simply put it is a module that lets you build – for now – simple Azure Resource Manager (ARM) templates with PowerShell .  The module can also import templates from a file or from the clipboard/string. Your partial template or ready made template can be exported as a PowerShell script. This blog post will walk you through how to use it and the features that is currently implemented.  Update 08.02.2017: The module is now published to the PowerShellGallery ( ). It is still in beta version, however test coverage have increased and some bugs have been squashed during the testing. Also help is present, however somewhat lacking here and there. Update 18.01.2017: The module is now on GitHub. Here is the link to the repro  ( PoshARM on GitHub ) What