Powershell to help plot graphs of how long TFS upgrades take

When doing TFS upgrades it is useful to know roughly how long they will take. The upgrade programs give a number of steps, but not all steps are equal. Some are quick, some are slow. I have found it useful to graph past updates so I can get a feel of how long an update will take given it got to ‘step x in y minutes’. You can do this by hand, noting down time as specific steps are reached. However for a long upgrade it usually means pulling data out of the TFS TPC upgrade logs.

To make this process easier I put together this script to find the step completion rows in the log file and format them out such that they are easy to graph in Excel

param
(
    $logfile = "TPC_ApplyPatch.log",
    $outfile = "out.csv"
)


# A function to covert the start and end times to a number of minutes
# Can't use simple timespan as we only have the time portion not the whole datetime
# Hence the hacky added a day-1 second
function CalcDuration
{
    param
    (
        $startTime,
        $endTime
    )

    $diff = [dateTime]$endTime - $startTime
    if ([dateTime]$endTime -lt $startTime)
    {
       $diff += "23:59" # add a day as we past midnight
    }

    [int]$diff.Hours *60 + $diff.Minutes
}

Write-Host "Importing $logfile for processing"
# pull out the lines we are interested in using a regular expression to extract the columns
# the (.{8} handle the fixed width, exact matches are used for the test
$lines = Get-Content -Path $logfile | Select-String "  Executing step:"  | Where{$_ -match "^(.)(.{8})(.{8})(Executing step:)(.{2})(.*)(')(.*)([(])(.*)([ ])([of])(.*)"} | ForEach{
    [PSCustomObject]@{
        'Step' = $Matches[10]
        'TimeStamp' = $Matches[2]
        'Action' = $Matches[6]
    }
}
 
# We assume the upgrade started at the timestamp of the 0th step
# Not true but very close
[DateTime]$start = $lines[0].TimeStamp

Write-Host "Writing results to $outfile"
# Work out the duration
$steps = $lines | ForEach{
    [PSCustomObject]@{
        'Step' = $_.Step
        'TimeStamp' = $_.TimeStamp
        'EplasedTime' = CalcDuration -startTime $start -endTime $_.TimeStamp
        'Action' = $_.Action
       
    }
}
$steps | export-csv $outfile -NoTypeInformation

# and list to screen
$steps