Shelveset Cleanup

When you have a TFS collection that has been running for a long time, as I do, you end with a lot of shelvesets.
The drawbacks of this is of course, (minor) storage, but it also affects upgrade time.
But instead of manually delete all the old obsoleted stuff manually, Powershell rescues us.

Note!! please be aware that removing shelvesets affects the revisions of your data. e.g. workitems might have links to shelvesets, so use it at your own risk.

First we need to extract all shelvesets from the collection. Unfortunately the API doesn’t allow to filter on dates, so we need to extract all, and then do the filtering clientside.
We get the shelvesets in batches of 1000

do {
    $result = (Invoke-RestMethod -Uri ($TFSServerURL + '/_apis/tfvc/shelvesets?$top=1000&$skip=' + $skip +'&api-version=1.0') -Method GET -UseDefaultCredentials).value | select name, createddate, @{N='Owner';E={$_.owner.uniquename}}
    $skip+=1000
    }
while ($result.count -eq 1000)

Then we can add a filter looking for shelvesets older than $RetentionTime days

$OldShelvesets += $result | where {[DateTime]$_.createddate -le [DateTime]::Now.AddDays(-$RetentionTime)}

When we have this, we can parse those values to the TF command, to actually remove them. (requires Visual Studio)

 & $TFcmd vc shelve /collection:$TFSServerURL /delete "`"$($shelveset.name);$($ShelveSet.Owner)`""

The full script:

$TFSServerURL = "HTTP://[TFSCollectionURL]"
$TFcmd = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe"
$LogFile = "d:\TFSShelveset.txt"
$DeleteShelvesets = $True #Delete shelvesets or only generate log
$RetentionTime = 720 #Remove shelveset older than x days

#Remove Logfile
if (Test-Path $LogFile)
{
   Remove-Item $LogFile
}

#Get all shelvesets
$skip=0
[System.Object[]] $OldShelvesets= $null

do {
    write-host "Getting shelveset starting at" $skip
    $result = (Invoke-RestMethod -Uri ($TFSServerURL + '/_apis/tfvc/shelvesets?$top=1000&$skip=' + $skip +'&api-version=1.0') -Method GET -UseDefaultCredentials).value | select name, createddate, @{N='Owner';E={$_.owner.uniquename}}
    $skip+=1000
    #Filter Shelvesets
    $OldShelvesets += $result | where {[DateTime]$_.createddate -le [DateTime]::Now.AddDays(-$RetentionTime)}
}
while ($result.count -eq 1000)

#Cleanup
foreach ($ShelveSet in $OldShelvesets)
{
	"Removing shelveset $($ShelveSet.Owner) `t $($ShelveSet.Name)"| Out-File $LogFile -Append
    if ($DeleteShelvesets)
    {
        Write-Host "Removing Shelveset $($shelveset.name) owned by $($ShelveSet.Owner)"
        & $TFcmd vc shelve /collection:$TFSServerURL /delete "`"$($shelveset.name);$($ShelveSet.Owner)`""
    }
} 

Author: KimC

TFS admin and deployment fellow

One thought on “Shelveset Cleanup”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s