2

I am trying to use an output variable from a powershell script. I'm using Devops online using the classic UI and tried both powershell 4.* and Powershell 5.* tasks in a release pipeline.

I am using a self-hosted agent that is working and doing lots of other build and release powershell stuff just fine. Azure Powershell modules version 3.5.0 (there is a reason for not using 4.x right now).

To simplify it, here is my test inline script in total...:

Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'
Write-Host "This is host"

Write-Output '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'
Write-Output "This is output"

Here is the output from the Azure powershell task. (4.*)

2020-07-01T00:06:57.2970494Z ##[section]Starting: Azure PowerShell script: InlineScript
2020-07-01T00:06:57.3335882Z 
==============================================================================
2020-07-01T00:06:57.3336692Z Task         : Azure PowerShell
2020-07-01T00:06:57.3337292Z Description  : Run a PowerShell script within an Azure environment
2020-07-01T00:06:57.3337566Z Version      : 4.171.1
2020-07-01T00:06:57.3338039Z Author       : Microsoft Corporation
2020-07-01T00:06:57.3338575Z Help         : https://aka.ms/azurepowershelltroubleshooting
2020-07-01T00:06:57.3338930Z 
==============================================================================
2020-07-01T00:06:58.5902105Z ## Validating Inputs
2020-07-01T00:06:58.5915067Z ## Validating Inputs Complete
2020-07-01T00:06:58.5924850Z ## Initializing Az module
2020-07-01T00:06:59.0747435Z ##[command]Import-Module -Name C:\Program 
Files\WindowsPowerShell\Modules\Az.Accounts\1.9.0\Az.Accounts.psd1 -Global
2020-07-01T00:07:00.0802372Z ##[command]Clear-AzContext -Scope Process
2020-07-01T00:07:01.5597330Z ##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue
2020-07-01T00:07:01.9691282Z ##[command]Connect-AzAccount -Identity @processScope
2020-07-01T00:07:03.1860248Z ##[command] Set-AzContext -SubscriptionId 5ec8ec06-XXXX-XXXX-XXXX- c0ff86c50e4 -TenantId ***
2020-07-01T00:07:03.9196710Z ## Az module initialization Complete
2020-07-01T00:07:03.9203692Z ## Beginning Script Execution
2020-07-01T00:07:03.9674782Z ##[command]& 'C:\DevOps\_work\_temp\1b1b130b-4306-448b-b4b2-e7daefc2382e.ps1' 
2020-07-01T00:07:03.9974844Z This is host
2020-07-01T00:07:04.0101140Z This is output
2020-07-01T00:07:04.0517610Z ##[command]Disconnect-AzAccount -Scope Process -ErrorAction Stop
2020-07-01T00:07:04.4795714Z ##[command]Clear-AzContext -Scope Process -ErrorAction Stop
2020-07-01T00:07:04.9468120Z ## Script Execution Complete
2020-07-01T00:07:04.9857991Z ##[section]Finishing: Azure PowerShell script: InlineScript

Note that "This is Host" and "This is Output" both display but the "##vso[...." does not.

Also the MobileAppInsightsKey I am trying to read in a subsequent step is empty (uninitialized).

Hopefully someone can point me in the right direction.

Thanks, Mark.

huysmania
  • 1,054
  • 5
  • 11
MarkD
  • 1,511
  • 18
  • 32

2 Answers2

5

And to make a clear description about this issue:

To define a job-scoped variable in your scenario, we don't need to add isOutput=true;

1.For job-scoped variable(Variable is only valid in current job):

Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey]thisisthekey' is enough. And we can output its value via format $(MobileAppInsightsKey) in CMD task.

2.For multi-job output variable(Variable is valid in multi-job):

We should use Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'.

In current job: You can use $(referencename.variablename) to get its value. (Support classic pipeline and yaml pipeline)

In subsequent jobs: Use below format to access the variable, and this format only supports yaml pipeline!!!

- 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

So for your scenario in which you want to access the variable in same job, just remove the isOutput=true;(it's not necessary). Or use $(referencename.variablename) format if you add isOutput=true; in the statement. (Not necessary, not recommended, but it should also work for current job)

In addition:

Details about $(referencename.variablename) format.

For Classic pipeline:(Set name as Test in Powershell task)

enter image description here

$(Test.MobileAppInsightsKey) represents the value of the variable.

For yaml pipeline:

  - powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
    name: Test
  - script: echo $(Test.myOutputVar)
LoLance
  • 25,666
  • 1
  • 39
  • 73
  • Thank you - this is a much more detailed "why" than my answer. I'll test it locally for the current job then mark it as answer. If you have any influence over the doc writers, maybe they can add this clarity. It makes sense now I know why but it isn't obvious from the docs that there is a distinction on how you must reference when you add isOutput=true; Cheers. – MarkD Jul 02 '20 at 20:00
  • 1
    Agree, it would be better if the docs add a `Note:Only format $(referenceName.variableName) is supported in current job when using is output=true`. You can share your feedback [here](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#recursive-expansion) via `This Page` option, the writer would reply if he views it. Hope it helps :) – LoLance Jul 03 '20 at 02:25
4

More messing around and I made it work. The answer goes against everything I have read both in docs and on SO.

If I don't use the

isOutput=true;

then it works.

I don't know why but happy to be educated. Thx, Mark.

MarkD
  • 1,511
  • 18
  • 32
  • When using isOutput=true; a prefix with the build step's name is added to the variable. E.g. if your variable name is "MyOutputVar", and it is set from a Powershell script within a build step of a classic Azure pipeline, then the full variable name will actually be "POWERSHELL1_MyOutputVar" or something similar. You can verify this by adding another build step with the command line "set" to show all your variables. – sɐunıɔןɐqɐp Jun 20 '23 at 07:42