Wednesday, October 8, 2014

XenDesktop DSC resource and the Azure DSC VM Extension

After all of the previous blog posts, I thought that I would climax with a few real examples of using the DSC resource for XenDesktop.

Earlier this year (just a few++ weeks ago) Microsoft released the VM extensions for Virtual Machines.  This is the IaaS style VM role.  The VM Extensions are small modules that you can inject into your VM and you can interface with them.  The simplest way to think of it is they are purpose built agents.  You can configure them on provisioning, but also nifty is that you can update the configuration of an extension after deployment and do something else.

There is a script extension that can be used to download and execute any script(s) inside of your VM.  Handy for performing a number of things. You can use this to drive DSC if you like.
After that the DSC extension was released.  This one is purpose built just for DSC and the one this post will be focusing on.

I will warn you, I am going to expose a few warts of the process as I do this, just because the extension is built to support DSC and only the DSC packages.  And this process requires external media - yes, the media could be bundled into the DSC resource (the only workaround to this process at the moment), but that would make the resource really fat.  So, why not continue to think of it as two problems.

One thing - the DSC provider for XenDesktop expects media to be on the machine where it runs or a DVD attached ISO.  So a ZIP or ISO (DVD attached or downloaded to the machine) or folder.  This way there is no requirement to save credentials for connecting to some share or other store.

Now, let get everything set up.  (I am experimenting with a slightly different writing format here, so you will have to let me know if it works for you)

First of all, I am going to assume that you are sitting at your 'configuration computer' - that management computer that you use that has all of the consoles and what not installed.  In this case it is where you build all of your configurations that you later push to machines or place on your pull server.  Your configuration computer needs the XenDesktop resource module installed under the path "%ProgramFiles%\WindowsPowerShell\Modules" so a later cmdlet for the DSC script provider can automagically pick it up and bundle it for you.

Begin by connecting to your Azure subscription and set the storage account you will be using ( Set-AzureStorageAccount -StorageAccountName "YourCoolStorageAccount" )

Then upload the XenDesktop media.  ( the media is created from the ISO, simply ZIP the contents of the ISO - don't add any folders into the path)
Be sure that your container security is set to public blob (not public container) since we don't want folks discovering it.

For a later step you will need the URI to the blob that you just uploaded.

Now, we need to define the configuration (the DSC one) that will be applied to the VM.

For that I created a PowerShell script that accepts two parameters; the URI to the media and the role to be installed.

The DSC extension will run this and then apply the configuration.

Now that the configuration script exists, this must be packaged up, with the module, for the Azure DSC extension to use.  I saved mine with the name "XenDesktopInAzure.ps1".

The Azure PowerShell cmdlets have created a cmdlet just for this action; Publish-AzureVMDscConfiguration

After running the Publish-AzureVMDscConfiguration cmdlet, go check out your Azure management portal and look into the container and you will find a ZIP archive with a name that matches your script.  What the Public- command does is package the script and the modules that are used into the ZIP, then uploads them to Azure for you.

Now, define the VM, so that can be created.

First needed is an Azure VM Image - an 'image' is a virtual disk that is installed with an OS and prepared with sysprep and registered with Azure as an image - to the management platform, this means that it can specialize the OS on provisioning through mini-setup and the use of an unattended answer file.
Moving forward to the next step of building the VM configuration.

First, begin with a base VM configuration.

Then add the provisioning configuration ( these are the specialization settings ).
Then configure the Azure DSC VM extension.

Then create the VM.  Azure and the VM extension take care of processing the configuration script, and the configuration script downloads the ZIP, unpacks it, and installs the role.

One really cool thing about DSC is that you can keep applying configurations.  The last applied settings to a specific thing win, configurations are not undone when a new one is added, simply the changes defined in the new configuration are applied.  So, if you have some management layer, it can apply configuration after configuration if it so wanted to, or change a configuration over time to modify something.

As an option for delivering media, you can use a data disk with the XenDesktop media within it.  Then you can attach that to a new VM and have DSC mount the disk (rather, make sure it is mounted at a specific drive letter) and then perform the installation.

If you are using SCVMM, you can have an ISO attached to the VM as part of the template.  You could even use DSC to map a drive if that is what fits for your environment.  They are all possibilities.

Have fun! And please, send feedback!

Monday, October 6, 2014

Using the XenDesktop DSC resource

In my last article I covered using the built-in desired state configuration (DSC) resources to stand up a Citrix License server.  All but one of the resources I used shipped in the box with Server 2012 R2 - and you could argue that I really didn't have to use the custom resource to fetch and install my license file.

I used the package resource to install the Citrix License server. 

The package resource works great for the License Server, which is a really quick and simple install.  But what do you do when you have an installer that requires reboots mid-stream?  Or even multiple reboots? 

Some of you who have installed XenApp or XenDesktop over the years know that this takes extra time and you have to follow your checklist or the wizard to make sure you didn't miss a step.  What if you didn't need to do that?  Or what if we could greatly simplify the entire process?

Here is an example I think you will like.

Recently released is a Technology Preview of a desired state configuration resource for XenDesktop.  You can find it here:

Follow the admin guide and place the module in the PowerShell path on your target (and the machine where you create configurations) and move forward.

Since I will be using this in upcoming examples, lets give it a quick description.

This brings together a few of the previous articles.

Lines 9 - 12 coupled with line 47 sets the local configuration manager (LCM) to handle reboots on its own.

Lines 15 - 20 creates my unzip and logging path

Lines 24 - 30 unzips my media.  I know what the name of my media is and I expect that media to be delivered to the same path where this script is being run by some other agent or process - such as an external process that downloads the media plus this script to the same path and then runs this script.

Lines 33 - 38 call the XenDesktop resource and install one of the roles defined.

If the role installation sets that the system requires a reboot, the LCM handles that.  On reboot it processes the configuration again, until the XenDesktop resource returns 'true' for ensure being set to 'present'.

For the Controller this is generally one reboot, for a session host or VDA tis could be two reboots.  The great thing for me is that it is totally hands off.  DevOps in the XenDesktop world.

Personally, I hope that you check this out, and I am looking for feedback on where this needs to go next and if it is useful to you.  So please, speak up in comments, in the forum, or complete the survey.

Next - lets show this all in action in some real use cases.

Tuesday, September 30, 2014

Using the native DSC resources

In my previous posts the focus was on giving some background into how desired state configuration DSC works, some ideas about how to use it, and some details around a very simple example.

Here I am going to walkthrough a configuration that uses a number of the built in DSC resources to apply a configuration.

First, I want to back up a bit and mention a concept.  If you read through many of the blog posts and TechNet documents out there all of the examples you see you could easily describe as being installation focused.  Or only making changes to the system that one would do when installing something.  And this observation is correct.  DSC is still in that v1 state at this writing which means that folks are getting used to it, using it, extending it.  And frankly talking about installation actions is relatively easy. 

One thing I want to mention now is that anyone can build a Custom Resource.  And if you want to configure an application, this is the way to go.  Put all of your complex logic into that custom resource.  Or, wait for the software vendor to write that custom resource so you can use it.  And you may need to ask them to do that for you to get the ball rolling.  There is nothing that says that DSC cannot be used to configure the applications that it also installs in a previous step.  We will get closer to that later on.

Back to this example, installing a Citrix License Server using DSC resources.

Before we get into my example I want to mention a couple things:

  1. In my setup I am using the full XenDesktop media ISO as a ZIP archive and I am hosing it on an HTTP endpoint (IIS Server).  This is an internally hosted, isolated, and unsecured endpoint - it is strictly an example to demonstrate different resources and possibilities.  In other words, please learn from the example but please "don't do this at home". 
  2. Also,  I am not demonstrating any commands that are not already documented in Citrix eDocs nor the DSC documentation in TechNet.  You need to read those sources for the definitive and current documentation.

Here is the configuration script sample:

Lets start to work through this example.

On line 3 is something new; Import-DscResource.  This is now modules are invoked when they are not shipped as part of the operating system.  Prior to being able to apply this configuration the module xPSDesiredStateConfiguration must be in the PowerShell path.  If you observe the behavior of a Pull configuration you will notice that it uses the path "%programfiles%\WindowsPowerShell\Modules" - and because of that I tend to use that one myself.  More on custom resources later.

On lines 7 - 12 you see the [File]citrixFolder resource that I have been showing in the previous articles.

On lines 14 - 31 is something new as well.  The Script resource

This is a utility resource that fills a gap when there is no other resource available to perform your actions.  When you use the Script resource you essentially write a mini custom resource - it has all the same base requirements of a custom resource provider. 

In this case I am using the web client to download the XenDesktop media to the %programdata% path I defined with [File]citrixFolder.  You might also notice that there is a dependency on that previous resource to ensure that the path exists prior to downloading.

Lines 33 - 39 use the Archive resource.  Here I define the path where I know the ZIP exists (previous dependency), and the destination I want it extracted to.

If you run the -Verbose switch when applying this configuration you will notice some interesting behavior with this provider.  The archive provider actually opens the ZIP, reads every file and tests the destination for the existence of the file.  If a file exists, it is not extracted, if it does not exist it is extracted.  This is just a bit of insight into the thinking around how desired state works and what it means to apply a configuration.

Lines 41 - 50 use the Package resource.  This resource is used to install or uninstall packages.  It is centric to MSI packages but it can also be used with EXE packages.  The installer must support silent installation.  Also, as you can see I left the ProductId empty - that is a property of MSI packages so I had to define it this way.

Lines 52 - 57 are the reason for the Import-DscResource.  Within that module is the provider xRemoteFile.  This resource allows me to use a URI as the source.  I defined the source file and my destination - and this places my license file right where my license server default path is.  Ready to go!

Why didn't I use this in place of the script extension?  Good question.  It is because the file I am downloading using the script resource is too large and the download fails at 1.7 Gb in a very reliable way (it is actually a very old bug).

That is it.  The hardest part is getting the infrastructure working to get the media and files delivered.

But quite honestly, MSFT is working on that problem.  Have you heard of OneGet or PSGetOneGet is all about packages, packages that could be used by DSC.  PSGet is about PowerShell modules.  And, you can set up your own internal version if you don't trust the public repositories.  But the nifty thing is this; ISVs can publish their packages to OneGet - and then their customer just points to it and before you know it that application is downloaded and installed.  Really nifty delivery method - almost like yum for Windows.

Friday, September 26, 2014

The next step for DSC configurations

Just to recap, this is a series regarding Desired State Configuration which shipped with Windows Management Framework v4 (Server 2012 R2 / Windows 8.1).  There are some references in my first article if you want to get deeper, and there is always TechNet and MSDN documentation.

In this article I am going to expand on my simple example from the last article.  Step it up a notch if you will.

The first thing I am going to cover is the DependsOn property.

This is why each of your declared resources has a name.

Lets consider the following sample:

The Log resource DependsOn the File resource citrixFolder.  What this means is that the File citrixFolder must complete or else the Log afterCitrixFolder will not be attempted.  Another way to say this is that the test for citrixFolder must return True.

This allows a chain of dependencies to be defined.  Defining them here, the configuration author must know about the dependencies and declare them.  Another option is that the resource provider itself is aware of dependencies and enforces them, but that is definitely an advanced topic.

In the last article I had mentioned that the Local Configuration Manager configuration could be changed.  This to is a configuration, and a special command.

Here is my scenario, I have a package installation that DSC is handling for me.  This is a complex installation and it requires two reboots for everything to be installed properly.  I want DSC to handle the rebooting, I don't want to have to setup jobs and start-up commands and the like as in the past.

For this I use the following example;

The first thing to notice is lines 6 through 10.  This is a special resource; localconfigurationmanager.  It supports modifying the properties of the LCM itself.  In this case the reboot behavior is false by default and I want to set that.

After I generate the MOF document, there will be two documents in the .\sample path.  The localhost.mof as before and a localhost.meta.mof that defines the behavior of the LCM.  Set-DscLocalConfiguraitonManager applies the LCM configuration and then Start-DscConfiguration applies the remainder.

If you have done any blog reading of DSC you would most likely have run across the 'Pull' model (and realize that I have been showing the 'push' model) of applying and managing configurations.

I bring this up now just to mention that the Pull model requires the LCM to be configured this way; as shown here:

In this sample I am setting the GUID that matches the configuration of this machine, I am telling it that it is using WebDownloadManager to download its configuration, the URL of my DSC Pull Server, that it will only apply the configuration and then stop, that it will reboot, and I set the frequency down to the minimum since I am impatient.

Just like above, This is a modification of the Local Configuration Manager on the target machine.

The Pull model is pretty handy, as there is simply one web endpoint where configurations call home to and then fetch their configuration and apply it.  If I change the configuration, I change it here and when the node performs its refresh it will look to see if the configuration changed and if it did the new configuration is downloaded and applied.

Pretty slick feature.  But I have to admit, keeping a bunch of GUIDs straight is not the easiest thing.  In this mode each configuration is the GUID identified by the ConfigurationID.  And you have to make sure you give the right configuration ID to the right VM.

Optimally, you set up an array and simply randomly assign one configuration to a machine out of a bunch of machines and wait for the magic to happen.  That is really where that model works.

If you really want to get into all of the possibilities of applying configurations to machines there is a good blog article that describes the options when you want your machine to automatically configure on boot up with DSC.  There are some interesting options in there such as

  • using mini-setup and the unattend.xml to set a task to run a configuration script on boot.
  • drop a pending.mof in the path %systemdrive%\Windows\System32\Configuration (mount the vhd and copy the file in) that the LCM will automatically process on boot
  • inject a meta-configuration (the configuration of the LCM) to download its configuration document

Not mentioned is that you can use and agent in the VM to execute a script, set a MOF, or trigger the LCM in a number of combinations.  And there is also remote applying a configuration as this is what Start-DscConfiguration uses by default using the -ComputerName of a remote machine (you have to be administrator).

Using SCVMM Service Templates the DSC configuration script would be the 'script application package' being executed by the SCVMM agent.  And the model is similar for a Windows Azure Pack Gallery Image.  If you are deploying to Azure you can use the VM DSC Extension or the VM Script Extension - both through the Azure API.

So, as you can see, the flexibility is all over the place.

Monday, September 22, 2014

How does Desired State Configuration work

Windows Management Framework v4 included a new feature; Desired State Configuration.  This is the second in a series of articles describing Desired State Configuration with the intent on giving a sip instead of a fire hose to get you into it.

In the previous post I made an attempt to introduce all of the moving parts of Desired State Configuration.  This is an introduction to the basics of the ability it brings and I am going to describe how it works by walking through a very basic sample.

Just to avoid confusion, I am going to follow the pattern that you see in many of the blogs, with a lot of words around it.  That said, it is rare to find a discussion of the MOF document itself.  Most articles focus on generating the MOF configuration and then applying it.  But I want you to be clear that there is a separation.

In my sample I am working in the PowerShell ISE instead of a console.  It is still just a PowerShell session running in my security context.

I am going to assume that you know what localhost is (the machine where I am executing commands).

First of all, I have a PowerShell script (a series of commands) that creates a configuration in memory, writes that configuration to a MOF document, and then applies that configuration to localhost.  MSFT refers to this configuration as configuration data at this point.  It is not a configuration until it is written to the MOF.

Here is the sample that relates to this article:

Lets first look at lines 2 - 14.  The special function 'configuration' is being used to declare a configuration named 'sample' surrounded in brackets.

Within the configuration 'sample' is one node element, it is named 'localhost'.  This node specifies the computer(s) the configuration applies to. It must match / resolve to a computer name for the configuration to be applied.  I could quickly get complex here and I am consciously trying to avoid that.  Lets just keep this to the local computer at the moment*.

Within the node is a state of a DSC Resource.  In this case the File resource which is built-in.  I named this File state 'citrixFolder' (each defined state has a name, I will mention more about that later).

The File resource has parameters.  I have defined that ensure is 'present' (it exists), the type as 'Directory' (so that it does not think I am defining a File), and the path.  If I stated this I would say: "ensure that a directory named 'EasyButton' exists at the path C:\ProgramData\Citrix\EasyButton"

I then close each element of the configuration.

On line 17 I call the configuration named sample - the same way you would call a function.

What this does is generate a folder .\sample and within that a MOF document - .\sample\localhost.mof  (note the '.\' in the path.  Since I did not define a literal path for the output).

If I look at localhost.mof, I can see how this looks in the MOF format.

You can see that it was generated by me, and my workstation is named scooter, as well as the time and date, and the configuration that I defined for the node localhost.

Now, lets apply this configuration - make it a reality.  That is where line 20 of the sample script comes into play.

I start the DSC Configuration engine and tell it to apply the configurations found at .\sample to the computer localhost.  I force the action, I request verbose output, and I want to wait.  Verbose is handy to show you what is happening.  Waiting makes the configuration run within the session, instead of off on a job thread.  Useful for debugging.

As you can see from the verbose output the first thing that happens is that the current state is evaluated.  Then the local configuration manager decides if it needs to make a change.  In this case the test of "is the directory C:\ProgramData\Citrix\EasyButton present" returned false.  So the Set is called to make that change.  The change returns a success and the local configuration manager moves on.

The behavior of the local configuration manager can be modified as well.  Since a configuration can be applied (make the changes), or applied and enforced (make the changes and be sure nothing changes), or applied and monitored (make the changes and toss an event if something changes).  More about that later.

* I am sure that some of you could imagine multiple node names, or multiple node elements (one big document defining multiple nodes) with the same document fed to them all.  Then only the configuration that matches the computer name is applied.