Use a PowerShell script to customize your pipeline

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

When you're ready to move beyond the basics of compiling and testing your code, use a PowerShell script to add your team's business logic to your build pipeline. You can run Windows PowerShell on a Windows build agent. PowerShell Core runs on any platform.

Add a PowerShell script

The syntax for including PowerShell Core is slightly different from the syntax for Windows PowerShell.

  1. Push your PowerShell script to your repo.

  2. Add a pwsh or powershell step. The pwsh keyword is a shortcut for the PowerShell task for PowerShell Core. The powershell keyword is another shortcut for the PowerShell task.

# for PowerShell Core
- pwsh: ./my-script.ps1

# for Windows PowerShell
- powershell: .\my-script.ps1

Example PowerShell script: version assemblies

Here's an example script to version your assemblies. For the script to run successfully, you'll need to update your build number to use a format with four periods (example: $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)). Build number can also be referred to as run number.

You can customize your build number within a YAML pipeline with the name property.

name: $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)

  vmImage: windows-latest

- pwsh: echo $(Build.BuildNumber) //output updated build number
# If found use it to version the assemblies.
# For example, if the 'Build number format' build pipeline parameter 
# $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
# then your build numbers come out like this:
# "Build HelloWorld_2013.07.19.1"
# This script would then apply version 2013.07.19.1 to your assemblies.
# Enable -Verbose option
# Regular expression pattern to find the version in the build number 
# and then apply it to the assemblies
$VersionRegex = "\d+\.\d+\.\d+\.\d+"
# If this script is not running on a build server, remind user to 
# set environment variables so that this script can be debugged
	Write-Error "You must set the following environment variables"
	Write-Error "to test this script interactively."
	Write-Host '$Env:BUILD_SOURCESDIRECTORY - For example, enter something like:'
	Write-Host '$Env:BUILD_SOURCESDIRECTORY = "C:\code\FabrikamTFVC\HelloWorld"'
	Write-Host '$Env:BUILD_BUILDNUMBER - For example, enter something like:'
	Write-Host '$Env:BUILD_BUILDNUMBER = "Build HelloWorld_0000.00.00.0"'
	exit 1
# Make sure path to source code directory is available
	Write-Error ("BUILD_SOURCESDIRECTORY environment variable is missing.")
	exit 1
elseif (-not (Test-Path $Env:BUILD_SOURCESDIRECTORY))
	exit 1
# Make sure there is a build number
	Write-Error ("BUILD_BUILDNUMBER environment variable is missing.")
	exit 1
# Get and validate the version data
$VersionData = [regex]::matches($Env:BUILD_BUILDNUMBER,$VersionRegex)
         Write-Error "Could not find version number data in BUILD_BUILDNUMBER."
         exit 1
   1 {}
         Write-Warning "Found more than instance of version data in BUILD_BUILDNUMBER." 
         Write-Warning "Will assume first instance is version."
$NewVersion = $VersionData[0]
Write-Verbose "Version: $NewVersion"
# Apply the version to the assembly property files
$files = gci $Env:BUILD_SOURCESDIRECTORY -recurse -include "*Properties*","My Project" | 
	?{ $_.PSIsContainer } | 
	foreach { gci -Path $_.FullName -Recurse -include AssemblyInfo.* }
	Write-Verbose "Will apply $NewVersion to $($files.count) files."
	foreach ($file in $files) {
		$filecontent = Get-Content($file)
		attrib $file -r
		$filecontent -replace $VersionRegex, $NewVersion | Out-File $file
		Write-Verbose "$file.FullName - version applied"
	Write-Warning "Found no files."

Example PowerShell script: access REST API

In this example, you'll use the SYSTEM_ACCESSTOKEN variable to access the Azure Pipelines REST API.

You can use $env:SYSTEM_ACCESSTOKEN in your script in a YAML pipeline to access the OAuth token.

- task: PowerShell@2
    targetType: 'inline'
    script: |
      $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=5.0"
              Write-Host "URL: $url"
              $pipeline = Invoke-RestMethod -Uri $url -Headers @{
                  Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
              Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
     SYSTEM_ACCESSTOKEN: $(System.AccessToken)


What variables are available for me to use in my scripts?

You can use predefined variables in your scripts. For more information on available variables and how to use them, see Use predefined variables.

How do I set a variable so that it can be read by subsequent scripts and tasks?

To learn more about defining build variables in a script, see Define and modify your build variables in a script.

To learn more about defining release variables in a script, see Define and modify your release variables in a script

Which branch of the script does the build run?

The build will use the active branch of your code. If your pipeline run uses the main branch, your script will also use the main branch.

What kinds of parameters can I use?

You can use named parameters. Other kinds of parameters, such as switch parameters, aren't supported. You'll see errors if you try to use switch parameters.

I use TFS on-premises and I don't see some of these features. Why not?

Some of these features are available only on Azure Pipelines and not yet available on-premises. Some features are available on-premises if you have upgraded to the latest version of TFS.