We have a customer who really, really want to ship source code from Team Foundation Server (TFS) to Perforce. Why you might ask… Well for many companies they can’t just migrate, they either need some sort of safety net, or have an external requirement that they MUST use a particular system as a matter of record.

But they really want to use TFS.


  • 2011-06-27 – I have added two new operating modes to increase the versatility (RuleThemAll | ForEachAction). These new modes do not run any .NET code at all and you have to do everything in PowerShell. I expect that PowerShell user will love RuleThemAll as all you need is one PowerShell per ChangeSet.

We have to have some way of getting each of the check-ins out of TFS in order and writing them to the other system on a regular basis without having to write an Adapter for each new system. This will obviously not be a perfect scenario as it will not be tailored directly for the other system, but it should suffice for 90% of cases that I will encounter.

The Theory

The TFS Integration Platform Adapter I have written is really simple, and focuses on adaptability not perfection. What is the best tool for this… well PowerShell of course Smile, and with the Team Foundation Adapters already written and provided in the box, we only have to worry about the other side.

In the integration platform if you want to do the writing, rather than the reading I recently did for Test Track Pro, then you concentrate on the IMigrationProvider interface which allows you to implement the ProcessChangeGroup method.

For each change group that is found in TFS the Integration Platform calls this method. The Platform is going to keep track of which you have already done and what types of changes need to be done in what order. All we have to do is do something with them and pass back a ConversionResult object that details a ItemConversionHistory object for each of the Actions that were part of the change group.

You can see from the code above that I am calling a PowerShell script at both the beginning and end of the process. You can’t see it here, but a PowerShell is also called for each of the actions. During this process we build up a record of what we have done and pass back the completed ConversionResult to the TFS Integration Platform so it can check all of the items that we have processed off the list.

In order to add some amount of flexibility to the system I am allowing a different PowerShell to be called for each ContentType and ChangeAction combination:

Content Type Action  
Version Controlled Folder Add  
Version Controlled Folder Edit  
Version Controlled Folder Delete  
Version Controlled Folder Rename  
Version Controlled File Add  
Version Controlled File Edit  
Version Controlled File Delete  
Version Controlled File Rename  

Figure: Supported Actions

In the configuration for the Adapter I have added a bunch of keys that translate to each of the entries above that will allow you to configure which scripts you want to use. You can use them all if you want or only use one.

Figure: Custom settings for configuring PowerShell files

As might be eluded to by the list of arguments above I am passing a bunch of them into PowerShell that should be of use to the person configuring the options. One of the really nice things about using PowerShell is that you can pass in a complicated object graph and have it available for the PowerShell user. You can also get objects back out again, but in this case I only need in.

Figure: Calling PowerShell from VB.NET with Parameters

This means that you can access things like the Comment from the original change group in TFS as well as the person that did the check-in.

Figure: PowerShell to check-in all outstanding files with the original comment

The Practice

In order to run this adapter you are going to need somewhere to install and run the TFS Integration Platform. I would suggest the the TFS server itself, but if you have a problem with that then find another server.

The TFS Integration Platform can run with a UI so we will be using that to configure it, but it can also run off the command line. If you are going to want this tool to run in more than “One-Time” mode then you are going to want to install the service. This will run the sync even if no one is logged on.


Figure: Install the Service if you will be syncing

Once you have it installed you will need a configuration file as a template. This file can be pretty loose, or it can be really strict in what you can select. Depending on the Adapters that you install out of the box will depend on the templates that you get. You can have Work Item Tracking only, Version Control only or a combination.

In this case we will be using my magic config file:

I have highlighted the important parts above and we have already described some of the important bits above, but there are only really three important things to configure:

  • Tfs Source folder - (e.g. $/TeamProject1/Folder1)

    The TFS Source Folder defines where in TFS you want to get the data. The Adapter does not currently support branches so it would be best to pick a folder that does not contain any.

  • Local Output Folder – (e.g. c:Enlistment1995Depot)

    This is the folder where the system will write out the files and folders before calling PowerShell. This would usually be the actual Workspace folder for the other system, or could be anywhere.

  • Power Shell File – (e.g. c:Enlistment1995SyncPerforceEditsWithDepot.ps1)

    The PowerShell files are easily configured as described. Remember that for every change “Add”, “Edit” or “Delete” a respective PowerShell can be configured to be called.

    note: You can call a single PowerShell or have it call the individuals, but not manage the file space.

Now that you are able to configure the config file, it is time to setup the run.


Figure: Creating a new Configuration for the TFS Integration Platform

We need to create a new configuration and select the config file template that we built. Don’t worry, we can change the individual settings later.


Figure: Using the Sample PowerShell Configuration



Figure: You can reconfigure the TFS side to point at a valid TFS server and Project.



Figure: Make sure that your folder does not “contain” a branch

For a very strange reason that probably spells from my laziness, you need to set both the left and the right hand side of the Paths to be the same thing. I am sure that this is just a temporary work around, but you know how they are!


Figure: Paths must be the same

You can now “Save to Database” the configuration and click the “Start” button on the left to start the first run on the Adapter.


Figure: The Adapter then starts it run

There is not much more to see, the files are populated by change set in the folder that was selected and the PowerShell scripts that were configured run.


Figure: Some Changesets are bigger than others

Once and a while there are some really big Changesets processed. This one is actually pretty small and only had 1846 change actions.


Although this process can take a while, the fact that you can configure the PowerShell any way you like on the fly makes it a very versatile adapter. Although the down side is that you have to write in PowerShell Smile

If you need a copy of your TFS Version Control data somewhere other than TFS for posterity, or you need a migration from Test Track Pro to TFS, then just ping me and see how we can help.

Request for Services

Configuring a PowerShell Adapter for the TFS Integration Platform was last modified: June 22nd, 2011 by Martin Hinshelwood

-Every company deserves working software that successfully and consistently meets their customers needs on a regular cadence. We can help you get working software with continuous feedback so that your lean-agile teams can deliver continuous value with Visual Studio ALM, Team Foundation Server & Scrum. We have experts on hand to help improve your process and deliver more value at higher quality.