29 September 2014

TFS 2013 report template

If you need to create reports for TFS, most of the time it is much easier to create them by copying an existing report.
As I need to do this frequently, I decided to create a template to minimize the amount of work.

Here is a link to the TFS report template.

04 September 2014

Occasional TF255040 error in the [Incremental Analysis Database Sync] TFS Job

When reviewing the job execution log, I noticed the [Incremental Analysis Database Sync] failed several times during the last few days, but not every time.

The strange part was that the error was TF255040 meaning the SSRS components where not installed. It puzzled me at first because the components are installed or they are not, but they cannot be occasionally not installed.

Then I remember a fail-over application tier had been installed a few months earlier without ever being used. It seems TFS suddenly decided to load-balance some jobs to the fail-over application tier. After a quick look it appeared that the SSRS components were not installed on the fail-over app-tier. Installing them seems to have resolved the issue.

22 August 2014

OLE DB error: OLE DB or ODBC error when deploying using Microsoft.AnalysisServices.Deployment.exe

When deploying an ASDatabase file using the Microsoft.AnalysisServices.Deployment.exe tool, you might get a cryptic "OLE DB error: OLE DB or ODBC error" message. The details message includes there was a problem connecting to one of the data sources.

I scratched my head for quite some time until I had a better look at the actual connection string. The server name was correct as well as the database name and security configuration. For example:

Provider=SQLNCLI11.1;Data Source=.;Integrated Security=SSPI;Initial Catalog=MyDatabase_Warehouse

At first I didn't notice the "Provider" part, but then I decided to strip the connection string to the bare minimum, and try again.

Data Source=.;Integrated Security=SSPI;Initial Catalog=MyDatabase_Warehouse

Surprisingly, it worked right away. But I honestly have no idea why it does not work if you specify the provider.
Maybe it is related to differences with the SQL client version installed on the machine that generated the package, but I have no time to further investigate.

EDIT: Apparently it was related to the fact that I selected the "Native OLE DB > SQL Server Native Client 11.0" provider instead of ".Net Providers > SqlClient Data Provider" in the connection string of the datasource in the SSAS project. After selecting the correct provider and rebuilding the package, everything worked as expected.

11 July 2014

TFS Equivalent of SVN Export

Here is a little trick to download the latest version of a source control folder from TFS. The idea is to use the Web Access API to retrieve the data.
Basically, you will get a Zip containing the HEAD version of the specified source control folder.

Here is the URL you have to use :


The yellow parameters are mandatory, the green ones can be omitted.
Replace the parameters as described:
  • tfs-server is the TFS server hostname
  • port is the TFS port (usually 8080)
  • Collection is the name of your team project collection
  • TeamProject is the name of your team project
  • Team is the name of the team
  • url-encoded-source-control-path is the URL encoded source control path (for example, $/Project1/Main/Sources/Folder/SubFolder becomes %24%2FProject1%2FMain%2FSources%2FFolder%2FSubFolder
The main benefit of this URL is that it allows you to retrieve a source control folder without having to create workspaces and mappings (and thus avoiding the manual deletion of the associated $tf folders).

This URL is using Windows Authentication, so if you are using CURL (for example) on a non-Microsoft platform, you have to pass the --ntlm switch together with your windows credentials to retrieve the Zip package.

10 June 2014

About Release Management for TFS Update 2

If you plan on upgrading your Release Management installation from update 1 to update 2, here is a bit of advice:

Do not.

I tried in our internal installation, and everything broke down. The worst part was the TFS integration. It was no longer possible to link a TFS build definition to a release template, rendering them completely useless. And since RM for TFS is all about release template, the whole release infrastructure was absolutely blocked.

I will wait for the next update and hope Microsoft will fix these issues.

As a side note, deploying a brand new Update 2 installation did not fix the TFS issues, so apparently it is not related to the upgrade process.

EDIT (2014-08-22): I have upgraded to Update 3 without problem. It was probably a bug corrected in the last version. 

07 January 2014

Completely remove an application tier from TFS 2012

If you ever wondered if it is possible to completely remove an application tier from the TFS Administration Console, here is an answer for you. Yes, but it is tricky and may result in a broken TFS installation. It involves messing with the catalog in the TFS_Configuration database.

As a disclaimer, this method is absolutely not supported. Not by me, not by my company, not by Microsoft. Use at your own risks.

So if you decide to reproduce the steps I am going to describe, please BACK UP your TFS installation (especially the Tfs_Configuration database).

Now, a little bit of context before starting, TFS uses a set of tables known as the catalog to keep track of the different pieces of your installation. It contains a lot of things including the databases, the servers, the web applications, etc.

Whenever you had a new piece to the installation (app tier, reporting tier, etc.) it goes into the catalog. Our problem is that for the moment there is no way to tell when you completely remove an app tier. So even if you uninstall an app tier, it stays in the catalog and eventually it will go out of sight thanks to the "Filter out machines that have not connected in more than 3 days".

Our goal here is to remove the app tier from the catalog itself. Unfortunately there is quite a bit of steps, and even more things to be aware of.

The first warning is that the steps below will produce the desired output only if you completely remove the server from the installation.

For example, consider a server APP-SERV1 hosting an app tier and another APP-SERV2 hosting an second app tier and SQL Server Analysis Services.

If you want to simply uninstall the app tier from APP-SERV2 but keep the SSAS on it, there is a high chance that this procedure will break your installation.

Actually this procedure removes the server from the catalog including all the other components that could have been part of the TFS installation (databases, reporting, datawarehouse, etc.).

Assuming TFS-APP is the server we'll remove, here is a high level list of the steps we will perform:
  • find the catalog resource for TFS-APP,
  • find the catalog resources for TFS-APP services,
  • find the catalog node for TFS-APP,
  • find the catalog nodes for TFS-APP services,
  • find the properties of TFS-APP,
  • find the catalog node dependencies for TFS-APP and services,
  • remove the items we found.

1. First things first, open a connection to your Tfs_Configuration database.

2. Then we start by looking for our server in the tbl_CatalogResource and tbl_CatalogNode tables:

SELECT 'Resource >'
     , r.*
     , 'Type >'
     , t.*
     , 'Node >'
     , n.*
  FROM [Tfs_Configuration].[dbo].[tbl_CatalogNode] n
  JOIN [Tfs_Configuration].[dbo].[tbl_CatalogResource] r
    ON r.Identifier = n.ResourceIdentifier
  JOIN [Tfs_Configuration].[dbo].[tbl_CatalogResourceType] t
    ON t.Identifier = r.ResourceType
 WHERE r.DisplayName = '{SERVER}' -- Replace with your server name

3. Note the value of the PropertyId, ParentPath, ChildItem, ResourceIdentifier fields. They will be used to identify and then delete the relevant data.

4. Select the properties associated with the catalog resource from the tbl_PropertyValue table.

  FROM [Tfs_Configuration].[dbo].[tbl_PropertyValue]
 WHERE ArtifactId = '{PropertyId}' -- Replace with the value from step 3

5. Select the relevant items from the tbl_CatalogNodeDependency, we are looking for a) the items TFS-APP depends on, b) the items that depend on TFS-APP and its children:

-- a)
  FROM [Tfs_Configuration].[dbo].[tbl_CatalogNodeDependency]
 WHERE ParentPath = '{ParentPath}' --Replace with value from step 3
    AND ChildItem = '{ChildItem}' -- Replace with value from step 3

-- b)
  FROM [Tfs_Configuration].[dbo].[tbl_CatalogNodeDependency]
 WHERE RequiredParentPath LIKE '{ParentPath}{ChildItem}%' -- Replace with values from step 3

6. The records returned by a) will be removed in the end.

7. From the results returned by b) note the values of the RequiredParentPath and RequiredChilditem

Warning: If the app tier was the only TFS component installed on the server, you should only have the "WebApplication" value  in the AssociationKey field, otherwise it means you had other components like databases or datawarehouse installed on the server. In this case, I recommend you make sure you understand the implications. For example, make sure the reports and warehouse were already migrated to another server (check in the TFS Administration Console).

8. Select the APP-SERVER children:

SELECT 'Resource >'
     , r.*
     , 'Type >'
     , t.*
     , 'Node >'
     , n.*
  FROM [Tfs_Configuration].[dbo].[tbl_CatalogNode] n
  JOIN [Tfs_Configuration].[dbo].[tbl_CatalogResource] r
    ON r.Identifier = n.ResourceIdentifier
  JOIN [Tfs_Configuration].[dbo].[tbl_CatalogResourceType] t
    ON t.Identifier = r.ResourceType
 WHERE r.ParentPath = '{RequiredParentPath}' -- Replace with value from step 7
   AND r.ChildItem = '{RequiredChildItem}' -- Replace with value from step 7

9. Note the values of PropertyId, ParentPath, ChildItem, ResourceIdentifier.

10. We have everything we need to start the actual removal of the server.

-- Delete property values
DELETE FROM [Tfs_Configuration].[dbo].[tbl_PropertyValue] WHERE ArtifactId IN ({PropertyId}) -- Replace with values from steps 3 and 9

-- Delete dependencies for TFS-APP
DELETE FROM [Tfs_Configuration].[dbo].[tbl_CatalogNodeDependency]
 WHERE ParentPath = '{ParentPath}'
   AND ChildItem = '{ChildItem}' -- Replace with values from step 3

-- Delete dependencies to TFS-APP and services (Web application)
DELETE FROM [Tfs_Configuration].[dbo].[tbl_CatalogNodeDependency]

 WHERE RequiredParentPath LIKE '{ParentPath}{ChildItem}%' -- Replace with values from step 3

-- Delete nodes
DELETE FROM [Tfs_Configuration].[dbo].[tbl_CatalogNode]
 WHERE ParentPath = '{ParentPath}'
   AND ChildItem = '{ChildItem}' -- Replace with values from step 3 and 9

-- Delete resources
DELETE FROM [Tfs_Configuration].[dbo].[tbl_CatalogResource]
 WHERE Identifier IN ({ResourceIdentifier}) -- Replace with values from 3 and 9

11. Open the TFS Administration Console, you should now see only the active app tiers in the Application Tiers section even if you uncheck the "Filter out..." checkbox.
If the list is empty, it means the catalog is broken and TFS cannot rebuild the dependencies. This can happen if you forgot to delete a dependency on a deleted node.
To find the source of the problem, open the Event Viewer, you should see some TFS Service errors with the following message:
TF246024: An error occured while attempting to build catalog nodes. A catalog node is missing the following path to its parent: [parent path].

One possible solution would be to find the tbl_CatalogNodeDependency record with the RequiredParentPath set to the value in the error message, and then delete the record.

Error when running the TFS Best Practices Analyzer with an account containing a dollar ($) sign

I recently tried to run the TFS BPA using an account containing a dollar ($) sign. It was something like "user$name".
I ended up with a rather strange error message looking like the following:

Cannot validate the URL provided The scan was generated using the corrected URL "%TFSServerURLValidated%".

A quick look at the "Other reports" section of the scan results, I found that the tool was trying to find files in the following directory:


The important part is highlighted.
It seems that some of the PowerShell scripts are analyzing the account name as the literal user followed by a variable named $name, instead of interpreting the whole account name as a literal.

As I didn't want to go through the various PS scripts in the BPA installation directory, I decided to take the lazy approach.
I created a symbolic link C:\Users\user pointing to C:\Users\user$name\ using the following command:

mklink /d \Users\user \Users\user$name

After that the BPA was able to perform the checks as expected.
Of course it is not a long term solution and it works only for my account, but still easier than scanning all the ps1 files to find the culprit.

26 September 2013

Error TF400324 when starting the Visual Studio Test Controller

I recently had a problem starting the Test Controller Configuration Tool. There was no error, but it simply hung on the loading state. A quick look at the event log showed three errors. The most important one was:
The Controller service could not be started. TF400324: Team Foundation services are not available from server: [redacted URL]

The URL was referring to an old team project collection. I actually wanted to use the Configuration Tool to change this URL.

Since I could not attach the controller to another collection by using the Configuration Tool, I started to look around to find where the configuration itself was stored. The answer is an XML file named QTControllerConfig.xml located in C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE.
I opened the file, replaced the content with this:
<?xml version="1.0" encoding="UTF-8"?>
<ControllerConfiguration xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010/QTControllerConfig.xsd">
    <TestEnvironment name="Default" id="8869bc36-5a69-4901-b46a-a38dfbd2ed06">
      <Description>Default Test Environment</Description>
        <MachineRole name="Default" id="dc134fe8-3c53-42e4-bcc1-6f2392e2fb8c" />
    <Property name="MaxAgentVersionOnController" value="11.0.60610" />
After that, I tried to open the Configuration Tool again and it worked.

For the record, updating the URL to the intended one did not work because the test controller itself was not yet registered.

28 June 2013

Visual Studio TFS 2012 and Web Deployment Packages

If you have been using Visual Studio 2010 and TFS to build Web Deployment packages (usable with MS Deploy), there is in the project properties a parameter for the name of the Web application in IIS.
The parameter is available in the Package/Publish Web section under IIS Web site/application name to use on the destination server.
Unfortunately this parameter is not available in Visual Studio 2012.
You can specify it when using the Publish feature (by right-clicking on the project) but if you want to set up builds in TFS, you will end up with an application in IIS with a _deploy suffix.

One possible solution is to add an additional parameter to the MSBuild command to update the IIS Web Application name.
In the process properties of the build definition, update the DeployIisAppPath in the MSBuild arguments:
MSBuild additional arguments

Entity Framework and TFS Build

I recently had an issue when trying to configure automatic deployments in TFS.
I was building a MS Deploy package with one build definition and deploying it with another.
The application was based on ASP.NET MVC with Entity Framework as a ORM
When I tried to open the application on the target server, I got an error "Unable to load the specified metadata resource".

The entity data model was configured to store the model files as resources into the assembly. The error was caused by the fact that the build process was no longer executing the packaging step. Usually Visual Studio does it automatically for you but MSBuild is not so kind. You have to manually tell it to execute the EntityDeploy step.

I added an instruction in the project file (containing the data model) to execute the packaging step.

<Target Name="AfterBuild">
  <EntityDeploy Sources="Models\DataModel.edmx" outputPath=".">

After that I made sure the build definition specified the MSBuild switch to rebuild the binaries (and not just build).