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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | |
.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