Bug in xWebAdministration module in DSC resource kit on Windows 2008 / IIS7

At one of the clients that I’m working we’re doing a proof of concept on using Release Management vNext type release templates for deploying their application. We’re using Powershell Desired State Configuration (DSC) for the actual deployment script.

One of the requirements is that we should also be able to deploy to the existing environments, running Windows 2008R2 and IIS7. Since the application is a simple web application, I was using the xWebAdministration module from the DSC Resource kit. When deploying to a Windows 2012R2 machine with IIS8, everything worked like a charm. However, when deploying on a Windows 2008R2 machine with IIS7, I got all sorts of weird error messages. There were already a couple of websites running on that machine, and it seemed as if the DSC script was trying to update those. Of course, it shouldn’t touch already existing sites.

After a bit of searching, I ran into this bug on Connect. Apparently there is a problem with the “Get-Website” cmdlet on IIS7. It returns all websites, instead of only the one specified with the “-Name” parameter. Since the xWebAdministration module uses “Get-Website -Name xyz” to get a reference to the website it should modify, it’ll try to update all the websites in the IIS server. So that explains it. Now, how to solve this?

Actually, the solution is not very complicated. The easiest is to modify your copy of the xWebAdministration module. Open the “MSFT_xWebsite.psm1” file in your favourite editor. You’ll find it in the “DSCResources\MSFT_xWebsite” folder.

Then, do a “find and replace” and replace this:

$Website = Get-Website -Name $Name

With this:

$Website = Get-Website | Where { $_.Name -eq $Name }

You should find five occurrences of the above snippet. After doing the replace, save the file and run your deployment again. If all is well, it should work now 🙂

Happy deploying!

Advertisements

"Failed setting account on COM permissions" and "Unhandled Exception" when installing TFS 2015 using local machine accounts

Recently the folks at Microsoft released the first CTP for Team Foundation Server 2015. Eager to check out the new features I fired up an Azure virtual machine and tried the installation. I like to have full control over what is happening, so I decided to run the “Full Server” (called “Advanced” in TFS 2013) wizard:

image

I had created local accounts for the TFS service account and the build service account (“tfsservice” and “tfsbuild”). In the appropriate screens in the installation wizard, I entered them as “.\tfsservice”:

image

and “.\tfsbuild”:

image

When clicking “Test” I got some nice green checkmarks, so I figured all was OK.

However, when continueing with the installation it went sideways… Of course, these are CTP bits so this can be expected. First I got an error telling me that “VsoJobAgent.exe” had stopped working:

image

And then the configuration wizard failed at the “Configure services” stage:

image

When digging into the logs I found two messages related to accounts and permissions:

[Error @11:39:03.930] Unhandled Exception: System.Exception: The windows service logon account '.\tfsbuild' is not a valid account. Please make sure you provide the correct account. 
[Error @11:39:03.930]   at Microsoft.TeamFoundation.DistributedTask.Agent.AgentConfigurationHelper.Configure(IResourceManager resourceManager, Dictionary`2 settings, String agentName, String workFolder, String windowsServiceLogonAccount, String windowsServiceLogonPassword, String sharedServiceIdentityName, String sharedServiceIdentityPassword, Boolean force, Int32 maxWorkerCount, ServiceStartMode startMode) 
[Error @11:39:03.930]   at VsoAgent.AgentManager.ConfigureAgent(IResourceManager resourceManager, Dictionary`2 settings, CommandLine commandLine) 
[Error @11:39:03.930]   at VsoAgent.Program.Main(String[] args) 

and:

[Error @11:39:12.974] Failed setting account on COM permissions 
[Error @11:39:12.974]   System.Security.Principal.IdentityNotMappedException: Some or all identity references could not be translated. at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess) at System.Security.Principal.NTAccount.Translate(Type targetType) at Microsoft.TeamFoundation.Admin.ConfigureSetComPermissions.Run(ActivityContext context)

This made me think that maybe I need to provide the full computer name when specifying the accounts, so I gave that a try:

image

image

This time the configuration completed successfully!

image

Happy previewing!

.psd is not .ps1

My first experiments with DSC consisted of a simple website that I wanted to deploy to a virtual machine I had running in Azure. Seems simple, doesn’t it? So I went ahead and created a DSC script and a file containing the configuration data, as described nicely on this blog: Separating “What” from “Where” in PowerShell DSC. So I ended up with two files: “Deploy.ps1” with my DSC configuration and “TestEnv.psd1” with the environment specific configuration data. Those two can be put together like so:

 
# Pass the configuration data to configuration as follows: 
Sample_xWebsite_FromConfigurationData -ConfigurationData TestEnv.psd1 

Where “Sample_xWebsite_FromConfigurationData” denotes the configuration as defined in the DSC script. When running this from a powershell prompt, it worked like a charm. Next step was to stick this in a vNext Release Template and run it from Release Management.

When configuring a vNext Release Template in Release Management, you’ll have to provide a “PSScriptPath” and “PSConfigurationPath” inside the “Deploy Using PS/DSC” block:

image

So I figured I’d provide the two files that I had prepared, one being the .ps1 file with the DSC configuration and the other being the .psd1 file with the configuration data. However, when running the deployment I got a bunch of weird errors, suggesting that my configuration data wasn’t passed to the DSC configuration. After doing some debugging I found that that was indeed the case.

Eventually I got the solution. Essentially: the “PSConfigurationPath” in Release Manager expects a regular Powershell script. So: a .ps1 file. If you supply a .psd1 file, Release Management will happilly run your deployment, but your configuration data will not be passed to your DSC configuration.

The solution is to put your configuration data in a variable, and pass that to your configuration. So, the DSC configuration looks something like this:

 
configuration Sample_xWebsite_FromConfigurationData {  	
  Node $AllNodes {
    ......  		
    # Copy the website content  		
    File WebContent 
    {
      Ensure = "Present"
      SourcePath = $Node.SourcePath
      DestinationPath = $Node.DestinationPath
      Recurse = $true
      Type = "Directory"
    }
    ...... 
  }
}
Sample_xWebsite_FromConfigurationData -ConfigurationData $configData

Notice the “$configData” parameter in the last line? That comes from the configuration data script:

# Hashtable to define the environmental data
$configData = @{
  # Node specific data
  AllNodes = @(
    @{
      NodeName = "*"
      WebsiteName = "FourthCoffee"
      SourcePath = "C:\BakeryWebsite\"
      DestinationPath = "C:\inetpub\FourthCoffee"
      DefaultWebSitePath = "C:\inetpub\wwwroot"
    }
  );
}

Make sure you save this as a .ps1 file! Then include it in your vNext Release Template in the “PSConfigurationPath” and all will be well!

Happy releasing!

Release Management vNext pitfalls

Recently I have been playing around with vNext Release Templates in Microsoft Release Management. These type of deployments use Powershell Desired State Configuration (DSC) to perform the actual deployment of your application to the target environment. While this generally works very well, I had a couple of “head-against-brick-wall” experiences which – I must admit – did cause a bit of an headache. This post is the first in a series to share some of those experiences, so that you can avoid them.

Installing WMF 4 requires .Net 4.5

I knew that in order for DSC to work I needed to install Powershell 4, which is part of the Windows Management Framework (WMF) 4.0. So I went ahead and downloaded and installed WMF 4.0. However, my DSC scripts wouldn’t work. Turns out you need to install .Net Framework 4.5 before you install WMF 4.0. A good way to check if everything is OK is to open up a Powershell prompt and type:

 $psversiontable 

That should return a PSVersion of 4.0:image

More information can be found in this post on the Windows Powershell Blog: WMF 4.0 – Known Issue: Partial Installation without .Net Framework 4.5

Happy DSC-ing!

Using icons from TFS

Recently I wanted to use some icons from the TFS user interface in a user manual that I was writing for a client. Of course there is the option to take a screenshot, but then the background is included and that didn’t look very pretty. And I like pretty ;-).

So I went looking for where those icons actually come from. I fired up the Chrome developer tools (hit F12) and poked around a bit with the inspector in the TFS web UI. There I eventually found the CSS for the build succeeded icon:

image

Notice the “-3696px” and “-16px”? This is a technique called CSS sprites. Essentially, that means that you take a small piece of a larger image file and show that. In this case, that larger image file is “tfs-icons.png”. And now it’s starting to get interesting… You can find this file in the directory where TFS is installed on your application tier. In my case (the default), this was “C:\Program Files\Microsoft Team Foundation Server 12.0\Application Tier\Web Services\_static\tfs\12\_content”. In there, you’ll find all icons used in the TFS web UI. Some of them are displayed using CSS sprites, others are just regular images.

Most of the icons can be found in the “tfs-icons.png” file. I used Paint.net to cut out the ones I needed. Just beware you don’t distribute them as part of your own product.