Backing up TFS Build and Release Definitions


We’ve chosen to use TFS 2015update3 to release and build our code.  As such I’ve found that I have a great many build and releases that are configured in TFS that I often make changes to.  So I’d like to keep a running set of configurations so that I can restore from a previous copy.  This post is about how I did this backup of build and release definitions with Powershell.

To begin with I need to figure out how I call TFS with it’s api.  Since all of these calls are made via rest we can use PowerShell’s cmdlet Invoke-RestMethod.  So the first thing I need to do is get all my projects so I can loop through them.

function Get-TFSProjects
{
 Param($tfsUrl,$apiversion = '3.0-preview')
 Invoke-RestMethod -method get -UseDefaultCredentials -uri "$tfsurl/_apis/projects?api-version=$apiversion"
}  

So to call this all I need to do is call my function:

 get-TFSProjects -tfsurl "http://mytfsinstance.com:8080/tfs/defaultcollection"  

Which then returns me an object with the projects:

count value 
----- ----- 
 18 {@{id=[guid]; name=Marketing; url=http://mytfsinstance.com:8080/tfs/defaultcollection/_apis/projects/[guid]; state=wellFormed; revision=3887163}, @{id=83ed4f89- 

This indicates a guid that is specific to my instance of tfs.[guid].

Now that I have the projects for my collection/instance of tfs. I can now loop through them and get each build definition, all my function expects is my $tfsprojects that  I gathered from the first function:


function Backup-TFSbuildDefinitions
{
 param([object]$tfsprojs,$tfsurl = 'mytfsinstance.com', $tfscollection = 'Defaultcollection', $apiversion = '3.0-preview',[string]$Path = 'c:\temp\tfsbuilds')
 #"$Uri/$DefaultCollection/$TeamProject/_apis/build/definitions?api-version=2.0&name=$buildName"
 $tfsInstance = "http://$($tfsurl):8080/tfs/$tfsCollection"

foreach($tfsproj in $tfsprojs.value)
 { 
 $tfsProjName = $tfsproj.name
 $tfsdev = "$tfsInstance/$tfsProjName"
 $projectIds = Invoke-RestMethod -Method Get -UseDefaultCredentials -uri "$tfsdev/_apis/build/definitions?api-version=$apiversion" -ContentType application/json 
 foreach($projectid in $projectIds)
 {
 $relnumber = $projectid.value.id 
 foreach($rel in $relnumber)
 {
 $relDef = invoke-restmethod -method get -UseDefaultCredentials -uri "$tfsdev/_apis/build/definitions/$($rel)?api-version=$apiversion" -ContentType application/json
 $exportPath = "$path/$tfsProjName"
 if(-not (test-path $exportPath))
 {
 mkdir $exportPath
 }
 $jsonDoc = $reldef | convertto-json -Depth 100
 $jsonDoc | out-file -FilePath "$exportPath\$($reldef.name).json"
 }

 }
 }

}

Now all I need to do is look at the api reference and use the appropriate call to get the release configuration.


function Backup-TFSReleaseDefinitions
{
 param([object]$tfsprojs,$tfsurl = 'mytfsinstance.com', $tfscollection = 'Defaultcollection', $apiversion = '3.0-preview',[string]$Path = 'c:\temp\tfsprojects')
 $tfsInstance = "http://$($tfsurl):8080/tfs/$tfsCollection"

foreach($tfsproj in $tfsprojs.value)
 { 
 $tfsProjName = $tfsproj.name
 $tfsdev = "$tfsInstance/$tfsProjName"
 $projectIds = Invoke-RestMethod -Method Get -UseDefaultCredentials -uri "$tfsdev/_apis/release/definitions?api-version=$apiversion" -ContentType application/json 
 foreach($projectid in $projectIds)
 {
 $relnumber = $projectid.value.id 
 foreach($rel in $relnumber)
 {
 $relDef = invoke-restmethod -method get -UseDefaultCredentials -uri "$tfsdev/_apis/release/definitions/$($rel)?api-version=$apiversion" -ContentType application/json
 $exportPath = "$path/$tfsProjName"
 if(-not (test-path $exportPath))
 {
 mkdir $exportPath
 }
 $jsonDoc = $reldef | convertto-json -Depth 100
 $jsonDoc | out-file -FilePath "$exportPath\$($reldef.name).json"
 }

 }
 }

}

Now if I stitch it all together I can call my tfs instance and save the configurations all to my local disk structure.  From where the script is called.

Here is the full script on my gist:


function Backup-TFSReleaseDefinitions
{
param([object]$tfsprojs,$tfsurl = 'mytfsinstance.com', $tfscollection = 'Defaultcollection', $apiversion = '3.0-preview',[string]$Path = 'c:\temp\tfsprojects')
$tfsInstance = "http://$($tfsurl):8080/tfs/$tfsCollection"
foreach($tfsproj in $tfsprojs.value)
{
$tfsProjName = $tfsproj.name
$tfsdev = "$tfsInstance/$tfsProjName"
$projectIds = Invoke-RestMethod -Method Get -UseDefaultCredentials -uri "$tfsdev/_apis/release/definitions?api-version=$apiversion" -ContentType application/json
foreach($projectid in $projectIds)
{
$relnumber = $projectid.value.id
foreach($rel in $relnumber)
{
$relDef = invoke-restmethod -method get -UseDefaultCredentials -uri "$tfsdev/_apis/release/definitions/$($rel)?api-version=$apiversion" -ContentType application/json
$exportPath = "$path/$tfsProjName"
if(-not (test-path $exportPath))
{
mkdir $exportPath
}
$jsonDoc = $reldef | convertto-json -Depth 100
$jsonDoc | out-file -FilePath "$exportPath\$($reldef.name).json"
}
}
}
}
<#
.Synopsis
Gets all the TFS projects for a given instance
.EXAMPLE
$tfsProjects = get-TFSProjects -tfsurl 'http://yourinstance.com:8080/tfs/Defaultcollection&#39;
.OUTPUTS
Returns an object of projects found in tfs.
count value
—– —–
19 {@{id=f7039238-b489-45d1-b9d1-c4c9222497c3; name=Marketing; url=http://yourinstance.com:8080/tfs/DefaultCollection/_apis/projects/[guid]; state=wellFormed; revisi…
#>
function Get-TFSProjects
{
Param($tfsUrl,$apiversion = '3.0-preview')
Invoke-RestMethod -method get -UseDefaultCredentials -uri "$tfsurl/_apis/projects?api-version=$apiversion"
}
function Backup-TFSbuildDefinitions
{
param([object]$tfsprojs,$tfsurl = 'mytfsinstance.com', $tfscollection = 'Defaultcollection', $apiversion = '3.0-preview',[string]$Path = 'c:\temp\tfsbuilds')
#"$Uri/$DefaultCollection/$TeamProject/_apis/build/definitions?api-version=2.0&name=$buildName"
$tfsInstance = "http://$($tfsurl):8080/tfs/$tfsCollection"
foreach($tfsproj in $tfsprojs.value)
{
$tfsProjName = $tfsproj.name
$tfsdev = "$tfsInstance/$tfsProjName"
$projectIds = Invoke-RestMethod -Method Get -UseDefaultCredentials -uri "$tfsdev/_apis/build/definitions?api-version=$apiversion" -ContentType application/json
foreach($projectid in $projectIds)
{
$relnumber = $projectid.value.id
foreach($rel in $relnumber)
{
$relDef = invoke-restmethod -method get -UseDefaultCredentials -uri "$tfsdev/_apis/build/definitions/$($rel)?api-version=$apiversion" -ContentType application/json
$exportPath = "$path/$tfsProjName"
if(-not (test-path $exportPath))
{
mkdir $exportPath
}
$jsonDoc = $reldef | convertto-json -Depth 100
$jsonDoc | out-file -FilePath "$exportPath\$($reldef.name).json"
}
}
}
}

I hope this helps someone

 

Until then

Keep scripting

 

thom

Leave a comment