10

I am trying to set the Azure pipeline variable value in PowerShell. I have created one variable winversion in the Azure pipeline. Now, in a PowerShell task, I want to assign some values to the winversion variable. My simple question is how can I change the value of an Azure PipeLine variable at run time?

Write-Host "Main value is $winversion"
$env:WINVERSION="abhinav";
Write-Host "Modified value is $env:WINVERSION"
Write-Host "Main value is $(winversion)"

Firstline print: original value is 123
Thirdline Print: Modified value is abhinav
Fourth Line print: 123

I want when I change the value of winversion from "123" to "abhinav" so it actually changes the pipeline variable value to abhinav.

enter image description here

enter image description here

I want to update this variable through Powershell. I am using one PowerShell script calling the API and trying to update its variable but getting the page not found error:-

param(
[string]$winVersion
)
$body = "{ 'definition' : { 'id' :85}
}"
$valueName="Winver"
$definitionId=85
$User=""
$Password=""
$base64authinfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User, $Password)))
$Uri = "https://Muac.visualstudio.com/OSGCXE/_apis/release/releases?api-version=2.0"
$urlDef = "https://Muac.visualstudio.com/OSGCXE/_apis/release/definitions/" + $definitionId + "?api-version=2.0"
$definition = Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64authInfo)} -Method Get -Uri $urlDef 

#Write-Host $definition

$definition.variables.$valueName.Value = "$winVersion"
$definitionJson = $definition | ConvertTo-Json -Depth 50 -Compress

#Write-Host (ConvertTo-Json $definition -Depth 100)

$update=Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64authInfo)} -Method Put -Uri $urlDef -Body $definitionJson -ContentType "application/json"

#Write-Host "$update"

#$buildresponse = Invoke-RestMethod -Method Post -ContentType application/json -Uri $Uri -Headers @{Authorization=("Basic {0}" -f $base64authinfo)} -Body $body

#write-Host $buildresponse.status
David Buck
  • 3,752
  • 35
  • 31
  • 35
Abhinav Sharma
  • 299
  • 1
  • 8
  • 20
  • 3
    Possible duplicate of [Is it possible to set an VSTS Build variable in a Build Step so that the value can be used in a subsequent Build Step?](https://stackoverflow.com/questions/32881749/is-it-possible-to-set-an-vsts-build-variable-in-a-build-step-so-that-the-value-c) – 4c74356b41 Apr 02 '19 at 10:52
  • You can't put a new value to the variable like regular way, you need to follow the answer above. – Shayki Abramczyk Apr 02 '19 at 11:01
  • Write-Host "##vso[task.setvariable variable=winversion;]test" I also tried with that but nothing happens. Write-Host "Main value is $(winversion)" always print the first value 23 not test. – Abhinav Sharma Apr 02 '19 at 13:02
  • This is another link from Microsoft's docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=designer%2Cpowershell#set-in-script – m00nbeam360.0 Apr 02 '19 at 16:53
  • 1
    i think it will only get updated in the next step, not in the same step – 4c74356b41 Apr 02 '19 at 20:01

2 Answers2

7

How To set azure pipeline variable from PowerShell

There is a bit of confusion here, you use the variable $winversion in the powershell scripts, but the variable is set testvar in the pipeline variable.

Anyway, no matter we overwrite the pipeline variable value directly like you, or use the script "##vso[task.setvariable variable=testvar;]testvalue" to overwrite it, the overwrite value only work for current build pipeline. When you use the $(winversion) to get the value, it will still pull the value from pipeline variable value. To get the current value, you need use $env:WINVERSION.

Besides, you said:

I want when I change the value of winversion from "123" to "abhinav" so it actually changes the pipeline variable value to abhinav.

If you mean you want change the pipeline variable value on the web portal, you need the REST API (Definitions - Update) to update the value of the build pipeline definition variable from a build task.

There is a very similar thread, you can check the answer for the details:

How to modify Azure DevOps release definition variable from a release task?

Note:Change the API to the build definitions:

PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=5.0

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • variable name in pipeline is winversion – Abhinav Sharma Apr 03 '19 at 07:50
  • 1
    @AbhinavSharma, Ahah, It is my fault, very very sorry about this. You should use the API `PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=5.0` Check the document here:https://learn.microsoft.com/en-us/rest/api/azure/devops/release/definitions/update?view=azure-devops-rest-5.0. And as test, I could use Definitions - Get API to get all the release list. – Leo Liu Apr 04 '19 at 07:25
  • Please look at my complete script in the question section i have added some more lines to my question. – Abhinav Sharma Apr 04 '19 at 07:32
  • @AbhinavSharma, To make sure we the path is correct, you can try to use postman to get a release definition by the get PAI:`GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=5.0`, if we get the 200OK, then we change it to update API. – Leo Liu Apr 04 '19 at 08:11
  • @AbhinavSharma, As I test with postman, we could not use the username/password to call that Rest API(401 Unauthorized). You can try to use PAT or Access OAuth Token to do it, check the details from this ticket: https://stackoverflow.com/questions/52399076/how-to-increase-update-variable-group-value-using-azure-devops-build-definition – Leo Liu Apr 04 '19 at 09:33
2

I found this link helpful: https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=powershell

This has the complete options of what you can do: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch

You can reuse set variable from task to task, and also job to job. I couldn't find anything on stage to stage.

In summary:

jobs:

# Set an output variable from job A
- job: A
  pool:
    vmImage: 'vs2017-win2016'
  steps:
  - powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
    name: setvarStep
  - script: echo $(setvarStep.myOutputVar)
    name: echovar

# Map the variable into job B
- job: B
  dependsOn: A
  pool:
    vmImage: 'ubuntu-16.04'
  variables:
    myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ]  # map in the variable
                                                                          # remember, expressions require single quotes
  steps:
  - script: echo $(myVarFromJobA)
    name: echovar
Ryan Harlich
  • 157
  • 1
  • 7
  • Well, to reuse variable in the same scope, you will be able to use a shorter syntax: `nugetConfigPath: "$(set_pipeline_vars_task.solution_dir_path)/NuGet.Config"` – Dmytro Bondarenko Apr 05 '23 at 12:44