You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure Pipeline中正确将JSON文件设为变量并用于后续任务

问题:Azure DevOps管道中JSON配置序列化与自定义类型转换失败

问题场景

有如下JSON配置文件myJson.json:

{
  "FirewallGroupsToEnable": [
    "Remote Event Log Management",
    "Windows Remote Management",
    "Performance Logs and Alerts",
    "File and Printer Sharing",
    "Windows Management Instrumentation (WMI)"
  ],
  "MemoryStartupBytes": "3GB"
}

需要将其序列化后设为Azure DevOps管道变量,供后续PowerShell脚本转换为自定义类使用。当前设置变量的任务代码:

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
        $Configs= Get-Content -Path $(Build.SourcesDirectory)\sources\myJson.json -Raw | ConvertFrom-Json
        Write-Host "##vso[task.setvariable variable=Configs]$Configs"

后续任务调用脚本myScript.ps1:

- task: PowerShell@2
  displayName: 'myTask'
  inputs:
    targetType: 'filePath'
    filePath: 'sources\myScript.ps1'
    pwsh: true

脚本中尝试转换自定义类(通过Using module .\Configs.psm1导入):

$env:Configs
[Configs]$envConfigs = ConvertFrom-Json -InputObject $env:Configs -ErrorAction Stop

自定义类Configs.psm1内容:

class Configs
{
    [string[]]$FirewallGroupsToEnable
    [string]$MemoryStartupBytes
}

运行时出现错误:

##[debug]Processed: ##vso[task.setvariable variable=Configs]@{FirewallGroupsToEnable=System.Object[]; MemoryStartupBytes=3GB}

@{FirewallGroupsToEnable=System.Object[]; MemoryStartupBytes=3GB}
Cannot convert the "@{FirewallGroupsToEnable=System.Object[]; MemoryStartupBytes=3GB}" value of type "System.String" to type "Configs".

尝试去掉ConvertFrom-Json直接设置原始JSON时,管道变量仅能获取到第一个大括号,序列化失败。

错误原因

当前方式将ConvertFrom-Json生成的PowerShell对象直接转为字符串,得到的是PowerShell的对象字面量表示(@{...}),并非标准JSON格式。后续ConvertFrom-Json无法将这种非JSON字符串解析为正确的属性结构,因此无法转换为自定义类。而直接设置原始JSON时未转义双引号,导致管道的##vso命令被截断,仅保留第一个大括号前的内容。

解决方案

正确的变量序列化方式

需要将配置序列化为标准JSON字符串,并转义双引号避免管道解析截断:

方式1:直接使用原始JSON内容

如果不需要修改配置对象,直接读取原始JSON并转义后设置变量:

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
        $jsonContent = Get-Content -Path $(Build.SourcesDirectory)\sources\myJson.json -Raw
        # 转义双引号,防止管道命令截断内容
        $escapedJson = $jsonContent -replace '"', '\"'
        Write-Host "##vso[task.setvariable variable=Configs]$escapedJson"

方式2:修改对象后重新序列化JSON

如果需要先修改配置对象,再序列化为标准JSON:

- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
        $configsObj = Get-Content -Path $(Build.SourcesDirectory)\sources\myJson.json -Raw | ConvertFrom-Json
        # 可在此修改对象属性,例如 $configsObj.MemoryStartupBytes = "4GB"
        # -Depth 10 确保多层嵌套结构完整序列化
        $jsonContent = $configsObj | ConvertTo-Json -Depth 10
        $escapedJson = $jsonContent -replace '"', '\"'
        Write-Host "##vso[task.setvariable variable=Configs]$escapedJson"

后续脚本中的正确转换方式:

# 先解析JSON为PowerShell对象,再转换为自定义类
$psConfig = ConvertFrom-Json -InputObject $env:Configs -ErrorAction Stop
[Configs]$envConfigs = $psConfig

更优替代方案:直接读取文件

如果任务在同一个Agent上运行,无需跨任务传递变量,直接在脚本中读取JSON文件更简单,避免序列化/反序列化的问题:

# myScript.ps1 中直接读取文件
$jsonFilePath = Join-Path -Path $PSScriptRoot -ChildPath "myJson.json"
$psConfig = Get-Content -Path $jsonFilePath -Raw | ConvertFrom-Json
[Configs]$envConfigs = $psConfig

验证结果

修改后,管道变量将存储完整的标准JSON字符串,后续脚本可正确解析为PowerShell对象,并顺利转换为自定义Configs类。

内容的提问来源于stack exchange,提问作者noobie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:50:46