PowerShell TFS 2013 API #1 – Get TfsCollection and TFS Services

Have you ever wanted to use PowerShell to interact with the TFS 2013 API? Well I have been working through a few scenarios and wanted to get them to you so that I can get some feedback.

This will likely be a series of PowerShell posts as I build up my library of PowerShell statements. In order to interact with the TFS API with PowerShell, the first things we need to do is import the types that we are going to use. As there are no real PowerShell comandlets for TFS out of the box we need to import the actual assemblies and then wrap a bunch of functions that we want to use.

Figure: Referencing Assemblies

Above I have a set of Assembly imports that reflect the breadth of the functions that I am adding. I am continuously adding to this list but there are a few parts of interest. The first 3 assemblies loaded are the core TFS API’s that you will need for almost every interaction. They represent things like the Server and Collection as well as TeamProject and other core concepts that traverse any particular component. It is worth noting that everything here is the same as you would do in .NET.

The last three assemblies provide Work Item Tracking, Version Control and Project Management respectively. The Project Management assemblies are in the v4.5 folder instead of v2.0 as they were only recently added. With more new features coming down the line it is likely that more things will end up in the v4.5 folder.

The very first thing that you will always do when working with the TFS is connect to your TFS server. Really that means that you will be connecting to the Collection that you want to work with. There are some things that you may want to do against the server but not many.

Figure: Connecting to the TFS Collection in PowerShell

Here I am doing a couple of things. If you pass a URL to a TFS Collection as a string into the function it will create a TFS Collection object based on that URL by calling the static GetTeamProjectCollection method on the built in factory class. That is the easy way. If you don’t specify the URL the PowerShell script above hooks into the built in API’s to show the same Collection Picker dialog that you get in Visual Studio when you try to connect. This actually has three modes, but here i am only using the “NoProject” mode to select a Collection only.

Figure: Connecting to the TFS Common Structure Service with PowerShell

Now that we have our TFS server object we can start exercising it. However everything in TFS is pretty much done through a collection of servers that you get from that Collection object. Here we are doing a get on the Common Structure Service which is responsible for some of the underlying structures like Team Projects, Area Paths and Iteration Paths.

Figure: Connecting to the TFS Work Item Store with PowerShell

Another component that you will get a lot of use out of is the Work Item Store. This is where all of the magic happens with Work Items. We can use it to access queries, create our own queries as well as create and edit Work Items. If you are just a little crazy you can also edit the work item types…

Figure: Connecting to TFS Version Control with PowerShell

If you are seeking to work with the Source Code then Version Control Server is the service you are looking for. It allows you to work with all of the files in source control and to add more. Simple to work with once you accept that you need a Local Workspace to do anything.

Figure: Connecting to TFS Project Process Configuration with PowerShell

There are many new features in 2012 and 2013 that required new API’s to edit and configure. The Project Process Configuration is one such entity that comes from the new “Microsoft.TeamFoundation.ProjectManagement.dll”. This allows you to configure and work with the Process Configuration for your Team Project. This is the configuration and layout of your Backlogs and Boards. You can just read the settings or you can set them as well.

Figure: Connecting to TFS Team Settings Configuration with PowerShell

While you can use the Process configuration above to change the process template there are also settings that are specific to the Teams that are created with TFS. Not only can you create new teams but there are a plethora of configuration options. Use the Team Settings Configuration services to access and edit these new features. It a little more convoluted an API than I would have liked, but it does have some awesome capabilities.

Conclusion

Have you been playing with the TFS API in PowerShell? The advantage of a scripting language is obvious in the versatility of both edit-ability and runtime execution of commands to figure out what you need to do. I would have loved for TFS to have built in commands, but with access to the API’s there really is no need. You can do whatever you want.

  • Dave Shaw

    This looks like the start of a great series, I always wanted to use PS with TFS, but never got around to it due to the lack of out of the box support! I don’t know why I didn’t roll my own, I know the API’s pretty well thanks to Linqpad. I might have to expose some of the build functions this way – I use PS and TFSBuild.exe for my continuous deployment and full TFS support for the builds would be way better than “if ($lastexitcode -eq 0)” :).

    Do you have all this setup as part of a PS Profile or do you import all the functions each time?

    • I have created a Powershell Module, but I will get to that 🙂

      • Dave Shaw

        Can’t wait! Do you have any plans to host these on CodePlex (or your OSS hostof choice)?

        • I have been thinking about it 🙂 More likely as a Chocolatey package…

          • Dave Shaw

            That would be awesome for easy of installation! It would be nice to contribute to it too, if and when people want new features.

  • Pingback: Dew Drop – October 2, 2013 (#1,636) | Morning Dew()

  • Pingback: PowerShell TFS 2013 API #1 - Get TfsCollection ...()

  • William S. Rodriguez

    Hi, Martin I wonder how can i access the Lab Management with the API? There is any way?

    • What are you trying to access? The TFS Community Build Tools and indeed the built in Lab Management build activates show that you can do pretty much anything…

  • kiquenet kiquenet

    I use TFS 2008, VS 2010, Addin VS, TeamFoundationClient.

    Is it possible:

    use tf merge command programmatically in C# (in my Addin VS code) ?

    do Merge, known if there are conflicts and resolve conflicts using API TeamFoundationClient ?

    thx. Great Blog !

  • Pingback: One Team Project… no automático! | egomesbrandao | blog()

  • Hans-Henrik Møller

    Hi Martin

    I have run into a small problem. I have changed my build to gated checkin.. but now I need to alter my after build script. Here I checkin a couple of dll’s that are produced in the before build script (coming out of Matlab). I need to bypass the gated checkin..

    My code:

    #Create a “workspace” and map a local folder to a TFS location

    $workspaceName = “PowerShell Workspace_{0}” -f [System.Guid]::NewGuid().ToString()

    $workspace = $versionControlServer.CreateWorkspace($workspaceName, $versionControlServer.AuthenticatedUser)

    $workingfolder = New-Object Microsoft.TeamFoundation.VersionControl.Client.WorkingFolder($ServerPath,$LocalPath)

    $result = $workspace.CreateMapping($workingFolder)

    $result = $workspace.Get() #Get the latest version into the workspace

    Write-Host “Copying dll files from matlab lib to SimcalM Library”

    Copy-Item $MatlabDistibPath*.dll $LocalPathCsharpSimcal_gui_v3Library

    $checkInComments = “Files automatically checked in by PowerShell script “”$scriptName”””

    #Submit file as a Pending Change and submit the change

    $result = $workspace.PendAdd($LocalPath,$true)

    $pendingChanges = $workspace.GetPendingChanges()

    Write-Host “Getting pending changes”

    #Only try to check in if there are changes

    If ($pendingChanges -ne $null)

    {

    If ($pendingChanges.Count -gt 0)

    {

    $changeSetId = $workspace.CheckIn($pendingChanges,$checkInComments)

    Write-Host “Successfully checked in “”$($pendingChanges.Count)”” changes using changeset id “”$changeSetId”””

    }

    else

    {

    Write-Host “No changes to check-in”

    }

    }

    else

    {

    Write-Host “No changes to check-in”

    }

    I have searched the net, but not quite turned up examples on how to do this.. not in powershell as my script is based on.. hoping you have the quick answer…

    /Hans-Henrik

    • You should never be checking in the result of a built to source control.

      • Hans-Henrik Møller

        And if I have my very good reasons? The point is, that it is not the result of the actual build, but dll’s that are build using Matlab in a before buyild action…dll’s that the product being build is relying on.. therefore, I want to check them in to the library folder if the build is successful.. but as we have activated the gated checkin.. I need to bypass that…

        • You should have a separate build that compiles using Matlab and creates and published a NuGet package containing your dependant DLL’s. Your Solution should then take a dependency on that NuGet package. This will prevent a Gated Checkin from being produced.

          • Hans-Henrik Møller

            Point taken.. I have a bunch of matlab code in the same project as a C# solution.. it is the matlab that should be build in a seperate build.. but would have no solution file.. how to go about that, as I still want to keep it together with the C# code in one project..

          • I would keep iot separate…:

            MyTeamProject
            |———-MyC#Solution
            |————ProjectA
            |————ProjectB
            |———-MyMatlabSolutuion
            |————ProjectA
            |————ProjectB
            That way you can have a Gated build on both, or only one…

          • Hans-Henrik Møller

            Yes.. I buy that.. but I am not sure how to go about the build definition for the matlab.. as it contains no solution file, and does not use msbuild… but matlab compiler… I have the ps scripts for the build process..

  • Pingback: Visual Studio 2015 TFS and Powershell | A Day In The Life Of A SQL Engineer()

  • once_lost_now_found

    Hi Martin,

    I’m running a powershell script in a build in TFS 2013. When I try to get the VersionControlServer I get a permissions error like this:

    Exception calling “GetService” with “1” argument(s): “TF30063: You are not authorized to access http://xxxx:8080/tfs/defaultcollection.”

    The build is running under the LOCAL SERVICE account. Here is the code that is failing:

    # get the team project collection

    $TeamProjectCollection=[Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($CollectionUrl)

    $VersionControlServer=$TeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

    Do you know why this would be failing? Is there some permission that i need to add to the Local Service account?

    Thanks,

    Brad

    • You will not be able to communicate back to TFS using “Local Service”. You will need at a minimum “Network Service” and you might be better with a domain account.

  • Hans-Henrik Møller

    Hi Martin

    I am moving from XAML build to the new one in 2015. I am hitting an unforssen obstacle, as I need to Get more source code than the actual project I am building.

    I am thinking I could do this in the ps1 script, but can not find a clean axample of getting latest for specific projects.

    I also have a hard time to make the run ps script item accept that the script is located in a subfolder.. I will not find the script… any hints?

    /HH

  • you can find full detailled informations on how to query TFS 2015 & 2013 with powershell in the following article : https://armandlacore.wordpress.com/2016/06/03/tfs-powershell/