I've written a PowerShell script to iteratively grab changesets from TFS, and do a build of the solution from that changeset. For each build I record the time taken. This is useful if you think builds are taking longer than they used to and you need some quantitative evidence. You can save the output to a CSV file and open it up in Excel to display a pretty graph etc.

To use the script, you'll need to have installed the Team Foundation Server Power Tools which include PowerShell cmdlets for TFS.

\# Iteratively build changesets from TFS to measure build speed
#
# Run this from a folder that is mapped as the TFS workspace

# Load VSVARS.BAT (From http://blogs.msdn.com/b/ploeh/archive/2008/04/09/visualstudio2008powershell.aspx)
function VsVars32()
{
    $vs100comntools = (Get-ChildItem env:VS100COMNTOOLS).Value
    $batchFile = \[System.IO.Path\]::Combine($vs100comntools, "vsvars32.bat")
    Get-Batchfile $BatchFile
}

function Get-Batchfile ($file) {
    $cmd = "\`"$file\`" & set"
    cmd /c $cmd | Foreach-Object {
        $p, $v = $\_.split('=')
        Set-Item -path env:$p -value $v
    }
}

VsVars32

# Get changeset history since 1-Jan-2011 and checked in by me
$history = Get-TfsItemHistory "$/Project/Branch" -Version "D01/01/11~" -Recurse | Where-Object { $\_.Owner -eq "DOMAIN\\username" }

# Process changesets from earliest to latest
\[array\]::Reverse($history)

$tf = "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\TF.exe"

$history | % {
    & $tf get /version:C$($\_.ChangesetId) /Recursive /Overwrite /NoPrompt 2>&1 | Out-Null

    # clean first
    & "msbuild.exe" /t:Clean /noconlog /v:q /nologo 2>&1 | Out-Null

    # build
    $duration = Measure-Command { & "msbuild.exe" /noconlog /v:q /nologo  }

    if ($LastExitCode -eq 0)
    {
        Write-Output "$($\_.ChangesetId), $($duration.TotalSeconds)"
    }
    else {
        Write-Warning "$($\_.ChangesetId) build failed"
    }
}