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:

Present:
  • 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):


[ClassVersion("1.0.0"),FriendlyName("FPad")] 
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
{
Param($Computername)

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!

Cheers

Comments

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

Creating Menus in Powershell

I have created another Powershell module. This time it is about Console Menus you can use to ease the usage for members of your oranization. It is available on GitHub and published to the PowershellGallery . It is called cliMenu. Puppies This is a Controller module. It uses Write-Host to create a Menu in the console. Some of you may recall that using Write-Host is bad practice. Controller scripts and modules are the exception to this rule. In addition with WMF5 Write-Host writes to the Information stream in Powershell, so it really does not matter anymore. Design goal I have seen to many crappy menus that is a mixture of controller script and business logic. It is in essence a wild west out there, hence my ultimate goal is to create something that makes it as easy as possible to create a menu and change the way it looks. Make it easy to build Menus and change them Make it as "declarative" as possible Menus The module supports multiple Men