How to get output from Azure Devops Powershell YAML - azure-devops

I have a yaml pipeline, using the task Azure Powershell Task
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-powershell?view=azure-devops
The script already has task output as follows:
$output = ConvertTo-Json -InputObject #{
resourceName = "aseName"
resourceGroupName = "ResourceGroupName"
} -Compress
Write-Output "##vso[task.setvariable variable=output;]$output"
In the subsequent task, within the same job. I need to use use it as {output.resourceName}. Typically from the designer it is possible to get it out the same way as I want. But with YAML I could not figure it out.
Any pointers?

just reference it like any other variable:
$(output)
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-in-script

As a side note, which might save others some time in the future. When you create a new stage and want to reference your variable, you should also add "isOutput=true" when you're setting the variable:
Write-Output "##vso[task.setvariable variable=output;isOutput=true]$output"
And when referencing the Output variable in YAML, call the variable as such:
- stage:
displayName: someName
variables:
output: $[stageDependencies.<stageName>.<jobName>.outputs['<stepname>.output']]
jobs:
- job: SomeName
steps:
- task: SomeTask

Related

Azure devOps deployment release setup

If the connection string is setup as a secret variable in the release pipeline.
Is there any way or any one to view the secret variable? If yes, how could we do it?
I write a powershell demo in the YAML file for you(Based on Daniel's idea.), please notice on the pipeline you will be unable to output the value because all of the same value will be captured by the pipeline and all of them will be covered by "***".
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-Host $(not_secure)
Write-Host $(secure)
#convert string to based64 string:
$secret = "$(secure)"
$secret = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($secret))
Write-Host $secret
Write-Host "value2" #Whenever the pipeline capture the same value of the secured secret, the pipeline will output '***'. So doing any tricks inside the pipeline can't make the pipeline output this value
Whenever the pipeline capture the same value of the secured secret,
the pipeline will output '***'. So doing any tricks inside the
pipeline can't make the pipeline output this value.
My pipeline output:
My variables:
get_secret_of_pipeline.ps1(run this on your machine.)
$secret = "dmFsdWUy"
$secret = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secret))
Write-Host $secret
Successfully get the value of secret:

Represent a list varible in an Azure DevOps pipeline, for use with PowerShell

I would like to have a list of items that I can iterate in PowerShell scripts in several stages of a release pipeline.
How can I represent a pipeline variable with multiple values, like a list? For instance, this variable could contain a list of languages.
What would be the syntax to access this pipeline variable from PowerShell?
Here is the syntax to pass a yaml list from an Azure DevOps pipeline parameter to an inline PowerShell script. The key is to use the convertToJson yaml method to convert the yaml object to json. Then converting that json into a PowerShell object with ConvertFrom-Json.
Parameters
parameters:
- name: environmentVariableList
type: object
default:
- key: ASPNETCORE_ENVIRONMENT
value: DV
- key: Variable2
value: Value2
Inline Script:
InlineScript: |
$environmentVariableList = '${{ convertToJson(parameters.environmentVariableList) }}' | ConvertFrom-Json
foreach($i in $environmentVariableList)
{
Write-Host "Setting environment variable [$($i.key)] to [$($i.value)]"
[Environment]::SetEnvironmentVariable($i.key, $i.value, "Machine")
}

How to specifiy formating of time string in azure pipeline build number

From the documention you can format the build number for the azure devops build pipeline but the formating on the time isn't working for me.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/run-number?view=azure-devops&tabs=yaml
I want something like
YY.MM.DD.MMSS
name: $(Date:yy).$(Date:MM).$(Date:dd).$(Hours)$(Minutes)
However this will generate single digits like '20.08.12.150' for 3pm. Does anyone know a way of forcing the format like the date fields so it will always be 2 chars? $(Hours:hh)$(Minutes:mm) does not work; I did try that.
Thanks
Instead of define the build number in name: of yaml file, you could add a powershell task to update the build number with command ##vso[build.updatebuildnumber]build number. Check the following example:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Set-TimeZone -Id "China Standard Time"
[string] $dateTime = (Get-Date -Format 'yy.MM.dd.HHmm')
Write-Host "Setting the name of the build to '$dateTime'."
Write-Host "##vso[build.updatebuildnumber]$dateTime"

ADS 2019 - How to pass variables between build jobs

Using Azure DevOps Server 2019.1 i am starting to work with Multi jobs, to allow me to split up work onto multiple agents.
The flow itself works fine. I have it setup like this
Begin Job - this basically tests a few variables and Updated the buildnumber
(Depends on Begin Job) RunTest Job - A job to run "multi-configuration", which splits a comma seporated list of task categories
(Depends on RunTest Job) End Job - A trigger build task for a new build in the chain
While the jobs depend on another job, this only seems to affect the time they will start, they will not get access to the information provided by the job that ran before.
Basically what i need is the value of a variable that has been set (buildNumber) in the Begin Job.
I need this version number in the RunTest and End Job.
How can i get this information ? I read articles that this is not possible, but have not seen a valid workaround yet. Does anyone have a decent workaround ?
Did you try multi job output variable:
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
Update2:
Using YAML should be the simplest solution. If you insist on Classic build view. You could try to accomplish this by storing the values in a file (json, xml, yaml, what have you), you can read the file in the Job either direct use or re-set the variable again.
When you queue next build, it will not effect the file in source control and the default value will also not change.
Passing variables between jobs in the same stage, it requires working with output variables.
However, according to this, using outputs in a different job is not supported in Classic UI Format.
As workarounds in this scenario, you can share variables via Pipeline Variables(share variables across jobs in same pipeline).
1.You can set a key variable in pipeline variables:
2.Add one Powershell Inline task with content below in your first job:
$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)"
# Update an existing variable to its new value
$pipeline.variables.key.value = "value"
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Varialbe key is updated to" $updatedef.variables.key.value
write-host "=========================================================="
3.Run the pipeline we can find the value of key variable is successfully updated:
So you can run the ps script in first job to update the value of key variable, then all next jobs can access the updated variable easily.
Note:
For the script itself, you only need to change lines $pipeline.variables.key.value = "value"(necessary) and Write-host "The value of Varialbe key is updated to" $updatedef.variables.key.value(optional).
If I want to set the variable named MyTest to value MyValue, the lines should be $pipeline.variables.MyTest.value = "MyValue" and Write-host "The value of Varialbe MyTest is updated to" $updatedef.variables.MyTest.value.
To make sure the ps task in one job can access OAuth Token, we should Allow Scripts to Access OAuth Token. Click the agent job name and check the box:
To enable the pipeline has the permission to update pipeline variable (edit build pipeline), go pipeline security to set the Edit build pipeline allow for user xxx(ProjectName) build service.

Pass build variables to powershell inline script in Azure DevOps pipeline

I have set a build variable which I would like to consume in my inline powershell script.
I tried $($myvariable) but this comes out blank.
Pass build variables to powerhshell inline script in Azure DevOps
To get the build variables with inline power shell script, you can try to use following syntax $env:variable:
$env:myvariable
The build variable:
The build result:
Note:At this moment, the value of nested variables (like $(myvariable$(Build.SourceBranchName))) on build variables table are not yet supported in the build pipelines.
Hope this helps.
here's what's working for me:
$(variableName)
for example built-in variable called Build.BuildNumber can be accessed like so:
$(Build.BuildNumber)
full example with format function:
- task: AzurePowerShell#3
displayName: UpdatePrereq
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
ScriptType: InlineScript
Inline: |
${{ format('. $(Build.Repository.LocalPath)\scripts\_helpers.ps1
Update-DeploymentPrereq -resourceGroup {1} -location {3}
Update-Prereq -pathSuffix {0} -pathBase $(Build.Repository.LocalPath) -resourceGroup {1} -buildId $(Build.BuildNumber) -paramFile {2}
Update-DeploymentConcurrency -resourceGroup {1} -buildId $(Build.BuildNumber)',
parameters.buildDir, parameters.resourceGroupName, parameters.paramFile, parameters.location ) }}
azurePowerShellVersion: LatestVersion
If you need to use nested variables you can use something like this:
$name = "CONNECTIONSTRING_$(Agent.MachineName)"
$val = [System.Environment]::GetEnvironmentVariable($name)
And then you get the value of the variable ConnectionString.MACHINENAME