Yesterday I posted about how to create script hooks in a 2012 build template. My colleague Tyler Doerksen commented and pointed out that there was no error handling in my solution.

Returning Error Codes from PowerShell

I knew that if I could get the script to return an error code, it would be simple to add an If activity to check it. The trick is to use “exit 0” for success and “exit 1” for failures. I also changed any error messages from Write-Host to Write-Error so that they go to errOutput and not stdOutput. Here’s the updated “UpdateVersion” script:

  [string]$pathToSearch = $env:TF_BUILD_SOURCESDIRECTORY,
  [string]$buildNumber = $env:TF_BUILD_BUILDNUMBER,
  [string]$searchFilter = "AssemblyInfo.*",
  [regex]$pattern = "\d+\.\d+\.\d+\.\d+"

if ($buildNumber -match $pattern -ne $true) {
    Write-Error "Could not extract a version from [$buildNumber] using pattern [$pattern]"
    exit 1
} else {
    try {
        $extractedBuildNumber = $Matches[0]
        Write-Host "Using version $extractedBuildNumber"

        gci -Path $pathToSearch -Filter $searchFilter -Recurse | %{
            Write-Host "  -> Changing $($_.FullName)" 
            # remove the read-only bit on the file
            sp $_.FullName IsReadOnly $false

            # run the regex replace
            (gc $_.FullName) | % { $_ -replace $pattern, $extractedBuildNumber } | sc $_.FullName

        Write-Host "Done!"
        exit 0
    } catch {
        Write-Error $_
        exit 1

Error Handling in the Build

Go back to the InvokeProcess activity that calls your script. Go to its parent activity (usually a sequence) and add a variable Int32 called “scriptResult”. On the InvokeProcess, set the result property to “scriptResult”.


Now you just need to add an If activity below the InvokeProcess that has condition “scriptResult <> 0” and add a Throw in the “Then”. I’m just throwing an Exception with an error message.


Here’s the output if the script fails:


Happy building!