TFS PowerShell cmdlets

With Git or Mercurial (or just about any other source control product) you take command line functionality for granted. However with TFS, Microsoft has made getting the PowerShell cmdlets convoluted. Although you can download the TFS 201x Power Tools which contain the PowerShell cmdlets, you need to have Visual Studio installed. If you just want to download the latest files of a project as part of task this is overkill and you probably don’t want Visual Studio installed on all your servers. However there is a way to get the cmdlets on to other servers with a bit of hacking.

First you need the assemblies. I would take them from the GAC on the TFS server. This ensures you have the correct DLL versions. You can copy all the DLLs you need with the following PowerShell command – replace C:\Temp\TFS with the path you want to save the DLLs to.

gci "$env:windir\assembly\GAC_MSIL\Microsoft.TeamFoundation.*" -recurse -include "*.dll" | % { cp $_.fullname "C:\Temp\TFS\$($_.name)" }

Copy these to the destination server. You can no longer copy DLLs back into the GAC. Instead you need to install them. You could do this with GACUtil.exe but this only comes bundled in with .Net SDK (or a Windows SDK) and we don’t want to install a massive SDK on all our servers. Thanks to this TechNet article, you don’t have to. Just run the following PowerShell command in an elevated shell (run as administrator). Again replace C:\Temp\TFS with the path you saved the DLLs to.

[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
gci C:\Temp\tfs\*.dll | % { $publish.GacInstall($_.fullname) }

At this point you can write PowerShell scripts to call TFS, if you are prepared to reference the assembly directly with the exception of DataStoreLoader (Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader) which comes in both 32bit and 64bit versions. I’ve yet to find a suitable way of getting these across.

We obviously want to use the cmdlets. On the reference machine where you installed Visual Studio and TFS Power Tools, go the C:\Program Files (x86)\Microsoft Team Foundation Server 201x Power Tools\ directory. You need to copy the Microsoft.TeamFoundation.PowerTools* files and the PowerShell folder to the target server. I’ll assume you copy them to C:\TFSPowerShell\ for the rest of the article.

So that PowerShell knows about the snapin, you need to create a registry entry. The easiest way is to copy the following to notepad (other text editors are available) and save it with a .reg extension (the save as type will need to be set to All files (*.*) if you are using notepad otherwise it will add a .txt extension) then run it. Change C:\\TFSPowerShell to the location you saved the files to (notice the double backslash – it needs to be escaped) and the version with the relevant TFS version number (see below).

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]
"PowerShellVersion"="2.0"
"Vendor"="Microsoft Corporation"
"Description"="This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"VendorIndirect"="Microsoft.TeamFoundation.PowerShell,Microsoft"
"DescriptionIndirect"="Microsoft.TeamFoundation.PowerShell,This is a PowerShell snap-in that includes the Team Foundation Server cmdlets."
"Version"="11.0.0.0"
"ApplicationBase"="C:\\TFSPowerShell"
"AssemblyName"="Microsoft.TeamFoundation.PowerTools.PowerShell, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
"ModuleName"="C:\\TFSPowerShell\\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"
"CustomPSSnapInType"="Microsoft.TeamFoundation.PowerTools.PowerShell.TFPSSnapIn"

The following table gives you the TFS year to internal version conversion for use in the above file. The packed number can be used in the full reference link below if you want to link to the version number directly.

TFS year version packed
2010 10.0.0.0 100
2012 11.0.0.0 110
2013 12.0.0.0 120
2015 14.0.0.0 n/a

 

And that’s it. You can now add the snapin with Add-PSSnapin Microsoft.TeamFoundation.PowerShell and the PowerShell cmdlets will be there ready to use. If you have a 64-bit version of Windows and you also want to use this in the 32bit version of Powershell you will create a second link in the registry. The file is the same as above just with the location changed to

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.TeamFoundation.PowerShell]

Time for a quick demo. Lets download all the latest files for a specific tfspath to the folder C:\TFSfiles with the following. Just change the $tfspath variable to your path in TFS and the URL to your TFS server.

Add-PSSnapin Microsoft.TeamFoundation.PowerShell
$tfspath = "$/collection/project/folder"
$server = Get-TfsServer -Name "http://tfsserver/tfs/collection"
Get-TfsChildItem $tfspath -Server $server -Recurse | ?{$_.ItemType -ne "Folder"}  | %{$_.DownloadFile(($_.ServerItem).Replace($tfspath,"C:/TFSfiles") ) }

Now you can have all your scripts source controlled and updated automatically on the servers before they are run. Documentation is sketchy for the commands but there is a full reference to the objects being used in the background. Don’t forget you can run PowerShell scripts from your Python code.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s