TFS in PowerShell

· by giulio · Read in about 3 min · (467 Words)

I am re-factoring my PowerShell administration scripts and noticed many useful snippets to share, let’s start.

Where is Team Foundation Server installed?

Scenario: your script runs TFSSecurity.exe; sadly this tool is not in the path and, worse, the path changes from one Team Foundation Server version to another.

The following function returns the Team Foundation Server path, e.g. C:\Program Files\Microsoft Team Foundation Server 12.0.

function Get-TeamFoundationServerInstallPath
    if (Test-Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer") {
        $highestTFSversion = "{0:N1}" -f (
            Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer" |
                Split-Path -Leaf |
                foreach { $_ -as [double] } |
                sort -Descending |
                select -First 1)
        $tfsPath = Get-ItemProperty
                    -Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer\$highestTFSversion"
                    -Name InstallPath
                    -ErrorAction SilentlyContinue
        if ($tfsPath) {

The path is searched in the registry.

Registry section with TFS keys

and determines the most recent version of TFS installed, then the root installation path is found at the InstallPath property. It returns $null if anything goes wrong.

Concatenate the Tools directory and the tool you need and it is done.

$TFSSecurity = Join-Path (Get-TeamFoundationServerInstallPath) -ChildPath 'Tools\TFSSecurity.exe'

Where is Visual Studio installed?

The scenario is similar to the precedent: you want to run some tool like witadmin.exe from a script.

The following function returns the Visual Studio path, more precisely to a path like C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE where most binaries live.

function Get-VisualStudioInstallDir
    if ($env:ProgramW6432) {
        # 64 bit
        $registryBase = "HKLM:\SOFTWARE\Wow6432Node\Microsoft"
    } else {
        # 32 bit
        $registryBase = "HKLM:\SOFTWARE\Microsoft"
    if (Test-Path "$registryBase\VisualStudio") {
        $highestVSversion = "{0:N1}" -f (Get-ChildItem -Path "$registryBase\VisualStudio" | Split-Path -Leaf | foreach { $_ -as [double] } | sort -Descending | select -First 1)    
        $vsPath = Get-ItemProperty -Path "$registryBase\VisualStudio\$highestVSversion" -Name InstallDir -ErrorAction SilentlyContinue
        if ($vsPath) {

As you may see, it is a bit more complex, as you have to account for 32 and 64 bit operating systems. Visual Studio is still a 32-bit application even when installed on a 64 bit operating system. This means that setup information is stored in the 32-bit hive of Windows Registry. Apart from this the code is the same for TFS, only the registry path is different.

Using the result do not change either.

$witadmin = Join-Path (Get-VisualStudioInstallDir) -ChildPath 'witadmin.exe'

Which Team Foundation Server roles are configured?

This snippet is a variation on the first. It searches what has been configured using the Administration Console.

function Get-TeamFoundationServerInstalledComponents
    if (Test-Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer") {
        $highestTFSversion = "{0:N1}" -f (Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer" | Split-Path -Leaf | foreach { $_ -as [double] } | sort -Descending | select -First 1)
      Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\TeamFoundationServer\$highestTFSversion\InstalledComponents" -ErrorAction SilentlyContinue | where {
          (Get-ItemProperty -Path $_.PSPath -Name IsConfigured -ErrorAction SilentlyContinue).IsConfigured -eq 1
      } | foreach {
          Split-Path -Path $_.PSPath -Leaf

The output is a sequence of values, e.g.


other possible values are


You can download the Powershell Module from here.