But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Using VSTO to access TFS

Have you ever thought ‘I know that you get the Team ribbon in Excel to manage TFS work items, and I can use Excel to as a SQL/OLAP client to run reports from the TFS warehouse but I want to do more….’?

Have you every considered using VSTO to create an ActionPane that uses the TFS .NET API?


In this example I have created an ActionPane that allows you to select a Team Project Collection, a Team Project and then a build definition. Press the button and it lists the builds that have run of this type using the TFS .NET API.

The code can be downloaded here, it is fairly basic, could be more exception handling for connection failures, but shows the principle.

Cannot connect to a Lab Management Environment using the MTM Environment Viewer

Today we had a problem that we could not connect to VMs within a Lab Management environment from the Environment Viewer in MTM. We had composed the environment from VMs independently create and tested on the HyperV host. The plan in the end is to have this as a network isolated environment, but for now it is a private domain that exists on our main LAN.

The first issue we had was that as this was a private domain the various hosts were not registered on our DNS, so we got a DNS lookup error for the VM host names. This is best fixed with network isolation, but for a quick fix we put some entries in a local hosts file on the PC we were using to resolve the name to IP addresses.

The next problem was one of concepts. The environment had been composed by one user (and could access everything via a host connection via Hyper-V, with no local host file fixes), but it was to be used by another user, a tester who was not the owner of the environment (yes again I know we should they should be provisioning their own network isolated version). This mean that a Hyper-V based host connection was not possible, as you have to be the owner to get a host connection.

This meant that the new user had to use a guest connection, a Remote Desktop Connection (RDC) created behind the scenes by the MTM Environment Viewer. This worked for the domain controller (a server OS) but failed for the other three VMs in the environment which were all running Windows 7 with a ‘lost connection to virtual machine error’


Turns out the issue was the level of security set for RDC connection in Windows 7. We remoted onto the VMs with the problems using the standard Windows RDC client (not MTM) and set the Allows connections from computers running any version of RD.


Once this was done the Environment Viewer could make guest connections and all was good in the world.

Recording Silverlight actions on Microsoft Test Manager

Whilst try to record some manual tests in MTM for a new Silverlight application I found I was not getting any actions recorded, just loads of “Fail to record the object corresponding to this action” warnings in the actions window.

Turns out to fix this you have to do three things

  1. Install the Visual Studio 2010 Feature Pack 2 (MSDN Subscribers Only) – this adds Silverlight support to MTM (this I had already done)
  2. In your SIlverlLight application you need to reference the Microsoft.VisualStudio.TestTools.UITest.Extension.SilverlightUIAutomationHelper.dll  from the folder C:\Program Files (x86)\Common Files\microsoft shared\VSTT\10.0\UITestExtensionPackages\SilverlightUIAutomationHelper
  3. Finally if using IE9 you need to run IE in IE8 mode. To do this in IE9 press F12 and select the browser mode


Once this was done I got the actions I would expect


Cross domain usage of TFS Integration Platform

Whist trying to do a cross domain migration of some source between two TFS2010 servers, I got the less than helpful runtime exception

System.ArgumentNullException: Value cannot be null.
Parameter name: activeWorkspace
at Microsoft.TeamFoundation.Migration.Tfs2010VCAdapter.TfsUtil.CleanWorkspace(Workspace activeWorkspace)
at Microsoft.TeamFoundation.Migration.Tfs2010VCAdapter.TfsVCMigrationProvider.ProcessChangeGroup(ChangeGroup group)

On checking the _tfsintegrationservice_<timestamp>.log I found the more useful

TFS::Authenticate : Caught exception : Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException: TF30063: You are not authorized to access tfsserver.otherdomain.com. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.

The issue is that when you setup the migration you are prompted for credentials for the remote server, but the actual migration does no occur in the same thread as you setup the definitions, so it only has its local credentials and none for the remote system. Hence the 401 error.

There is no way to enter two sets of credentials within the Integration tool itself, but there is a workaround on Willy’s Cave. This is to place the remote credentials in the PC’s credential manager, this work fine for me

Creating a TFS Team Project Collection using Powershell

Grant Holiday posted on how to create a TPC using Powershell. However his post did not address how to set the SharePoint or Reporting Services parameters. His example used for the form

Dictionary<string, string> servicingTokens = new Dictionary<string, string>();
servicingTokens.Add("SharePointAction", "None"); // don't configure sharepoint
servicingTokens.Add("ReportingAction", "None"); // don't configure reporting services

So not much use if like ourselves you have your TFS integrated with the company wide SharePoint farm

Finding the Parameters (the hard way)

If you want configure SharePoint or Reporting Services it turns out there is not source of documentation for the process. So thanks then to Chris Sidi for telling me how to find out the required options. This is his process to find out what parameters a TPC needs to be created with:

  1. Create a TPC via the TFS Administration Console, specifying a custom configuration for Sharepoint and Reporting for your system.
  2. In the Administration Console at the bottom of the screen, switch to the Status tab. Double-click “Create Collection” to load the servicing log.
  3. In the first ~15 lines of the servicing log, find the JobId (e.g. “Setting token. Key: JobId. Value: 9638bd57-f494-4ac3-a073-dd1548ab24dc.”)
  4. Using Powershell, query the servicing tokens used:

[Reflection.Assembly]::Load("Microsoft.TeamFoundation.Client, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$credProvider = new-object Microsoft.TeamFoundation.Client.UICredentialsProvider
#Update the TFS url as necessary
$tfsConnection = new-object Microsoft.TeamFoundation.Client.TfsConfigurationServer "
http://localhost:8080/tfs", $credProvider
$jobService = $tfsConnection.GetService([Microsoft.TeamFoundation.Framework.Client.ITeamFoundationJobService])

# Replace the JobId. Use the one in the servicing log.
$jobId = '9638bd57-f494-4ac3-a073-dd1548ab24dc'
$servicingJob = $jobService.QueryJobs([Guid[]] @($jobId))[0]

This script gets the list of parameters as shown below which we can pass into the PowerShell script used to create a new  TPC.

SharePointAction UseExistingSite
SharePointServer 3eYRYkJOok6GHrKam0AcSA==wytV0xS6vE2uow3gjrzAEg==
SharePointSitePath sites/test
ReportingAction CreateFolder
ReportServer 3eYRYkJOok6GHrKam0AcSA==KRCi2RTWBk6Cl1wAphaxWA==
ReportFolder /TfsReports/test

It is shame the SharePoint and Reporting Services servers are returned as hash codes not their URLs, but as these will probably be fixed for any TFS implementation this is not a major issue as they can just be hardcoded.

Finding the Parameters (the easy way)

Once I ran this script I actually noticed that I already had access to this information without running  PowerShell or creating any trial TPCs. Isn’t that so often the case the information is under your nose but you don’t recognise it.

Actually all the parameters are actually shown at the start of the creation log for any TPC creation on a given TFS server. Just look for the log files via the TFS admin console.

[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational] Creating dictionary with 14 initial tokens:
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     FinalHostState => Started
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     VMM_SHARES (Value is an empty string.)
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     VMM_HOSTS (Value is an empty string.)
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     INT_USRACC (Value is an empty string.)
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     SharePointAction => UseExistingSite
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     SharePointServer => 3eYRYkJOok6GHrKam0AcSA==wytV0xS6vE2uow3gjrzAEg==
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     SharePointSitePath => sites/test
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     ReportingAction => CreateFolder
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     ReportServer => 3eYRYkJOok6GHrKam0AcSA==KRCi2RTWBk6Cl1wAphaxWA==
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     ReportFolder => /TfsReports/test
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     DataTierConnectionString => Data Source=sqlserver;Initial Catalog=Tfs_Configuration;Integrated Security=True
[Info   @11:12:34.876] [2011-05-04 20:32:36Z][Informational]     CollectionName => test
[Info   @11:12:34.876] [2011-05-04 20:32:37Z][Informational]     InstanceId => 0cf30e1d-d8a6-4265-a854-9f6c5d288f7e
[Info   @11:12:34.876] [2011-05-04 20:32:37Z][Informational]     DefaultDatabase => Data Source=sqlserver;Initial Catalog=Tfs_test;Integrated Security=True

The revised TPC creation script

So given this new set of parameters we can edit Grant’s script to pass in all the extra parameters as shown below

    [string]$tpcName = $( throw "Missing: parameter tpcname"),
    [string]$serverUrl = http://localhost:8080/tfs/ ,
    [string]$sqlServer = "sqlserver" ,
    [string]$spBase = "sites", 
    [string]$spServer = "3eYRYkJOok6GHrKam0AcSA==wytV0xS6vE2uow3gjrzAEg==", 
    [string]$rsBase = "TfsReports",
    [string]$rsServer = "3eYRYkJOok6GHrKam0AcSA==KRCi2RTWBk6Cl1wAphaxWA==" )

Write-Host "Using the TPC with the following settings"
Write-Host "tpcName:   $tpcName"
Write-Host "serverUrl: $serverUrl"
Write-Host "sqlServer: $sqlServer"
Write-Host "spBase:    $spBase"
Write-Host "spServer:  $spServer"
Write-Host "rsBase:    $rsBase"
Write-Host "rsServer:  $rsServer"

# Load client OM assembly.
[Reflection.Assembly]::Load("Microsoft.TeamFoundation.Client, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");

# Get the server
$tfsServer = new-object Microsoft.TeamFoundation.Client.TfsConfigurationServer $serverUrl;

# Create the token set
$servicingTokens = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]"

$spPath = $spBase +"/" +  $tpcName;
Write-Host "Sharepoint path is  $spPath"
$servicingTokens.Add("SharePointAction", "UseExistingSite");
$servicingTokens.Add("SharePointServer", $spServer);
$servicingTokens.Add("SharePointSitePath", $spPath);

$rsPath = "/" + $rsBase + "/" + $tpcName
Write-Host "Reporting Services path is  $rsPath"
$servicingTokens.Add("ReportingAction", "CreateFolder");
$servicingTokens.Add("ReportServer", $rsServer);
$servicingTokens.Add("ReportFolder", $rsPath);

# Create and run the job
$tpcSvc = $tfsServer.GetService([Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService]);

$sqlString ="Server=$sqlServer;Integrated Security=SSPI;"
Write-Host "SQL connection string is  $sqlString "

$job = $tpcSvc.QueueCreateCollection(
    $tpcName,      # collection name.
    "",                  # description.
    $false,              # don't make this the default collection.
    "~/" + $tpcName + "/",   # virtual directory.
    "Started",           # State after creation.
    $servicingTokens,               # tokens for other services.
    $sqlString,       # The SQL instance to create the collection on. Specify SERVER\INSTANCE if not using default instance
    $null,               # null because the collection database doesn't already exist.
    $null)               # null because the collection database doesn't already exist.

Write-Host "Creating TPC (this could take a few minutes)"
$collection = $tpcSvc.WaitForCollectionServicingToComplete($job)
Write-Host "Compeleted"

If you get any errors from the script the best place to go is the TFS Admin console to look at the logs (the same ones you used to find the parameters). You should see the detailed create process log that gives normal TF errors as to why the process has failed; usually rights on SharePoint for Reporting Services from my experience.

Problems and workaround for the EMC Scrum for Team System Process Template

I have recently been looking at the EMC Scrum for Team Systems (SFTS) 3 Template for TFS 2010 with SharePoint 2010. The core of it works, and works well for Scrum based teams. If you have not used it before have a read of the getting started post to get a feel of what it can do.

However, there are some issues when you try to make use of SharePoint 2010 as opposed to SharePoint 2007. Hopefully you will find some of the adventures I have had enlightening


The first one is that the installation and configuration tools just ignore SP2010. This means when you try to create a team project using the process template you get the error:

“TF249033: The site template is not available for the locale identifier (LCID).” ”The site template name is: SCRUM.”

You have to manually download and install the SharePoint template WSP, as detail in this blog post. Once the WSP is deployed on your SharePoint 2010 farm you can create new team projects using the process template.

How it looks

There are problems with the way the site renders. The two major issues are the site actions drop down appears behind the main display area (red box in left screen shot), and on some page large blocks of CSS get rendered to the screen as opposed to being dealt with programmatically (right screen shot).

image image

Both of these issues have been reported on the support forum

My reading is that the current SFTS SharePoint template WSP has only had minimal changes to port it to SP2010 from SP2007, just enough to get it to load. I think the key issue here maybe that the SFTS SharePoint template has its own master page. This is something all TFS 2005/2008 templates tended to do, but for 2010 there has been a general move to inherit from core SharePoint master pages. Basically the master page structure needs to be rebuild from the ground up by EMC for fix all the issues, but we can address some of them…

Change the master page

Fixing all the issues in the master page is somewhat daunting as 2007 and 2010 master pages are very different in style. However, after a chat with one of our SharePoint developers it was suggested a better solution is to just tell the site just to use a different master page (one of the SP2010 standard ones). This is a technique we have used on bespoke site upgrades and usually will address most of the issues, then it is a matter of fixing the, hopefully smaller, list of outstanding problems.

So below is the process to make the change

  1. Install SharePoint Designer 2010 on a PC (this is a free download from Microsoft)
  2. Logging in as a user with admin rights on the site, open SP2010 Designer and open the url of the Scrum for Team System SharePoint Site e.g. http://tfsdemo/sites/DefaultCollection/team1
  3. In the site objects tree on the left select the master pages node
  4. You should see four master pages
  5. Right click on the v4.master and select ‘set as custom master page’
  6. Load the site in a browser and it should look like a more normal SP2010 site
  7. You can swap it back by making the SFTS.master the custom master page


Actually on first look the swapping the master page seems to have done the job on the homepage in default view mode without any other edits. However, there are still problem of stray CSS being shown when accessing the other pages, and a trace of green in some of the borders.

So a partial success, but with more work maybe a complete one? But that is not the route I took.

Report Title Click-through

Both the SFTS and standard Microsoft reports are displayed in dashboards the same way, they use a page view webpart and the TFSredirect.aspx page. This shows the report chart and a link to take you to its Reporting Services home when the title is clicked. The rendering of the report works for SFTS, but another reported problem is that when you click the report title links (highlighted in green in above graphic) you get the error

TF250008: This SharePoint site is not currently associated with a team project in Team Foundation Server. To ensure that this site functions correctly, you must configure a team project to refer data for that project to this site. For more information, see this topic on the Microsoft Web site: How to: Add a Team Project Portal. You can use the following querystring argument to specify a specific project: tf:ProjectId.

The error says a workaround is to pass the TF:ProjectID parameter in the title URL. This is the only solution I have found. To do this

  1. Load SQL Management Studio
  2. Open the tfs_defaultcollection DB (or the one for your tema project collection) and the tbl_projects table.
  3. Look for and copy the projectID for the project you want to report on
  4. Open the SharePoint page with the failing chart. Click the small down triangle in the top right of the webpart to get the webpart editor.
  5. In the advanced section add &TF%3aPROJECTID={guid} with your {GUID} to the end of the Title URL (the %3a is the : character)
  6. I also had to remove the &IsDashboard=false else I got a “An attempt was made to set a report parameter 'IsDashboard' that is not defined in this report. (rsUnknownReportParameter)” error.
  7. Press OK to save, the chart should render and the link work

Basically the title URL as automatically build is wrong, it has an extra parameter the report does not support and for some reason the automatically passed project ID is being lost. In fact even when you fix the Url is wrong as the report it points to is a dashboard summary when you probably want to take the user to a fuller version of the report. Which of course you could do by altering the Url provided.

I think the root problem here is that the webpart assumes that the report has a dashboard and full version mode, as many of the MSF agile ones do, so this sort of makes sense.If you reports are single mode you need to pass two Urls.

Again this editing is all a bit of pain, but you don’t do it too often, and you could also write a command line tool to easily get the GUID.

But maybe a better overall option?

However, whilst trying all this I realised that the SFTS created SharePoint site does not really do what much ‘special’. Beyond being a basic SharePoint site it has

  • a link to the process guidance, but is just an HTML file that redirects to http://www.scrumforteamsystem.com/processguidance/v3/ so can be added as link
  • a link to the Team Web Access, there is a standard webpart for this or you could just use a link
  • the front page dashboard, this has the two SFTS chart webparts and a TFS query webpart, but we can recreate this ourselves with the standard TFS webparts

Therefore I would suggest the best option to avoid all these SharePoint 2007/2010 issues is to manually create a new SharePoint site and add similar controls to those used by SFTS to make the SharePoint site you want. As long as you are not creating new team projects all the time this should not be too much of a problem.

The steps to do this are as follows:

  1. In Team Explorer create a new Team Project using STFS template but set it not to create a Sharepoint site (you can always use an existing SFTS Team project if you want in place of this step if it already exist)
  2. On the default collections SharePoint e.g http://tfsdemo/sites/DefaultCollection create a new site (site actions), give it a name e.g. ‘Team1’ so it’s URL is http://tfsdemo/sites/DefaultCollection/team1. You can select any site template, but the collaboration/team one would seem a good start, nice and generic
  3. In Team Explorer select the STFS created in step1 and right click, select team project settings | portal settings
  4. Check the enable tram project portal (if not already set) press the configure URL and enter the details of the site created in step 2, press OK to exit
  5. Check the ‘reports and dashboards refer to data for this team project’ checkbox and press OK.
  6. Return to the web site created in step 2, it is now wired to the correct team project

You can now add pages, links and webpart to the web site to build your portal. The most important are

  1. Adding the set of ‘Visual Studio Team Foundation Server Web Parts’ which provide items such a build list, work item list etc.They should all pickup the correct team project.
  2. The page viewer that allows redirections via the TFSRedirect.aspx page as detailed above

We can also link directly to the reporting services reports using the SQL Server reporting web part. As SFTS does not ship its reports as Excel workbooks we don’t have to consider Excel Services..

And finally

I hope this post has given you some ideas as to how to address the issues with SFTS 3.0 on SP2010, enough too keep you happy until there is a release of the template what fully supports SP2010.