
Setting Azure DevOps pipeline variable from PowerShell script
Output value from PowerShell script to Azure DevOps builds and releases
When using Azure DevOps Pipelines or Releases, it is pretty easy to move informations from the pipeline/release into the target artifact package or folder on the target environment. What can be tricky if you need to dictate your pipeline/release based on the value from your code base or maybe the environment to which you are deploying to.
As a simple example I set the version attribute in in my .csproj file which I will use to tell UseDotNet task in my build pipeline which SDK to use to perform .NET Core project build.
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <Version>5.0.103</Version> </PropertyGroup> ... </Project>
In order to achieve this I need to read .csproj file from the local filesystem of build agent. Since first step after provisioning agent is cloning the project from the git repository, I will have my source code with my project file at local repository path which can be accessed through pre-defined Azure pipeline variables. You can check Azure DevOps predefined values from User predefined values page in Microsoft documentation.
Project source code will be cloned to that path under Build.Repository.LocalPath variable value.
From here we can read Version node value with a simple PowerShell script using System.Xml.XmlDocument class from .NET framework
$xdoc = new-object System.Xml.XmlDocument $file = "$(Build.Repository.LocalPath)\MulitpleDb.Sample\MulitpleDb.Sample.csproj" $xdoc.load($file) $version = $xdoc.SelectSingleNode("Project/PropertyGroup/Version").InnerText echo $version echo "##vso[task.setvariable variable=sdkVersion]$version"
Although I am using Windows build agent, same PowerShell script will also work on Linux build agent machine thanks to portability of PowerShell 7
Last two lines are used to print out the value read from the .csproj XML file node. The first line simply prints out the value to the console, but the second line, the last one in file uses the specific pattern ##vso[task.setvariable variable=<varaible name>]<value> to set the value of our pipeline variable.
From the PowerShell script you can see that we have variable called sdkVersion to which we push value calculated in the script. Now the sample pipeline would look something like this.
pool: vmImage: 'windows-latest' variables: solution: '**/*.sln' buildPlatform: 'Any CPU' buildConfiguration: 'Release' sdkVersion: '' steps: - task: PowerShell@2 displayName: 'Read SDK version' inputs: targetType: 'inline' script: | $xdoc = new-object System.Xml.XmlDocument $file = "$(Build.Repository.LocalPath)\MulitpleDb.Sample\MulitpleDb.Sample.csproj" $xdoc.load($file) $version = $xdoc.SelectSingleNode("Project/PropertyGroup/Version").InnerText echo $version echo "##vso[task.setvariable variable=sdkVersion]$version" - task: UseDotNet@2 displayName: 'Use .NET Core sdk' inputs: packageType: 'sdk' version: '$(sdkVersion)' installationPath: $(Agent.ToolsDirectory)/dotnet - task: DotNetCoreCLI@2 displayName: 'Restore NuGet packages' inputs: command: restore projects: '$(Build.Repository.LocalPath)\MulitpleDb.Sample\MulitpleDb.Sample.csproj' - task: DotNetCoreCLI@2 enabled: true displayName: "Build project" inputs: command: 'build' projects: '$(Build.Repository.LocalPath)\MulitpleDb.Sample\MulitpleDb.Sample.csproj' configuration: $(buildConfiguration) - task: DotNetCoreCLI@2 displayName: 'Publish' inputs: command: publish projects: '$(Build.Repository.LocalPath)\MulitpleDb.Sample\MulitpleDb.Sample.csproj' arguments: '--output $(Build.ArtifactStagingDirectory)' publishWebProjects: false
You can see that we have sdkVersion variable declared in variables section and it is initially set to en empty string. This is fine since we are going to set the value of this variable using PowerShell task.
Once the PowerShell task runs, we'll have value of the SDK version we want to use and we just simply use it in UseDotNet task of the pipeline
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article