简体   繁体   中英

AzureDevOps Pipeline variable assignment of Powershell script task output

I have a YAML pipeline which defines a variable called vmPrivateIp :

pr: none
  trigger: none

variables:
  vmName: 'MyVmName'
  vmPrivateIp: '10.0.0.1'

I want to assign this variable with the result of a script task which obtains the private IP of MyVmName :

- task: PowerShell@2
  inputs:
  targetType: 'inline'
  script: |
    $IP = (Get-AzNetworkInterface -Name $(vmName)-nic -ResourceGroupName MyResourceGroup).IpConfigurations.PrivateIpAddress
    Write-Host "##vso[task.setvariable variable=vmPrivateIp,isOutput=true]$IP"
    Write-Host $(vmPrivateIp)

The task runs fine but the variable still contains the initial value

在此处输入图像描述

What do I need to do in order to successfully assign the result of the script task to vmPrivateIp ?

In a job, if you use the ' SetVariable ' command in a step to set up an output variable with a new value, it is functionally equivalent to creating a new output variable that has the same name but different value with the pipeline variable. The pipeline variable and its initial value still are available.

This output variable is only available to the subsequent steps in the same job and the subsequent jobs that depend on current job. For the step which runs the ' SetVariable ' command to set up this output variable, this output variable is not available.

  • For the subsequent steps in the same job, you should use the expression " $(stepId.varName) " to access the value of the output variable. The expression " $(varName) " will return the value of the pipeline variable that is the initial value.

  • For each subsequent job that depends on current job, you should use the expression " $[dependencies.jobId.outputs['stepId.varName']] " to assign the value of the output variable to a job variable, then in the steps of the job you can access the value through this job variable.

To view more details, you can see " SetVariable: Initialize or modify the value of a variable " and " Set a multi-job output variable ".

An example as reference:

  • azure-pipelines.yml
variables:
  vmPrivateIp: '10.0.0.1'

jobs:
- job: 'JobA'
  displayName: 'Job A'
  steps:
  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: Write-Host "vmPrivateIp = $(vmPrivateIp)"
    displayName: 'View IP before update'

  - task: PowerShell@2
    name: 'UpdateIp'
    inputs:
      targetType: 'inline'
      script: Write-Host "##vso[task.setvariable variable=vmPrivateIp;isoutput=true]10.0.0.2"
    displayName: 'Update IP and set output'

  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: |
        Write-Host "vmPrivateIp = $(vmPrivateIp)"
        Write-Host "UpdateIp.vmPrivateIp = $(UpdateIp.vmPrivateIp)"
    displayName: 'View IP after update'

- job: 'JobB'
  displayName: 'Job B'
  dependsOn: 'JobA'
  variables:
    IP_from_JobA: $[dependencies.JobA.outputs['UpdateIp.vmPrivateIp']]
  steps:
  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: Write-Host "IP_from_JobA = $(IP_from_JobA)"
    displayName: 'View IP from JobA'
  • Result在此处输入图像描述

    在此处输入图像描述

    在此处输入图像描述

The purpose of task.setVariable is to communicate variable values to other tasks, jobs, and stages of your pipeline. You can't expect it to reflect a value into a variable within the task because it operates effectively after the task has completed - the pipeline runs Powershell, then scans the output for task.setVariable , and sets variables accordingly. So, within a task, you use the Powershell variable itself.

- task: PowerShell@2
  name: GetPrivateIp
  inputs:
  targetType: 'inline'
  script: |
    # Lives local to this script
    $IP = (Get-AzNetworkInterface -Name $(vmName)-nic -ResourceGroupName MyResourceGroup).IpConfigurations.PrivateIpAddress
    # Sets release variable after execution
    Write-Host "##vso[task.setvariable variable=privateIp;isOutput=true]$IP"
    # Writes your initial value as declared
    Write-Host $(vmPrivateIp)
- task: PowerShell@2
  name: UsePrivateIp
  inputs:
  targetType: 'inline'
  script: |
    Write-Host "$(GetPrivateIp.privateIp)"

Note that this syntax is for communication within a job - a different syntax is needed to communicate the variable to another job or stage of your pipeline.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM