Change build definition branches with PowerShell

Problem:

I have a large number of build definitions I need to point to a different branch.

Solution:

Use the attached PowerShell script.

Explanation:

Today on a call with a customer I was asked how they could point hundreds of builds to a new branch.  My obvious answer was with PowerShell.  With PowerShell we can use the entire TFS API to script whatever we need.  The attached script defines an update-BuildBranch function that takes the following parameters:

$tfsUrl

This is the full URL to your Team Foundation Server collection. https://tfs.visualstudio.com/DefaultCollection/

$teamProject

This is the name of the Team Project that contains the desired build definition.

$buildDefinitionName

This is the name of the Build Definition to update or clone.

$from

This is the portion of the Source Control Folder value to search for. $/TeamProject/Branch

$to

This is the value to replace the $from value with. $/TeamProject/NewBranch

$update

If present the Build Definition is updated. If not a copy of the Build Definition is made. -update

 

function update-BuildBranch

{

    [CmdletBinding()]

    param(

        [string] $tfsUrl,

        [string] $teamProject,

        [string] $buildDefinitionName,

        [string] $from,

        [string] $to,

        [switch] $update

        )

 

    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")

    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")

 

    $teamProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($tfsUrl)

    $buildServer = $teamProjectCollection.GetService([type]"Microsoft.TeamFoundation.Build.Client.IBuildServer")

    $buildDef = $buildServer.QueryBuildDefinitions($teamProject) | Where-Object { $_.Name -eq $buildDefinitionName }

 

    if($buildDef -eq $null)

    {

        Write-Error "Build Definition was not found"

        return;

    }

 

    if($from.StartsWith("$"))

    {

        $from = "\" + $from;

    }

 

    if($update.IsPresent)

    {

        foreach($mapping in $buildDef.Workspace.Mappings)

        {

            $original = $mapping.ServerItem

            $mapping.ServerItem = $original -replace $from, $to

            Write-Verbose "Updating $original to $($mapping.ServerItem)"

        }

 

        $buildDef.ProcessParameters = $buildDef.ProcessParameters -replace $from, $to;

 

        $buildDef.Save();

    }

    else

    {

        $branch = $to.Substring($to.LastIndexOf("/") + 1);

 

        # Find a name

        $count = 1;

        $newName = "$($buildDef.Name)_$branch"

 

        while(($buildServer.QueryBuildDefinitions($teamProject) | Where-Object { $_.Name -eq $newName }) -ne $null)

        {

            $newName = "$($buildDef.Name)_$branch`_$count"

            $count++;

        }

       

        Write-Verbose "Cloning build to $newName"

 

        $cloneDef = $buildServer.CreateBuildDefinition($teamProject);

 

        $cloneDef.BuildController = $buildDef.BuildController

        $cloneDef.BatchSize = $buildDef.BatchSize;

        $cloneDef.ContinuousIntegrationQuietPeriod = $buildDef.ContinuousIntegrationQuietPeriod;

        $cloneDef.ContinuousIntegrationType = $buildDef.ContinuousIntegrationType;

        $cloneDef.DefaultDropLocation = $buildDef.DefaultDropLocation;

        $cloneDef.Description = $buildDef.Description;

        $cloneDef.Enabled = $buildDef.Enabled;

        $cloneDef.Name = $newName;

        $cloneDef.Process = $buildDef.Process;

        $cloneDef.ProcessParameters = $buildDef.ProcessParameters -replace $from, $to;

        $cloneDef.QueueStatus = $buildDef.QueueStatus;

       

        $cloneDef.TriggerType = $buildDef.TriggerType;

 

        foreach($mapping in $buildDef.Workspace.Mappings)

        {

            $original = $mapping.ServerItem

            $newMapping = $original -replace $from, $to;

            $cloneDef.Workspace.AddMapping($newMapping, $mapping.LocalItem, $mapping.MappingType)

            Write-Verbose "Updating $original to $newMapping"

        }

 

        $cloneDef.Save();

    }

}

 

updateBuildBranch.ps1 (3KB)

Comments (3) -

  • Thank you Donovan!  Exactly what I was looking for.
  • Donovan,

    This script is exactly what I was looking for!

    I saw you at Ignite in Chicago and you really gave me the push I needed to use powershell to my advantage.

    -Thanks,
    Kurtis Orr
    • Hey Kurtis!  Glad this information was helpful.

Add comment

Loading