PowerShell and TFS: The Basics and Beyond

Doctor Scripto

Summary: Learn about Windows PowerShell and Team Foundation Server.

Microsoft Scripting Guy, Ed Wilson, is here. Today I am happy to introduce a new guest blogger, Susan Ferrell. Susan has spent most of her professional life working with computers, from basement tech startups to high-end datacenters. She’s a senior technical writer at Microsoft.

Hi all! Susan here.

Unlike most of you reading this, administering Team Foundation Server (TFS) is my primary focus, not Windows PowerShell. In fact, I was pretty much a Windows PowerShell novice until a month ago. However, less than a half hour into my first Windows PowerShell scripting session, I found myself excited by the possibilities for TFS and Windows PowerShell together.

Things that are difficult or downright impossible to do with the built-in tools in TFS are very possible by using Windows PowerShell. Or so I believed. And luckily enough for me, Jason Stangroome not only confirmed my suspicions, he volunteered to help me put this post together. He's an old pro with both Windows PowerShell and TFS. So whether you're relatively new to Windows PowerShell (like me), relatively new to TFS, or an old hand at both, there should be at least something of interest to you here. In fact, I'm labelling the sections, so you can skip to what's interesting to you.

The absolute basics

Where does a newbie to Windows PowerShell start—particularly in regards to TFS? There are a few obvious places. I'm hardly the first person to trip across the natural peanut-butter-and-chocolate nature of TFS and Windows PowerShell together. In fact, the TFS Power Tools contain a set of cmdlets for version control and a few other functions.

There is one issue when downloading them, however. The "typical" installation of the Power Tools leaves out the Windows PowerShell cmdlets! So make sure you choose "custom" and select those Windows PowerShell cmdlets manually.

After they're installed, you also might need to manually add them to Windows PowerShell before you can start using them. If you try Get-Help for one of the cmdlets and see nothing but an error message, you know you'll need to do so (and not simply use Update-Help, as the error message implies).

Fortunately, that's simple. Using the following command will fix the issue:

add-pssnapin Microsoft.TeamFoundation.PowerShell

See the before and after:

Image of command output

A better way to review what's in the Power Tools and to get the full list of cmdlets installed by the TFS Power Tools is to use:

Get-Command -module Microsoft.TeamFoundation.PowerShell

This method doesn't depend on the developers including "TFS" in all the cmdlet names. But as it happens, they did follow the Cmdlet Development Guidelines, so both commands return the same results.

Something else I realized when working with the TFS PowerShell cmdlets: for administrative tasks, like those I'm most interested in, you'll want to launch Windows PowerShell as an administrator. And as long-time Windows PowerShell users already know, if you want to enable the execution of remote scripts, make sure that you set your script execution policy to RemoteSigned. For more information, see How Can I Write and Run a Windows PowerShell Script?.

Of all the cmdlets provided with the TFS Power Tools, one of my personal favorites is Get-TfsServer, which lets me get the instance ID of my server, among other useful things.  My least favorite thing about the cmdlets in the Power Tools? There is little to no useful information for TFS cmdlets in Get-Help. Awkward! (There's a community bug about this if you want to add your comments or vote on it.)

Jason has a different favorite: Get-TFSItemHistory. His following example not only demonstrates the power of the cmdlets, but also some of their limitations:

Get-TfsItemHistory -HistoryItem . -Recurse -Stopafter 5 |

    ForEach-Object { Get-TfsChangeset -ChangesetNumber $_.ChangesetId } |

    Select-Object -ExpandProperty Changes |

    Select-Object -ExpandProperty Item

This snippet gets the last five changesets in or under the current directory, and then it gets the list of files that were changed in those changesets. Sadly, this example also highlights one of the shortcomings of the Power Tools cmdlets: Get-TfsItemHistory cannot be directly piped to Get-TfsChangeset because the former outputs objects with ChangesetId properties, and the latter expects a ChangesetNumber parameter.

One of the nice things is that raw TFS API objects are being returned, and the snap-ins define custom Windows PowerShell formatting rules for these objects. In the previous example, the objects are instances of VersionControl.Client.Item, but the formatting approximates that seen with Get-ChildItem.

So the cmdlets included in the TFS Power Tools are a good place to start if you're just getting started with TFS and Windows PowerShell, but they're somewhat limited in scope. Most of them are simply piping results of the tf.exe commands that are already available in TFS. You'll probably find yourself wanting to do more than just work with these.

Beyond the basics

Fortunately, the APIs for TFS client, SQL Server, and SharePoint are all accessible in Windows PowerShell. This is where the fun begins, and where you really start getting into the scripting. This is also where I, as a newbie to Windows PowerShell, start running into my limitations. Fortunately, there are a lot of great resources out there, from people posting their first TFS-related Windows PowerShell scripts to projects available on CodePlex. (I've started a Curah to share useful links. If you have additional suggestions, please add them!)

For my first project, I decided I wanted to write a simple script to tell me if my account is an authenticated account in TFS (I work with a lot of different TFS boxes in test environments). To do this, I had to learn how to add the TFS public assemblies to my Windows PowerShell scripts. Check out Add-Type –AssemblyName! It made my day when I realized I could simply do this to get the full power of the TFS 2012 client assemblies at my Windows PowerShell fingertips:

Add-Type –AssemblyName "Microsoft.TeamFoundation.Client, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

By adding the public TFS assemblies, I can call the APIs from Windows PowerShell simply by referencing them. For example, here’s the simple script I wrote as a training exercise:

And hurrah, it works! I just input the URI (for example, http://fabrikamfiber:8080/tfs), and the script tells me if the account I’m logged in as authenticates against that particular server.

You’ll notice that instead of only using Add-Type –AssemblyName, I defined a function. This is a handy shortcut, particularly if you want to load more than one assembly, as I did. Because this is a function, I’m will likely want to use over and over again, so I’m going to add it to my profile.

Jason came up with an even more elegant answer to add assemblies, which is a lot easier to read and is also easier to add multiples to, if they are the same version and use the same key:

'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Client', 'Microsoft.TeamFoundation.Common' |
    ForEach-Object {
        Add-Type -AssemblyName "$_, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

Next, I thought about using Windows PowerShell to create a team project. I ought to be able to create a Windows PowerShell cmdlet that lets me specify the name of the server and collection, the name for the project, the template to use, and the source control option, and then go. Right?

Yes, I know, there's a power tool that does this already: tfpt createteamproject. It's not Windows PowerShell, though, and it requires installing the power tools and having Visual Studio or Team Explorer on the box. And as it happens, I couldn’t figure out a better way to do this in Windows PowerShell. Jason did, though. He’s created a Windows PowerShell script that wraps the tfpt createteamproject command, and he made it publicly available: New-TFSTeamProject.ps1.

I then wanted to create a cmdlet to help me know what users belong to what teams in TFS. Getting information about what users belong to which projects in a collection is a relatively straightforward task (you can pipe the results of TFSSecurity commands into much nicer formats by using Windows PowerShell). But there’s no quick way to show what teams exist in a collection, or the user membership of each of those teams. There's the Team Members utility in the TFS 2012 Power Tools, but even that isn't ideal. Fortunately, I know that the TeamFoundationTeam Class is part of Microsoft.TeamFoundation.Client. So can I leverage that by using Windows PowerShell?

Probably. Here's where I've run into my limitations as a newbie Windows PowerShell user. I had some ideas about how to do this, but I'm still trying to figure it out and get it to work. But I was sure it was possible, and here's where Jason comes to the rescue once again (and provides the real value for those of you well past my basic level).

Not only has he already thought about this, he did in PSTFSTeams—at least for those of you using TFS 2012. PSTFSTeams not only lets you see exactly the information that I was trying to figure out how to extract, but it lets you add members to teams and create new teams, too.

So what next? There are all kinds of administrative tweaks that seem suited to Windows PowerShell, from managing build workflows to mass-managing work items. I hardly know where to start. What are your favorite TFS-related Windows PowerShell tips and tricks? And what would you like to see next?

I can't wait to find out.


Thank you, Susan and Jason, for a really powerful and interesting post.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Eshwar Babu 0

    I have a requirement to get the latest change date to check the Active project in TFS. Can you help me with any script that can achieve that.


Feedback usabilla icon