One of my colleagues recently came to me and mentioned that a customer needed him to set up a new build controller for them, and then migrate several hundred build definitions to use the new controller, so the original controller could be deprecated. There's no way to do that within the Visual Studio UI or with the tf.exe command, so it's usually approached manually. Ouch!
I came up with a slightly more elegant solution: Use the TFS API! Here's the PowerShell script I whipped up.
[powershell]
<#
.SYNOPSIS
This script allows you to change all of the build definitions in a Team Project to use a different build controller.
.PARAMETER TfsUrl
The URL of the Team Foundation Server -- http://<serverName>:<port>/<virtual directory>/<team project collection>
.PARAMETER TeamProject
The name of the team project
.PARAMETER NewBuildController
The name of the build controller to use
.PARAMETER WhatIf
Displays what actions the script would take, without taking any action
.EXAMPLE
This will run the script in 'WhatIf' mode -- no actions will be taken, but the script will display what actions it would normally take.
UpdateBuildController.ps1 -TfsUrl 'http://myTfsServer/tfs/DefaultCollection' -TeamProject 'MyTeamProject' -NewBuildController 'Some New Build Controller - Default' -WhatIf
.EXAMPLE
This will connect to the TFS Server 'http://myTfsServer/tfs/DefaultCollection' and update all of the build definitions in the team project 'MyTeamProject' to use the 'Some New Build Controller - Default' controller.
UpdateBuildController.ps1 -TfsUrl 'http://myTfsServer/tfs/DefaultCollection' -TeamProject 'MyTeamProject' -NewBuildController 'Some New Build Controller - Default'
#>
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$TfsUrl,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$TeamProject,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$NewBuildController,
[Switch]
$WhatIf
)
$ErrorActionPreference = "STOP"
add-type -Path 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Common.dll'
add-type -Path 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll'
add-type -Path 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Build.Client.dll'
$tfsUri = new-object System.Uri $TfsUrl
$tpc = new-object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection $tfsUri
$buildClient = $tpc.GetService('Microsoft.TeamFoundation.Build.Client.IBuildServer')
$controller = $buildClient.GetBuildController($NewBuildController)
$buildDefinitions = $buildClient.QueryBuildDefinitions($TeamProject)
$buildDefinitions | % {
Write-Host "Checking" $_.Name
Write-Host $_.Name "is using" $_.BuildController.Name
if ($_.BuildController.Uri -ne $controller.Uri) {
Write-Host "Setting" $_.Name "to use $NewBuildController"
if (!$WhatIf) {
$_.BuildController = $controller
$_.Save()
}
}
else {
Write-Host "Build controller is already set. Taking no action."
}
}
[/powershell]
Running it is easy. Either load it up in the PowerShell ISE and run it, then fill in the parameters as specified, or run it from the command line!