TfsSecurity wrapper

TfsSecurity is an ugly but effective tool. I said ugly because the scope parameter is hard to get: you need to ask the database or go through the API.

This latter is a palatable option in PowerShell, so here is a sample script to create a Group in an existing Team Project.

[CmdletBinding()]
param (
    [Parameter(Mandatory=$true, Position=0)]
    [uri]
    $collection,
    [Parameter(Mandatory=$true, Position=1)]
    [string]
    $project,
    [Parameter(Mandatory=$true, Position=2)]
    [string]
    $groupName,
    [Parameter(Mandatory=$false, Position=3)]
    [string]
    $groupDescription = ""
)
 
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
 
$TFSSecurity = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 12.0\Common7\IDE\TFSSecurity.exe"

# load the required DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")

function Get-TFS
{
    param(
    [string] $serverName = $(throw 'serverName is required')
    )

    $propertiesToAdd = (
        ('VCS', 'Microsoft.TeamFoundation.VersionControl.Client', 'Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer'),
        ('WIT', 'Microsoft.TeamFoundation.WorkItemTracking.Client', 'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore'),
        ('CSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.ICommonStructureService'),
        ('GSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.IGroupSecurityService')
    )

    [psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverName)
    foreach ($entry in $propertiesToAdd) {
        $scriptBlock = '
            [System.Reflection.Assembly]::LoadWithPartialName("{0}") > $null
            $this.GetService([{1}])
        ' -f $entry[1],$entry[2]
        $tfs | add-member scriptproperty $entry[0] $ExecutionContext.InvokeCommand.NewScriptBlock($scriptBlock)
    }
    return $tfs
}

#set the TFS server url
[psobject] $tfs = get-tfs -serverName $collection

$projectUri = ($tfs.CSS.ListAllProjects() | where { $_.Name -eq $project }).Uri

& $TFSSecurity /gc $projectUri $groupName $groupDescription /collection:$collection

Here line 52 is the important one: it search and gets the Team Project URI, which is what the TFSSecurity tool wants. The rest of the code is well known and do not deserve comments.

TFS Version

This script works with TFS 2013. You need to change the version numbers to make it work with other TFS versions.

To use it, copy the code in a file, e.g. New-TeamProjectGroup.ps1 and in a Powershell prompt run something similar to this

New-TeamProjectGroup.ps1  -collection "http://localhost:8080/tfs/DefaultCollection" -project MyProject -groupName "My secure TFS group"