Azure DevOps中向YAML模板传递JSON数组参数报错求助
问题排查:Azure DevOps流水线传递JSON数组参数解析错误
在Azure DevOps流水线中,需将JSON数组作为参数传递给另一个YAML模板,已对JSON数组做转义处理,但仍出现PowerShell参数列表缺失的解析错误,以下是相关信息及修复方案:
数组示例
{"arr":[{"priority":1,"ipAddress":"<IP Address>","description":"","name":"test","action":"Allow"},{"priority":1,"ipAddress":"<IP Address>","description":"","name":"test1","action":"Allow"}]}
错误信息
At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:30 char:338 + … dt-sem-use2" ipSecurityRestrictions=" [{"action":"Allow","descri … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:30 char:433 + … :"64.136.252.163/32","priority":1},{"action":"Allow","ipAddr … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:30 char:528 + … ","priority":1,"tag":"Default"},{"action":"Allow","ipAddr … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:30 char:641 + … priority":1000,"tag":"ServiceTag"},{"action":"Deny","ipAddr … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:38 char:366 + … dt-sem-use2" ipSecurityRestrictions=" [{"action":"Allow","descri … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:38 char:461 + … :"64.136.252.163/32","priority":1},{"action":"Allow","ipAddr … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:38 char:556 + … ","priority":1,"tag":"Default"},{"action":"Allow","ipAddr … + ~ Missing argument in parameter list. At D:\a\_temp\azureclitaskscript1689449876215_inlinescript.ps1:38 char:669 + … priority":1000,"tag":"ServiceTag"},{"action":"Deny","ipAddr … + ~ Missing argument in parameter list. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingArgument
现有YAML代码
- task: AzureCLI@2 name: 'AllowedIPs' displayName: 'GET allowed IPs' inputs: azureSubscription: ${{ parameters.ams_service_connection }} location: $(region) scriptType: pscore scriptLocation: inlineScript inlineScript: | $jsonResult = az deployment group create -g "<groupname>" --template-file '$(Pipeline.Workspace)/infrastructure/api/ip-restrictions.json' --parameters apiManagementName=<amsname> apiManagementRg=<amsrgname> | ConvertFrom-Json $ips = @($jsonResult.properties.outputs.ips.value) | ConvertTo-Json -Compress $val = $ips.replace('"', '\"") Write-Host "##vso[task.setvariable variable=ips;isoutput=true]"$val - template: deploy/arm-deploy.yml parameters: displayName: 'Configure ADT API IP restrictions' azureSubscription: ${{ parameters.adt_service_connection }} location: $(region) resourceGroupName: '<groupname>' force: true file: '$(Pipeline.Workspace)/infrastructure/api/adt-api-confog.json' parameters: name="<serviceprincipalname>" appServicePlanName="<serviceplanname>" apiRgName="<groupname>" ipSecurityRestrictions="$(AllowedIPs.ips)"
问题根源及修复方案
问题1:转义语法错误
原代码中$val = $ips.replace('"', '\"")存在语法错误,闭合引号不匹配;且PowerShell中双引号的正确转义方式是使用两个双引号,反斜杠是CMD的转义规则,不适用PowerShell环境。
问题2:参数解析拆分
当JSON变量被渲染到PowerShell脚本时,未被正确包裹的双引号会被PowerShell当作参数分隔符,导致JSON被拆分成多个无效参数。
修复方案:两种可选方式
方式一:使用Base64编码传递(推荐)
通过Base64编码完全避免转义和解析问题,步骤如下:
- 修改
AllowedIPs任务的脚本逻辑:
- task: AzureCLI@2 name: 'AllowedIPs' displayName: 'GET allowed IPs' inputs: azureSubscription: ${{ parameters.ams_service_connection }} location: $(region) scriptType: pscore scriptLocation: inlineScript inlineScript: | $jsonResult = az deployment group create -g "<groupname>" --template-file '$(Pipeline.Workspace)/infrastructure/api/ip-restrictions.json' --parameters apiManagementName=<amsname> apiManagementRg=<amsrgname> | ConvertFrom-Json $ips = @($jsonResult.properties.outputs.ips.value) | ConvertTo-Json -Compress # 将JSON转为Base64字符串,彻底避免转义问题 $val = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($ips)) Write-Host "##vso[task.setvariable variable=ips;isoutput=true]$val"
- 在
deploy/arm-deploy.yml中添加解码逻辑:
# 假设arm-deploy.yml中使用AzureCLI任务处理参数 - task: AzureCLI@2 inputs: azureSubscription: ${{ parameters.azureSubscription }} scriptType: pscore inlineScript: | # 解码Base64字符串为原始JSON $ipRestrictions = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("${{ parameters.ipSecurityRestrictions }}")) # 使用解码后的JSON,注意用单引号包裹避免解析问题 az webapp config set -g ${{ parameters.resourceGroupName }} -n ${{ parameters.name }} --ip-security-restrictions '$ipRestrictions'
方式二:修正转义并使用单引号包裹参数
如果不想用Base64,可调整转义和参数传递方式:
- 修正转义逻辑:
inlineScript: | $jsonResult = az deployment group create -g "<groupname>" --template-file '$(Pipeline.Workspace)/infrastructure/api/ip-restrictions.json' --parameters apiManagementName=<amsname> apiManagementRg=<amsrgname> | ConvertFrom-Json $ips = @($jsonResult.properties.outputs.ips.value) | ConvertTo-Json -Compress # PowerShell中双引号转义为两个双引号 $val = $ips.Replace('"', '""') Write-Host "##vso[task.setvariable variable=ips;isoutput=true]$val"
- 修改模板参数传递,用单引号包裹变量:
- template: deploy/arm-deploy.yml parameters: ... parameters: ... ipSecurityRestrictions='$(AllowedIPs.ips)'
内容的提问来源于stack exchange,提问作者user2439203
相关产品推荐
相关产品推荐

