Visual Studio Team System

1 Comment

Since Holland is kicked out of Euro 2008, I found myself some extra time to investigate Visual Studio Team System "Rosario" CTP 12. It's been a couple of months ago Microsoft released this fantastic platform, but almost nobody blogged about it. Of course three of the most interesting VSTS bloggers (Willy-Peter Schaub's, Mickey Gousset and Grant Holiday) commented a lot about it, but that's almost everything you find on the net. Naturally almost every self respecting blogger blogged about the release of this CTP, but in my opinion that's not what blogging is all about.

After starting the virtual machine and opening Visual Studio, I immediately focused on the new Process Templates and the Work Item structure of it. In Rosario there are two new Process Templates:

  • VSTS Process for Agile Software Development v1.0
    • Bug - Describes a divergence between required and actual behavior, and tracks the work done to correct the defect and verify the correction.
    • Shared Step Set - Server-side data for reusable set of test steps.
    • Task - Tracks work that needs to be done.
    • Test Case - Server-side data for a set of steps to be tested.
    • User Story - Tracks an activity the user will be able to perform with the product
    • Issue - Tracks an obstacle to progress.
  • MSF for CMMI Process Improvement - Rosario
    • Bug - Includes information to track the work to resolve the bug and to verify its resolution
    • Task - Includes information to track the task through the MSF for CMMI Process Improvement life cycle.
    • Issue - Includes information to track changes through the MSF for CMMI Process Improvement life cycle.
    • Change Request - Includes information to track changes through the MSF for CMMI Process Improvement life cycle
    • Risk - Includes information to track the work to mitigate a risk.
    • Requirement - Includes information to track the requirement through the MSF for CMMI Process Improvement life cycle
    • Review - This work item tracks reviews and the results.
    • Test Case - Server-side data for a set of steps to be tested.
    • Shared Step Set - Server-side data for reusable set of test steps.
    • Feature - Includes information to track the feature through the MSF for CMMI Process Improvement life cycle
    • Business Objective - Includes information to track the business objective through the MSF for CMMI Process Improvement life cycle

Work Item Structure
In the VSTS Process they removed Risk and replaced Scenario by User Story. This is a good decision because the Risk implementation in MSF Agile is one of the worst implementation of Risk Analysis I ever seen. Didn't the guys who developed this read the specs of MSF Risk Management. CMMI has a better risk implementation but still it could be better. The other two Work Items are for test purposes only. A Test Case describes a test and the steps to reproduce it. In some cases you will repeat a lot of the same steps. For Example: 1. open Internet Explorer, 2. open the Web Application, 3. Log on to the app. These steps are probably used in all Test Cases. To use shared steps you must use the Shared Step Set Work Item.

Work Items

Work Item Link Types
As you can see, the screen layout is completely rearranged to show more controls on one single screen. Furthermore the buttons to Open, Add, Edit and Delete links are redecorated. All this styling will create a synoptic layout.

Link Types

They also added a couple of new Link Types to a Work Item. The nice thing about the Link Types is you can filter it for a specific control. For example: You only want to allow links to create a hierarchy for parent and child relations. Your WIT control specification could look like this. Watch closely to LinkFilters sections.

<Control Type="LinksControl" Name="Hierarchy" Label="Parent and &amp;Child Links:" LabelPosition="Top">
        <WorkItemLinkFilters FilterType="include">
            <Filter LinkType="System.LinkTypes.Hierarchy"  />
        <ExternalLinkFilters FilterType="excludeAll"/>
            <LinkColumn RefName="System.ID" />
            <LinkColumn RefName="System.WorkItemType" />
            <LinkColumn RefName="System.Title" />
            <LinkColumn RefName="System.AssignedTo" />
            <LinkColumn RefName="System.State" />
            <LinkColumn LinkAttribute="System.Links.Comment" />

Work Item Custom Controls
Besides extensions in the XML definition of a Work Item there are two Custom Controls added to Rosario which can be found in C:Documents and SettingsAll UsersApplication DataMicrosoftTeam FoundationWork Item TrackingCustom Controls9.0. Check this blog for all Custom Control locations.

  • ReproStepsControl.wicc
  • TestStepsControl.wicc

The latter is showed in the screen below.

<?xml version="1.0"?>
<CustomControl xmlns:xsi="" 

With this custom control you can create you're own test steps including parameters which can be data bound. A brief explanation about this steps can be found in the November Rosario CTP - Planning A Testing Effort with Camano from Grant Holiday.

Custom Controls

For more information about Custom Controls check a community by Naren Datha (Unfortunately he left the TFS Team): and Mathias Olausson: One of their coolest controls is the Screenshot control.

Work Item Queries
One of the superb new features of Work Items is you can now query on links. Depending on the type of query it will not only give you an other result, but also another icon in the Team Explorer. In this examples I added a Work Breakdown structure to the CTP12-Agile Team Project. Creating a structure like this is easy. Just select the Query on links checkbox, select Tree as Type of query and add Child as Link Type. Not only you good create Work Breakdown structures using this concept, Backlogs are created as easily as well.

Work Item Queries

It's good to see Microsoft is listening to its customers. More and more people are asking for a better Agile template and they will get it. Other people asked for work breakdown support as you can read in one of my older posts and the will get it. I'm very anxious they will not support these new features in the old Team Explorer for Visual Studio 2005. I still hope they will because a lot of companies are willing to upgrade to a new server environment but to upgrade to a new client upgrade is a complete other story. And yes I know you could install another Team Explorer instance besides it, but that's not a solution. VSTS Dev Team keep up the good work and maybe it's still a good idea to also include the old MSF Agile Process Template because a lot of companies have adopted this structure.



Lately I've been asked to install Team System Web Access on the same machine containing WSS 3.0. Officious I configured their SharePoint using a fully qualified domain name (FQDN). This gives them the ability to open the TFS sites from outside their environment and on Internet as well. Since MS is advising to install Web Access on a separate Web Site it probably will be hard to configure it they way I want it. When I installed Web Access on the WSS site as a virtual directory and added a new URL mapping to the web.config it gave me this error. The web.config can be found in your VSTS Web Access directory in Program Files. e.g. %Program Files%Microsoft Visual Studio 2008 Team System Web AccessWeb

    <urlMappings enabled="true">

<!-- Become-->

    <urlMappings enabled="true">
<add url="~/" mappedUrl="~/Index.aspx" />


The trusted callers error exists because SharePoint runs in a kind of a sandbox. We need to upscale the trust level of Web Access. This can be done by using the following statements. I haven't tested any other kind of trust level but you're free to do so.

    <compilation debug="false" batch="false" />

<!-- Become-->

    <compilation debug="false" batch="false" />
<trust level="Full" originUrl="" />


Who hasn't seen this error before 'Object reference not set to an instance of an object.' After a bit of reverse engineering I discovered it's depending on sessions. Sessions can be supported in SharePoint but is turned off by default. Not only it must be enabled to use sessions, it must be handled as well. All other unnecessary modules will be removed for optimal performance.

    <pages validateRequest="false" enableEventValidation="false" />

<!-- Become-->

    <pages validateRequest="false" enableEventValidation="false" enableSessionState="true" />


        <add name="CompressionModule" type="Microsoft.TeamFoundation.WebAccess.CompressionModule"/>

<!-- Become-->

        <clear />
        <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
        <add name="CompressionModule" type="Microsoft.TeamFoundation.WebAccess.CompressionModule"/>


The last problem is a security issue which can be easily solved by changing these two properties. The nice thing about this change its configuring your WSS site and your VSTA site to let you logon using one single user account. So we have a kind of Single Sign-On where you can open VSTA from your WSS site without a new logon form. With automatic Logon in fully qualified domain name (FQDN) environment all your customers will be really satisfied and doesn't have to logon at all.

    <authentication mode="None"/>
    <identity impersonate="false"/>

<!-- Become-->

    <authentication mode="Windows"/>
    <identity impersonate="true"/>


I hope this article will help you to set up an environment such as described above. Sometimes when you open a Work Item this will give you an error where Microsoft.TeamFoundation.WorkItemTracking.Controls was not found. I had to track it down in %Program Files%Microsoft Visual Studio 9.0Common7IDEPrivateAssemblies and copy it to %Program Files%Microsoft Visual Studio 2008 Team System Web AccessWebbin. Normally the TSWA installation copies that file over from the privateassemblies directory. As you can see in my images I'm not only still using XP, I'm using Internet Explorer 8.0 as well. This tool rocks and performs like hell. Haven't seen such a boost since Opera arrived. I really like the activities and advice you all to use it event though it's still beta.


1 Comment

The latest Project Server to TFS Connector was just released on CodePlex. This release of the PS2007 VSTS Connector is targeted to work with Team Foundation Server 2008 and resolves several bugs that were reported in the first two releases. They've done their best to ensure that this Connector is easy to install and well documented.

Unfortunately Team System 2008 isn't fully ready for Hierarchical Work Items. With the Hierarchical Work Items you can create a Work Breakdown structure. This structure is needed when you want full support for MS Project and Project Server. What can we expect of the future releases of Team System. In this example the new query “Work Breakdown” of Team System Rosario shows how “Tasks” are child items of “Features”.


When  you try to open this in MS Project using the current CTP of Team System Rosario, it will flatten the structure.


Future versions of Team System will have native integration with Project Server, in the meantime this Connector solution is the best way to integrate the two Microsoft products. Hopefully this MS Project integration will work better in the next Rosario CTP so we can really start using work items the way we supposed to do. We still have a 'long' way to go, but as with most products of MS, the third version of a product really rocks.


1 Comment

A couple of weeks ago I posted a post about creating a couple of data generators for DataDude. In mine first data generator I used aggregation extensibility. Microsoft divided each form of extensibility in another section. Since I created one or more instances of the standard data generator classes and use those to do the work its called aggregation extensibility. Another thing I created is the use of multiple generators in one class. The base class implementation constructs outputs that are based on public properties that are marked with the OutputAttribute. The inputs are set by using the InputAttribute. Using properties that are marked with attributes provides a simple mechanism for declaring input and output values that are strongly typed. The code below uses multiple outputs, a numeric and a regular expression data generator to do the work.

    1 using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator;
    2 using Microsoft.VisualStudio.TeamSystem.Data.Generators;
    3 using System;
    4 using System.Globalization;
    6 namespace DutchGenerator
    7 {
    8     public class DutchDataDetails : Generator
    9     {
   10         #region Fields
   11         private string _prefix;
   12         private string _seperator;
   13         private CasingType _casing;
   15         private RegexString _regex;
   16         private Int _numeric;
   17         private Random _rand = new Random();
   19         private string genPostCode;
   20         private string genProvince;
   21         private string genProvinceAbbrev;
   22         private string genPhoneNumber;
   23         private string genMobilePhoneNumber;
   24         #endregion
   26         #region Enumerators
   27         public enum CasingType
   28         {
   29             NormalCase,
   30             LowerCase,
   31             UpperCase,
   32             TitleCase
   33         }
   35         private string[] Provinces = new string[] {
   36               "Drenthe"
   37             , "Flevoland"
   38             , "Friesland"
   39             , "Gelderland"
   40             , "Groningen"
   41             , "Limburg"
   42             , "Noord-Brabant"
   43             , "Noord-Holland"
   44             , "Overijssel"
   45             , "Utrecht"
   46             , "Zeeland"
   47             , "Zuid-Holland"};
   49         private string[] ProvincesAbbrev = new string[]
   50         {
   51               "DR"
   52             , "FL" 
   53             , "FR"
   54             , "GL"
   55             , "GR"
   56             , "LI"
   57             , "NB"
   58             , "NH"
   59             , "OV"
   60             , "UT"
   61             , "ZH"
   62             , "ZL"
   63         };
   64         #endregion
   66         #region Inputs
   67         [Input(Name = "Prefix", Description = "Prefix for (mobile)phonenumbers. (e.g. +31)", DefaultValue = "")]
   68         public string Prefix
   69         {
   70             get
   71             {
   72                 return _prefix;
   73             }
   74             set
   75             {
   76                 _prefix = value;
   77             }
   78         }
   80         [Input(Name = "Seperator", Description = "Seperator for postcodes (e.g. space char) and (mobile)phonenumbers (e.g. parenthes and minus char).", DefaultValue = " ")]
   81         public string Seperator
   82         {
   83             get
   84             {
   85                 return _seperator;
   86             }
   87             set
   88             {
   89                 _seperator = value;
   90             }
   91         }
   93         [Input(Name = "Character casing", Description = "Character casing of generated string.", DefaultValue = CasingType.NormalCase)]
   94         public CasingType CharacterCasing
   95         {
   96             get
   97             {
   98                 return _casing;
   99             }
  100             set
  101             {
  102                 _casing = value;
  103             }
  104         }
  105         #endregion
  107         #region Outputs
  108         [Output(Name = "Province name", Description = "The long form of the province name.")]
  109         public string Province
  110         {
  111             get
  112             {
  113                 return genProvince;
  114             }
  115         }
  117         [Output(Name = "Province abbreviation", Description = "The 2 letter form of the province name.")]
  118         public string ProvinceAbbrev
  119         {
  120             get
  121             {
  122                 return genProvinceAbbrev;
  123             }
  124         }
  126         [Output(Name = "Postcode", Description = "A valid _regex.")]
  127         public string PostCode
  128         {
  129             get
  130             {
  131                 return genPostCode;
  132             }
  133         }
  135         [Output(Name = "Phonenumber", Description = "A valid phonenumber, including area code.")]
  136         public string PhoneNumber
  137         {
  138             get
  139             {
  140                 return genPhoneNumber;
  141             }
  142         }
  144         [Output(Name = "Mobile Phonenumber", Description = "A valid mobile phonenumber.")]
  145         public string MobilePhoneNumber
  146         {
  147             get
  148             {
  149                 return genMobilePhoneNumber;
  150             }
  151         }
  152         #endregion
  154         protected string FormatOutputValue(string originalOutput)
  155         {
  156             string formattedValue = String.Empty;
  158             if (originalOutput != null)
  159             {
  160                 //format character casing
  161                 switch (_casing)
  162                 {
  163                     case CasingType.NormalCase:
  164                         formattedValue = originalOutput;
  165                         break;
  167                     case CasingType.LowerCase:
  168                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToLower(originalOutput);
  169                         break;
  171                     case CasingType.UpperCase:
  172                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToUpper(originalOutput);
  173                         break;
  175                     case CasingType.TitleCase:
  176                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(originalOutput);
  177                         break;
  179                     default:
  180                         break;
  181                 }
  182             }
  184             return formattedValue;
  185         }
  187         protected override void OnInitialize(GeneratorInit initInfo)
  188         {
  189             base.OnInitialize(initInfo);
  191             switch (this.OutputKey)
  192             {
  193                 case "Province":
  195                 case "ProvinceAbbrev":
  196                     _numeric = new Int();
  197                     _numeric.Distribution = new Normal();
  198                     _numeric.Min = 0;
  199                     _numeric.Max = 11;
  200                     _numeric.Initialize(initInfo);
  201                     break;
  203                 case "PostCode":
  204                     _regex = new RegexString();
  205                     _regex.Expression = "[1-9]{1}[0-9]{3}##([a-z]|[A-Z]){2}";
  206                     _regex.MaximumLength = 8;
  207                     _regex.Initialize(initInfo);
  208                     break;
  210                 case "PhoneNumber":
  211                     _regex = new RegexString();
  212                     _regex.Expression = "0[123457]{1}[0-9]{1}##[0-9]{7}";
  213                     _regex.MaximumLength = 12;
  214                     _regex.Initialize(initInfo);
  215                     break;
  217                 case "MobilePhoneNumber":
  218                     _regex = new RegexString();
  219                     _regex.Expression = "06##[0-9]{8}";
  220                     _regex.MaximumLength = 12;
  221                     _regex.Initialize(initInfo);
  222                     break;
  224                 default:
  225                     break;
  226             }
  227         }
  229         protected override void OnGenerateNextValues()
  230         {
  231             string result;
  232             base.OnGenerateNextValues();
  234             switch (this.OutputKey)
  235             {
  236                 case "Province":
  237                     _numeric.GenerateNextValues();
  238                     genProvince = FormatOutputValue(Provinces[_numeric.Result]);
  239                     break;
  241                 case "ProvinceAbbrev":
  242                     _numeric.GenerateNextValues();
  243                     genProvinceAbbrev = FormatOutputValue(ProvincesAbbrev[_numeric.Result]);
  244                     break;
  246                 case "PostCode":
  247                     _regex.GenerateNextValues();
  248                     genPostCode = FormatOutputValue(_regex.Result.Replace("##", _seperator));
  249                     break;
  251                 case "PhoneNumber":
  252                     _regex.GenerateNextValues();
  253                     result = _regex.Result.Replace("##", _seperator);
  255                     if ((_seperator.Length > 0) && (_rand.Next(0, 2) == 0))
  256                     {
  257                         result = result.Replace(_seperator, result.Substring(3 + _seperator.Length, 1));
  258                         result = result.Remove(4, 1);
  259                         result = result.Insert(4, _seperator);
  260                     }
  261                     genPhoneNumber = FormatOutputValue(_prefix.Length > 0 ? _prefix + result.Substring(1) : result);
  262                     break;
  264                 case "MobilePhoneNumber":
  265                     _regex.GenerateNextValues();
  266                     result = _regex.Result.Replace("##", _seperator);
  268                     genMobilePhoneNumber = FormatOutputValue(_prefix.Length > 0 ? _prefix + result.Substring(1) : result);
  269                     break;
  271                 default:
  272                     break;
  273             }
  275         }
  277     }
  278 }

Dutch data generator (Provinces, Postcodes, Phone - and Mobile phone numbers)

To register the class in the Visual Studio environment a XML file has to be created where all objects are registered through

  • XML file naming convention <AssemblyFilename>.Extensions.xml
  • The file extension .Extensions.xml is mandatory
  • The Extensions.xml file has to be placed in the %ProgramFiles%Microsoft Visual Studio 8DBPro directory
  • Must implement the schema defined in %ProgramFiles%Microsoft Visual Studio 8DBPro Microsoft.VisualStudio.TeamSystem.Data.Extensions.xsd
<?xml version="1.0" encoding="us-ascii"?>
<extensions assembly="DutchGenerator, Version=, Culture=neutral, PublicKeyToken=d6ddc2e862439c84" version="1" xmlns="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions" xmlns:xsi="" xsi:schemaLocation="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions
    <extension type="DutchGenerator.DutchDataDetails" enabled="true" />


There are two options where the extension assemblies can be placed

  • %ProgramFiles%Microsoft Visual Studio 8DBProExtensions directory
  • GAC, requires the assembly to be strong name signed

Do use the extension assembly the following steps have to be done

  • Copy .extensions.xml file to DBPro directory
  • Copy assembly to DBProExtensions directory
  • GAC the extension assembly

Since this isn't handy when your developing you Extension, you could create a generic post build event:

copy "$(ProjectDir)$(TargetName).Extensions.xml" "$(ProgramFiles)Microsoft Visual Studio 8DBPro$(TargetName).Extensions.xml" /y 
copy "$(TargetDir)$(TargetFileName)" "$(ProgramFiles)Microsoft Visual Studio 8DBProExtensions$(TargetFileName)" /y 
"$(DevEnvDir)....SDKv2.0bingacutil.exe" /if "$(ProgramFiles)Microsoft Visual Studio 8DBProExtensions$(TargetFileName)"

In the next screendumps the Dutch Data Generator is used to select and modify one of the data generator outputs and create the generated output.

Generator properties

Generated output

I love the data generators option. More and more often companies prohibited you to use you production data in a test environment, probably because of SOX (Sarbanes-Oxley). So you have to create your own test data with the same amount of records. Before DataDude this was hard to do, but with DataDude you can do this easily and even create your own generators. I hope lots of people will create useful generators and maybe we can collect them on codeplex.


On June 11 and 12, I attended a 2-day Visual Studio Team Edition for Database Professionals workshop at Class-A. This event was hosted by Gert Drapers (also aka DataDude), see his blog post announcing the event. Gert discussed all the important features of the tool and some of my fellow attendees complained the workshop was too short for such an enormous set of features and exercises. I have to agree a bit, because we not only discussed all the features of DBPro, we also covered the features of SR1 and the not yet released power tools. The Power Tools are listed on the Future Release page of VSTS. So there was hardly time for any of the exercises, but I don’t give a ****, because I’m more interested to hear and see what DBPro can do. After this workshop and the DevDays, I started to do my own exercises. One of the things, which I will give my full attention, is the ability to extend DBPro. I will focus on all extensions, but data generation in particular.

The power of VSTE DBPro data generation, lays in the fact you can generate data that closely matches your domain values allowed in your environment. The problem is that knowledge of the allowed and disallowed domain values cannot always be derived from the schema, so you have to go in to the designer and configure the generators for your columns. By using the built-in data generators, you can generate random data, generate data from existing data sources, and control many aspects of data generation. If the functionality of the built in generators is insufficient, you can create custom data generators. To create custom data generators, you use the classes in the Microsoft.VisualStudio.TeamSystem.Data.DataGenerator namespace.

Let me start by motivating the data generators that I would like to build. I often find databases which contain Dutch related information, such as postal code, phone number, provinces, e.t.c. Furthermore a lot of columns contain data which could be generated with a DataBound generator, but some of these data could also be retrieved from a number of web services (Cities, Countries, Currencies, ISO-codes e.t.c.). Last but not least I have credit card background, not that I misused other peoples card, but I build a card number controller to prevent this.

The extensibility API provides classes from which developers can inherit. In addition to classes, the API includes attributes that you can apply to your derived classes. By applying these attributes, you reduce the amount of code that is required in custom generators for common cases.

You can use the extensibility API in the following four ways to create custom data generators:




Declarative Extensibilty

  • Inherit from the Generator class.
  • Add custom input and output properties.


Normal Extensibility

  • Inherit from the Generator class.
  • Add custom input and output properties.
  • Override one or more Generator methods (for example, OnGenerateNextValues and OnInitialize).

Medium. This method is recommended in most cases.

Aggregation Extensibility

  • Inherit from the Generator class.
  • Add custom input and output properties.
  • Override one or more Generator methods.
  • In your class, create one or more instances of the standard data generator classes and use those to do the work.


Base Extensibility

  • Create a class that implements the IGenerator interface.
  • Implement all methods that are required by your generator.
  • Create a custom designer for the generator that implements the IDesigner interface.
  • Implement all methods that are required by your designer.


Since I hope to be better than the average, I will use Aggregation Extensibility for my Dutch data generator, in which I will probably use the Regular Expression generator to build my data details. For one of the other two data generators I will be using Base Extensibility and give them their own designer. So keep in touch and follow my posts.



Last night I had a dream about the future of TFS. Wouldn't it be nice if we had one single portal on which all my team projects and their web interfaces resides. That you could easily search across libraries and projects and relate those projects by using site hierarchies. Reports and other functionality will be really exist in those sites and all options are fully integrated. I know it's a dream, but some dreams ....

If you have read Brian Harry's blog about the future of TFS, there is possibility MS is aiming at this goal too. He mentions Office SharePoint Server 2007. And when I think of MOSS in combination with TFS, this picture immediately pops up in my head.

TFS portal on which all team projects and their sub projects resides

All Team sites have all the nice features of WSS v3.

For Example:

  • Customize your sites quickly
  • Better control with master pages
  • Send e-mail to a SharePoint site
  • Get mobile access to a SharePoint list
  • Poll people more effectively with improved surveys
  • Receive updates about lists and libraries with RSS Feeds
  • Track your work with improved calendars
  • Copy documents easily to another location
  • Better management of versions
  • Better document recovery

Team Project running on WSS v3 site

Note: You can already use WSS v3 in a TFS v1 environment. To do so follow this guide.

Another thing which was fully integrated in my dream was the reporting functionality. Reporting Services can be integrated in WSS v3 and Office SharePoint Server 2007 as you can read in a old blog of my. This way all permissions can be set within WSS and will give you a consolidated place to manage security. Nowadays when using Team Foundation Server you have to set rights in TFS, SharePoint and Reporting Services. Wouldn't it be nice to only support TFS and SharePoint.

Reporting fully integrated in SharePoint

Just a couple of days ago MS acquired acquired DevBiz Business Solutions, the makers of the popular TeamPlain Web Access for Team System. To read the complete article about this acquiring check this blog of Brian Harry. Again a great tool for TFS, but also a new web site with its own management and its own look and feel. In my dream release 3 of this product will fulfill my wishes and TeamPlain uses SharePoint as its container.

TeamPlain integrated in SharePoint

Personally I don't think my dream will be realized in Orcas, but hopefully in Rosario. Another interesting part left from the UI of a standard TFS environment is an integration with Outlook. Who doesn't want to sync their Tasks with TFS? So come' on guys acquire Personify Design and you can release TeamLook as a VSTS Power Tool as well. I know there's a free Outlook Addin utility from the SRL Team, works great by the way, but sometimes you just want to have dreams. 😉



As most of you TFS addicts, I also immediately installed the new TFS Power Tools. Like Marcel de Vries wrote in his blog "A must have is the new embedded in Visual Studio Process Template Editor". This editor is almost same as the one I used before, but it's using Visual Studio as a container to modify the process. I compared the code of both products and must say that most of the code isn't changed at all. They renamed some variables and replaced strings containing messages to use resources. The only new part they added is the new Domain Specific Language (DSL) for the workflow of a WorkItem. As you can see it is a great improvement for showing the complete process of WorkItem.

I took the liberty of 'stealing' the picture Marcel used in his post.

The only difference I could find between the two tools was PTE gave me the ability to select which user groups are allowed to do a specified transition. All groups which I added to process template are immediately available to select in each transition. In the Power Tools it will only give you a group of users when you're connected to a Team Foundation Server.

VSTS Customization Toolkit

Team Foundation Server Power Tools 1.2

Another annoying thing is the new tool will create an extra dialog for each transition you select. Every dialog becomes it's own instance within your taskbar.

Again the team delivered a great tool, but I hope they will fix the small bug and change the appearance of each dialog. Maybe the can lock it so you can't click on another transition unless you closed the dialog. I didn't have the time to dig into to code to see were things go wrong. When I have some extra time I'll update this blog. Furthermore I hope TFS in Orcas will use WF for their workflows and show all states and transitions in the Workflow Designer. For a complete outline of the Power Tools check the blog of Buck Hodges.



If you’re going to analyze Visual SourceSafe databases for migration to Team Foundation source control, and to migrate Visual SourceSafe databases to Team Foundation source control, you’ll eventually meet VSSConverter. VSSConverter is a command line utility that uses XML configuration files to transfer SourceSafe projects to TFS. Eyal Post of EPocalipse Software has built a GUI front-end for the VSSConverter tool, which is the command-line utility that helps you migrate source from Visual SourceSafe to Team Foundation Version Control. In this post I will describe which steps need to be taken.

Converting your projects
Before you can use VSSconverter you need to have the correct tools and rights. VSSConverter depends on Visual Studio Team Explorer, which will help you to connect to TFS and Source Control to determine its projects.

Admin password of SourceSafe
If you want to retrieve data from your SourceSafe environment, you need to have full control to do so. In some case it's necessary to hack SourceSafe, because no one remembers the password of the Admin account. Luckily you can easily overwrite the passwords for a SourceSafe environment, which are stored in the um.dat file. This file, which can be found in the root, contains all passwords of each user and are binary stored. Open the um.dat in a hexadecimal editor and try to determine the offset of your Admin account, as the file is ordered alphabetically by login. If you haven't any user name that appears alphabetically before "Admin" it will appear at offset 80. Hack the file and remove the Admin password from offset 80 the bytes are (all numbers are hex) and change the bytes to exactly what's typed below and include all bytes even the one from offset a0.

0:80  55 55 bc 7f 41 64 6d 69 6e 00 00 00 00 00 00 00
0:90  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:a0  00 00 00 00 90 6e 00 00 a8 01 00 00 00 00 00 00

You now have full access to your SourceSafe database.

SQL Server
Furthermore you need to have SQL Server rights and client tools to connect to the database server, else you will receive the error.

Need a connection and correct rights on SQL Server

ERROR: TF60022:  Unable to connect to Microsoft SQL Server.

VSSConverter requires either SQL Express or SQL Server for migration. By default it looks for SQL Express which is installed with VS 2005 in a default configuration. For overriding the default you can specify another SQL Server. 

User Mapping
After selecting my project source and destination the tool will give you the ability to map the users from SourceSafe to TFS. It's nice to see that only the VSS users which involves the project are given. After selecting the correct TFS users my migration still failed.

ERROR: TF60014:  The username WINNT://SERVER/Mike in the user map file C:tempvssToTfsUsermap.xml is invalid.
User mapping

ERROR: TF60087: Failed to initialize user mapper


I don't know why, but in mine case I needed to remove WinNT:// per user as you can see in the code below. You can do this by editing the UserMap.xml.

<?xml version="1.0" encoding="utf-8"?>
<UserMappings xmlns:xsi="" xmlns:xsd="">
<UserMap From="MIKE" To="SERVERMike" />
<UserMap From="ADMIN" To="SERVERTFSSetup" />

Team Foundation Server
The last step which has to be taken is give the user who migrates all projects the ability check in other users' changes security rights on TFS. If you forgot to do so this error will occur.

ERROR: TF14098: Access Denied: User SERVERmike needs Checkin, CheckinOther permission(s) for $/Playground/Source/dummy.txt.

After correcting all steps I was able to convert one of my SourceSafe projects. You could easily migrate several projects, but I think you should only migrate those which are still usable and important. All other projects can be left in SourceSafe and create a backup of it on disk or cd.

The Microsoft Team for TFS delivered a great product to really upgrade your sources to a fully transactional and more secure source control environment. It's not hard to setup a migration, but some steps are not fully documented. One of the nicest things about the migration, it will give you the ability to still see your previous history. Files checked in at the same time, will now show up as complete changeset.





I've just finished my guide about upgrading TFS V1 to WSS 3.0 and Microsoft immediately releases Service Pack 1 for TFS V1. This is good thing and I knew it was planned for half December, but I now have to write a second guide about extending your TFS V1 with SP1, while you already upgraded it to WSS 3.0. In the last blog I quoted Brian Harry who commented in my Blog "The last remaining issue that you may hit is when you try to upgrade to a future version of TFS. You may find yourself trying to hack your way through that too.". He was absolutely right, I had to do some stunts again. Most of the stunts are just faking your WSS 3.0 Team Site is a WSS 2.0 Team Site. The easiest way is to install SP1 before you upgrade to WSS 3.0. If so, my previous post still stands, otherwise read the steps below to continue your upgrade. Before you start upgrading your TFS its important to create a good planning for Backup and Restore. Just read this article about "Planning for Backup and Restore" on MSDN. This upgrade works for single- and dual server installments.


Visual Studio 2005 Service Pack 1 was released last Thursday.  Here are the direct download links.

and the two for TFS

If you want to slipstream those packs check the blog post of Heath Stewart on How to slipstream Visual Studio 2005 Service Pack 1. For Detecting Visual Studio 2005 Service Pack 1 and Uninstall Visual Studio 2005 Service Pack 1 Beta before Installing the Release he also got some interesting articles.

If you want to read about all bug fixes solved in TFS SP1, read the following blogs Bug fixes in TFS SP1 and Update on Bug fixes in TFS SP1 of Brian Harry

Workgroup Edition Error

Before showing you the way the go, I like to mention if you're upgrading your TFS with SP1 (which you should) and you're using the Workgroup Edition, there are some problems if the server already is using 5 Licensed Users. The error which will certainly strike is 28002 Error Unknown when installing the KB919156 (Quiescing GDR) fix.

To prevent this error, you will have to remove one of the users, upgrade your server and add the user back in the list. In this fix and SP1, MS tries to add the installing user to the Licensed Users list, even if the installing user is already a member of the list. Marcel de Vries, who already blogged about this error in TFS SP1 Beta1, asked if this error will be fixed in the final release of the service pack. But is seems to be an issue for the RTM of the Service Pack as well.

How to fake a WSS 2.0 on WSS 3.0 server

I've created 4 sections in which I describe the changes compared to a normal install. Both installers (Feature- and Service Pack) are checking if TFS is configured correctly on WSS. When all steps are done it will finally install the updates for TFS.

To retrieve the STS_Content database, it using the proc_getDatabasesWithServer stored proc of the STS_Config_TFS database which is obsolete in WSS 3.0. Run the the SQL statement below, and this check won't fail anymore.


CREATE PROCEDURE [dbo].[proc_getDatabasesWithServer]
      @DatabaseServiceId uniqueidentifier = null, 
      @VirtualServerId uniqueidentifier = null
) AS
      INNER JOIN Services ON 
            Databases.DatabaseServiceId = Services.ServiceId
      INNER JOIN Servers ON
            Services.ServerId = Servers.ServerId
            Databases.VirtualServerId = @VirtualServerId AND
            Databases.SiteCountLimit >= 0     

      IF @@ROWCOUNT = 0
            RETURN 0

            INNER JOIN Services ON 
                  Databases.DatabaseServiceId = Services.ServiceId
            INNER JOIN Servers ON
                  Services.ServerId = Servers.ServerId
            Databases.VirtualServerId = @VirtualServerId AND
            Databases.SiteCountLimit >= 0  
      RETURN 0

Because the WSS v2 site isn't active anymore you want the SharePoint Administration Tool to return the info about your WSS v3 site. This can be established by putting the SharePoint Administration Tool in the WSS v2 directory.

Open the Windows Explorer to copy the WSS v3 Administration Tool to the WSS v2 directory.

Open C:Program FilesCommon FilesMicrosoft Sharedweb server extensions60BIN
Rename stsadm.exe -> stsadm.exe.old
Open C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12BIN
Copy stsadm.exe to C:Program FilesCommon FilesMicrosoft Sharedweb server extensions60BIN

The next part I'll explain in the following section.

Open the Windows Explorer to create a dummy root folder for the Dummy Web Site.

Open C:Inetpub
Create a dummyroot folder

When installing the Feature- and Service Pack the web server is also requested to deliver some information to the installers. The first checks if the WSS v2 administration site is installed on the server, and if it's configured for port 17012. During my previous guide I reconfigured the WSS v2 admin site to use 9999 and the WSS v3 admin site to use 17012. Luckily the installers don't check if the server is actually running, so you can change it without stopping the WSS v3 admin site. The other check checks if the Default Web Site is running and if it can be extended. This last check isn't possible with our current Default Web Site, because this site is already extended to WSS v3. This is the part where my dummy site comes in.

Add a Dummy Web Site

Click Start, click Control Panel, click Administrative Tools, and then click Internet Information Services (IIS) Manager.
Stop the Default Web Site

Right-click on Web Sites and add a new Web Site using the Wizard.

Description: Dummy Web Site
IP Address: All Unassigned
TCP Port: 80
Path: C:Inetpubdummyroot
Permissions: Read, Run scripts (such as ASP)


Change WSS v2 port to 17012

Click Start, click Control Panel, click Administrative Tools, and then click Internet Information Services (IIS) Manager.
Right-click the SharePoint Central Administration folder and then click Properties.
Change the TCP Port to 17012 without starting the site.

Now having configured your server, you can install SP1 for TFS. Be sure al these screen will popup when installing the updates. You can also check your Add/Remove programs if the update succeeded. The update for the build will always succeed, because this update won't use TFS. 


When everything is installed correctly return to original state of you Web Server. So stop the Dummy Web Site and start the Default Web Site. The last thing you should do, is change the ports, so IIS can't make a mistake.

I showed you again, the it's possible to upgrade to WSS 3.0 and even install your Feature- and Service Packs afterwards. This is a good thing, so all you WSS 3.0 sites for TFS out there, keep on running. At my company we are using WSS 3.0 for TFS (dual-server), so we can eat our own Dogfood. This way I guarantee you I'll deliver a guide for upgrading to 'Orcas' as well.



This is the second article about Ten Must-Have Tools Every TFS User Should Download Now.

Part I discusses:

Part II discusses:

You cannot expect to build a first-class project unless you use the best available tools. Besides well-known tools such as Visual Studio® .NET and Team Foundation Server, there are a multitude of small, lesser-known tools available from the .NET community. In this article, I'm going to introduce you to some of the best free tools available today that target project development. I'll walk you through a quick tutorial of how to use each of them, some of which will save you a minute here and there, while others may completely change the way that you work. Because I am squeezing so many different tools into this single article, I will not be able to cover each of them extensively, but you should learn enough about each to decide which tools are useful for your projects.

Workitem Event Subscription
In TFS there are a lot of things which can't be realized with the Team Explorer. These special methods are hidden for default user and can only be called by using the command-line. One of these things is subscribing to events. Lots of people have trouble creating filter expressions for event subscriptions, and managing subscriptions. We do have bissubscribe.exe tool that helps with creating subscriptions. But creating subscription expressions is hard because of its syntax. Also, that tool doesn't give a way to view existing subscriptions to unsubscribe them. This excellent tool will do this for you.

Note: This tool as name says only add WorkItem events to the TFS Server. It would be nice if you could add Filters to other event types as well.

Is a .Net 3.0 smart client which monitors for user selected TFS events and will display a balloon window in the Windows TaskBar Notification Area. It is built on top of WCF where you can subscribe to any TFS event you feel fit. It's initial focus is around Team Build management but will also include features around Work Item tracking. For extra information about WCF, read this excellent blog series of my colleague.

Note: This tool has some commonalities with the email messages of Outlook. Outlook will also show you a balloon and will even store it in your Inbox, so you can easily find again. Only with this tool you'll get a specific balloon based on the event type. Unfortunately this balloons don't contains any hyperlinks for showing detailed information about the Workitem and its way for subscribing to events is to barbarian. You have to edit the app.config to subscribe to several events. It would be nice if they integrated some features of Workitem Event Subscription tool.

TFS Bug Snapper
Tool that allows to simplify the process of attaching screen captures and bug descriptions to work items in Team Foundation Server.

Note: The tool works like hell, except it creates a Task WorkItem instead of Bug WorkItem. I don't know why Grant build it this way.

TFS Permission Manager
Working with Team Foundation Server we have to perform various repeating task related to user declaration and permission setting.

Note: I know there is also another TFSAdmin tool, but this tool is a lot more stable than the other one. Besides this if you upgrade your TFS to WSS v3 as I described in my Guide, you won't be able to administrator WSS anymore.

While this article has been dedicated to freely available tools, there are also a host of tools that can be purchased for a reasonable price. I encourage you to check out these other options, as in some cases they can add some tremendous functionality to the TFS. This article has been a quick tour of some of the best freely available tools for TFS. Each of these tools may only do a small thing, but together they help to increase your productivity and enable you to create better projects.

Besides this Microsoft could integrate or add some off the tools from the TFS community to TFS. Microsoft could use a trimmed-UI, so only the users containing the right permissions, could see and use these tools. Maybe we see some of these in 'Orcas' or 'Hawaii'.