Azure Pipeline Variables

There exists several types of variables that can be added to YAML scripts. I really like the Microsoft page that lays out a table that specifies the type of variable and when its value is computed and set. I have reproduced it below. The Azure documentation is listed in the Links section.

SyntaxExampleWhen is it processed?Where does it expand in a pipeline definition?How does it render when not found?
macro$(var)runtime before a task executesvalue
(right side)
prints $(var)
template expression${{variables.var}}compile timekey or value
(left or right side)
empty string
runtime expression$[variables.var]runtimevalue
(right side)
empty string

Variable Naming Restrictions

User-defined and environment variables can consist of letters, numbers, ., and _ characters. Don’t use variable prefixes reserved by the system. These are: endpoint, input, secret, path, and securefile. Any variable that begins with one of these strings (regardless of capitalization) won’t be available to your tasks and scripts.

PowerShell: Accessing Variables and the Environment

The variables that are defined in the YAML are also available from the environment. In the example below, we define variable cg_RootFolder in the variables section so it will be available to all jobs in the pipeline.

Note that variable substitution that occurs with “${}” is using PowerShell complex variable escaping that allows a variable value that may include spaces or special characters (items 12-13).

variables:
  # Top level repo folder location on build agent. Looks like "D:\A\1\S\{repo}"
  cg_RootFolder: $(Build.SourcesDirectory)\$(Build.Repository.Name)

jobs:
- job:
  workspace:
    clean: all
  pool:
    vmImage: 'windows-2019' # Generic VM without any Select Product/SDK version installed.

  steps:
    # Perform PowerShell commands.
    - task: PowerShell@2
      displayName: PowerShell examples
      inputs:
          targetType: inline
          script: |
            Write-Host "Examples of Azure variables being inserted before PowerShell task executes..."
            Write-Host "(1)        cg_RootFolder:" $(cg_RootFolder)
            Write-Host "(2)        cg_RootFolder: $(cg_RootFolder)"
            Write-Host '(3)        cg_RootFolder: $(cg_RootFolder)'

            Write-Host "(4)        cg_RootFolder:" $env:cg_RootFolder
            Write-Host "(5)        cg_RootFolder: $env:cg_RootFolder"
            Write-Host '(6)        cg_RootFolder: $env:cg_RootFolder'
            Write-Host "(7)  AZURE_EXTENSION_DIR:" $env:AZURE_EXTENSION_DIR

            Write-Host "`nExamples of Azure variable loaded into PowerShell variable..."
            $a = $env:AZURE_EXTENSION_DIR
            Write-Host "(10) a: $a"
            Write-Host "(11) a:" $a
            
            $b = ${env:AZURE_EXTENSION_DIR}
            Write-Host "(12) b: $b"
            Write-Host "(13) b:" $b

Results in the following Azure pipeline output. In lines 1 through 3, the pipeline inserts the value of cg_RootFolder into the script immediately BEFORE the script runs. In the remaining lines, PowerShell loads the value from the environment at runtime.

Notice that the variable was not expanded in line 6 because it was enclosed in single quotes.

Examples of Azure variables being inserted before PowerShell task executes...
(1)        cg_RootFolder: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(2)        cg_RootFolder: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(3)        cg_RootFolder: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(4)        cg_RootFolder: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(5)        cg_RootFolder: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(6)        cg_RootFolder: $env:cg_RootFolder
(7)  AZURE_EXTENSION_DIR: C:\Program Files\Common Files\AzureCliExtensionDirectory

Examples of Azure variable loaded into PowerShell variable...
( 8) a: C:\Program Files\Common Files\AzureCliExtensionDirectory
( 9) a: C:\Program Files\Common Files\AzureCliExtensionDirectory
(10) b: C:\Program Files\Common Files\AzureCliExtensionDirectory
(11) b: C:\Program Files\Common Files\AzureCliExtensionDirectory

PowerShell: Changing Variable Values

We often need to create or change a variable value. The example below builds on the prior code to change the variable value with task.setvariable.

variables:
  # Top level repo folder location on build agent. Looks like "D:\A\1\S\{repo}"
  cg_RootFolder: $(Build.SourcesDirectory)\$(Build.Repository.Name)

<snip>

    # Write current value of variable then change it to "This is a new value."
    - powershell: |      
          Write-Host "(1) Before: $env:cg_RootFolder"
          Write-Host "(2) Before: $(cg_RootFolder)"
          Write-Host "##vso[task.setvariable variable=cg_RootFolder]This is a new value."
          Write-Host "(3) Inside same task: $env:cg_RootFolder"
          Write-Host "(4) Inside same task: $(cg_RootFolder)"

    # Write new value of variable and get original value, too.
    - powershell: |
          Write-Host "(5) Inside different task: $env:cg_RootFolder"
          Write-Host "(6) Inside different task: $(cg_RootFolder)"
          Write-Host "(7) Pipeline compile time value: ${{variables.cg_RootFolder}}"

The results in the following Azure pipeline output. In lines 3-4, notice that the new value is not available – it will be available until the next task starts (since values are loaded immediately before the task executes). Once the next task loads (lines 5-7) the variable will be updated.

There is a trick you can use to get the original unmodified value – use the ${{variables.varname}} format. This works because the pipeline sets this value at compile time before any code runs.

(1) Before: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(2) Before: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(3) Inside same task: D:\a\1\s\SoftPro-Select-DefaultDocFolder
(4) Inside same task: D:\a\1\s\SoftPro-Select-DefaultDocFolder

(5) Inside different task: This is a new value.
(6) Inside different task: This is a new value.
(7) Pipeline compile time value: D:\a\1\s\SoftPro-Select-DefaultDocFolder

Links

There are many rules and capabilities with variables in addition to those presented. Click here for further information.

Command Line task

PowerShell task