Azure 在下一步中使用Powershell变量作为输入

Azure 在下一步中使用Powershell变量作为输入,azure,powershell,azure-devops,Azure,Powershell,Azure Devops,我需要从Json文件中读取设置以执行管道。为此,我使用Powershell任务。在下一步中,我想使用这些属性作为输入。但是,当我这样做时,变量不会被渲染。我怎样才能做到这一点 - task: PowerShell@2 displayName: 'Main -> Read App Setting' inputs: targetType: 'inline' script: | $settings = Get-Content "$(Build.Rep

我需要从Json文件中读取设置以执行管道。为此,我使用Powershell任务。在下一步中,我想使用这些属性作为输入。但是,当我这样做时,变量不会被渲染。我怎样才能做到这一点

- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"      
  
- template: ./.lib/create_resources.yml
  parameters:
    type: $(type)
但是,当我这样做时,变量不会被渲染。我怎么能 实现这一目标

- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"      
  
- template: ./.lib/create_resources.yml
  parameters:
    type: $(type)
不能以这种方式将参数传递给模板。未呈现该变量,因为无法在模板参数中使用运行时变量。这是它没有被渲染的直接原因

这是Azure Devops服务的设计,请检查:

因此,您的变量出现在任务执行之后(步骤6),而参数在该过程的第一步(管道运行过程的步骤1)进行计算。见:

这种排序有助于回答一个常见问题:为什么我不能在模板参数中使用某些变量?步骤1,模板扩展,仅对YAML文档的文本进行操作。该步骤中不存在运行时变量。步骤1之后,模板参数已完全解析,不再存在

此外:Shayki Abramczyk的评论是正确的,虽然这不是问题的主要原因,但您应该使用
编写主机“##vso[task.setvariable=type]$($settings.pipeline.type)”
,以便
$(type)的值
将是
$settings.pipeline.type
而不是
$settings

在下一步中使用变量:

steps:
- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"

- template: ./template1.yml
  parameters:
    input: $(type)
    outputVariable: template1Output

- template: ./template2.yml
  parameters:
    input: $(template1Output)
parameters:
- name: input
  type: string
- name: outputVariable
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 1
  inputs:
    targetType: inline
    script: |
      $input = "${{parameters.input}}"
      $output = $input + " some extra value"
      Write-Host "##vso[task.setvariable variable=input]${{parameters.input}}"
      Write-Host "##vso[task.setvariable variable=${{parameters.outputVariable}}]$output"

- template: ./template2.yml
  parameters:
    input: $(input)
parameters:
- name: input
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 2
  inputs:
    targetType: 'inline'
    script: |
      echo "${{parameters.input}}"
我们可以检查:

为了将变量用作任务输入,必须将该变量设置为输出变量,并且必须为生成任务指定一个引用名称


有关如何在yaml管道中使用该参数的更多详细信息,请检查my。

如Lance所述,问题是模板参数首先展开,因此当使用变量作为模板中任务的输入时,设置参数不起作用。但是,我发现在模板中的PowerShell任务中,完全相同的参数显示了最新的值

此外,我希望按顺序运行模板,并将模板1的输出用于模板2等,而模板1不知道模板2,也不依赖。这样,仍然可以从DevOps手动运行单个模板

因此,我使用了以下设置,它满足这两个要求。它将输出从模板1传递到模板2,而不在模板本身中硬编码这些变量&它显示模板1先使用PowerShell将参数转换为变量,然后将传入参数作为输入传递几秒钟。通过这种方式,可以向每个模板添加PowerShell脚本,将所有参数转换为变量,并在模板中使用这些变量。一个额外的步骤,但在MS包括动态参数之前,我认为是可以接受的

Main:

steps:
- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"

- template: ./template1.yml
  parameters:
    input: $(type)
    outputVariable: template1Output

- template: ./template2.yml
  parameters:
    input: $(template1Output)
parameters:
- name: input
  type: string
- name: outputVariable
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 1
  inputs:
    targetType: inline
    script: |
      $input = "${{parameters.input}}"
      $output = $input + " some extra value"
      Write-Host "##vso[task.setvariable variable=input]${{parameters.input}}"
      Write-Host "##vso[task.setvariable variable=${{parameters.outputVariable}}]$output"

- template: ./template2.yml
  parameters:
    input: $(input)
parameters:
- name: input
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 2
  inputs:
    targetType: 'inline'
    script: |
      echo "${{parameters.input}}"
模板1:

steps:
- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"

- template: ./template1.yml
  parameters:
    input: $(type)
    outputVariable: template1Output

- template: ./template2.yml
  parameters:
    input: $(template1Output)
parameters:
- name: input
  type: string
- name: outputVariable
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 1
  inputs:
    targetType: inline
    script: |
      $input = "${{parameters.input}}"
      $output = $input + " some extra value"
      Write-Host "##vso[task.setvariable variable=input]${{parameters.input}}"
      Write-Host "##vso[task.setvariable variable=${{parameters.outputVariable}}]$output"

- template: ./template2.yml
  parameters:
    input: $(input)
parameters:
- name: input
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 2
  inputs:
    targetType: 'inline'
    script: |
      echo "${{parameters.input}}"
模板2:

steps:
- task: PowerShell@2
  displayName: 'Main -> Read App Setting'
  inputs:
    targetType: 'inline'
    script: |
      $settings = Get-Content "$(Build.Repository.LocalPath)\settings\appsettings.json" | ConvertFrom-Json
      Write-Host "##vso[task.setvariable variable=type]$($settings.pipeline.type)"

- template: ./template1.yml
  parameters:
    input: $(type)
    outputVariable: template1Output

- template: ./template2.yml
  parameters:
    input: $(template1Output)
parameters:
- name: input
  type: string
- name: outputVariable
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 1
  inputs:
    targetType: inline
    script: |
      $input = "${{parameters.input}}"
      $output = $input + " some extra value"
      Write-Host "##vso[task.setvariable variable=input]${{parameters.input}}"
      Write-Host "##vso[task.setvariable variable=${{parameters.outputVariable}}]$output"

- template: ./template2.yml
  parameters:
    input: $(input)
parameters:
- name: input
  type: string

steps:
  
- task: PowerShell@2
  displayName: Task in Template 2
  inputs:
    targetType: 'inline'
    script: |
      echo "${{parameters.input}}"

请尝试
Write Host“##vso[task.setvariable=type]$($settings.pipeline.type)”
@shaykibaramczyk,如果您将其延长一点,并解释为什么必须使用
$($variable)
语法(称为
子表达式语法
),这将是对这个问题的一个很好的回答。@FoxDeploy我将解释这是否对他有效,我不确定这是否是问题所在。@Shayki Abramczyk很好地抓住了,因为它不起作用,没有抓住这个。我已经更新了问题,以避免对实际问题的混淆。感谢${parameters.type}}不作为任务的输入,但是它们在模板中的PS脚本中使用时会显示出来,如echo${parameters.type}。此外,如果我使用类似模板的函数以及从主yml文件调用的输入变量/参数,主yml文件从repo读取json文件并将属性发送到模板?第一个注释:您将
$(type)
传递给参数
type
,因为模板参数是在运行时变量之前计算的,所以当您使用
${{parameters.type}
作为任务输入时,它将不起作用,它应该是纯文本。当您在脚本中使用该变量时,它将变成${parameters.type}=>
$(type)
,因为$(type)是一个运行时变量,所以可以在脚本中对其求值,所以您可以在脚本中回显其值。这就是您遇到的行为。如果您只想在步骤/任务之间共享变量,就足够了。如果您想使用变量作为下一步的条件,可以选中。不,它实际上在PS脚本中很好地显示了更新后的值。它只在一个步骤中被用作Unpthi好友的值时不起作用,请考虑接受它作为回答,以便更多的具有相似问题的成员可以很容易地从标记答案中找到有用的信息。只是提醒你