PowerShell and Team Foundation Server (TFS)- processing Changesets by Path

In the previous post we talked about the TFS object model and two ways to use it to get info about our changes. In this post we’re going to concentrate on getting changes by path. In other words, we want to know what changes happened in a folder. We will use our local path (or the TFS server path, doesn’t matter) to get to a changeset collection. We will use that to get to the WorkItem and Change collections. Here is how these objects are inter-related

ChangeSet To Work Item to Change Class Diagram

There are two ways to get a changeset collection, both based on the VersionControlServer.QueryHistory Method. We can invoke it directly or use a powershell cmdlet wrapper Get-TfsItemHistory.

A bit of explanation about Get-TfsItemHistory main parameters:

  • [-HistoryItem] – can be an itemspec class object. I’ve used it as such may be once or twice. Typically here I just specify the starting path/file type. For example ./*.sql
  • [-Recurse] – very important! Without it, you will only get changes for the directory specified. BTW, doesn’t have to be written out. -r does the same
  • [-Server ] – if you’re running this cmdlet from a directory not mapped to TFS, you can still access your collection with this parameter. it will take a Microsoft.TeamFoundation.Client.TfsTeamProjectCollection object. As you may have noticed, help documentation is outdated as it refers to the (Microsoft.TeamFoundation.Client.TeamFoundationServer) object, which is marked as obsolete and has been replaced by the TfsTeamProjectCollection. Practical implication of all this is that to get the correct object type you will need to use the get-tfsserver cmdlet, not get-tfs. More on that a bit later.
  • [-Slotmode] – this is what MS documentation has to say about it “A flag that describes how history entries are searched. If ‘true’, the returned history entries may reflect multiple different items that have occupied the requested path in the repository. If ‘false’, the returned history entries will reflect the single item currently occupying the requested path.” I usually set it to true.
  • [-All] or more commonly known as [-IncludeItems] – very important parameter as without it you will just get the changeset metadata an no links to change or workitem objects.

This cmdlet is very easy to use:

Get-TfsItemHistory ./*.sql -r -IncludeItems

and if you’re working with TFS interactively you will appreciate not having to type few more characters to invoke the original method. But if you need to save results to a variable for post processing, it’s better to go straight to .NET. I tend to use Get-TfsItemHistory interactively and VersionControlServer.QueryHistory in scripts. Depending on your setup you may get a variety of error messages. Most related to not having Power Tools installed but also some others as described on stackoverflow. Otherwise, it should be pretty easy:

#enter a path to your tfs server

# get an instance of TfsTeamProjectCollection
$tfs=get-tfsserver $tfsServer

# get an instance of VersionControlServer
$vCS = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

# specify a local path. Use wildcards as needed

# get the changesets
$vscHistory=$vcs.QueryHistory($path,[Microsoft.TeamFoundation.VersionControl.Client.VersionSpec]::Latest,0,'Full', $null, $null,$null, [int32]::MaxValue, $true ,$true, $false)

it may be a few keystrokes longer than Get-TfsItemHistory, but it works flowlessly, and now your $vscHistory variable contains both Work Item and Change objects. Which is something that I didn’t manage to accomplish with Get-TfsItemHistory. Notice that the parameters for QueryHistory method are the same as for Get-TfsItemHistory. They are described in detail in the relevant msdn library article.

An important note about get-tfsserver and get-tfs cmdlets. First returns TfsTeamProjectCollection, the second – TeamFoundationServer. TeamFoundationServer has been marked as obsolete so you shouldn’t really use it any more. It did make it into the 2012 version of the TFS API, so it can’t be going away that fast, still TfsTeamProjectCollection is more lightweight and forces us to explicitly define which service we want to use. TeamFoundationServer contains:

  • VCS : Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer
  • WIT : Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore
  • CSS : Microsoft.TeamFoundation.Proxy.CommonStructureService
  • GSS : Microsoft.TeamFoundation.Proxy.GroupSecurityService

Whereas with TfsTeamProjectCollection you need to use the GetService method to get to any of above. In the next post you will see an example of GetService method usage. I’ll be happy to hear from you if you have a preference either way.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you #CuriousAboutData? This is a members’ only discussion forum for any CTO, Developer, DBA, Data Engineer/Scientist — or anyone who just wants to know more about using and managing data. Members enjoy open debate, ask/ answer questions, offer opinions, expertise, and support. If your curiosity has no limits, this group is for you!