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

Azure DevOps执行PowerShell脚本添加应用注册范围遇Schema错误

问题1:Azure DevOps流水线中更新应用注册Scope时的Schema错误

脚本内容

param (
    [Parameter(Mandatory = $true)]
    [string]$serviceAppRegAppId
)

$uuid = [guid]::NewGuid()
$api = @{
    acceptMappedClaims = $null
    knownClientApplications = @()
    oauth2PermissionScopes = @(
        @{
            adminConsentDescription = "admin description"
            adminConsentDisplayName = "admin name"
            isEnabled = $true
            id = "$uuid"
            type = "User"
            userConsentDescription = "user description"
            userConsentDisplayName = "user name"
            value = "amx.read"
        }
    )
    preAuthorizedApplications = @()
    requestedAccessTokenVersion = "2"
} | ConvertTo-Json

write-host "api=$api"

$appRegName = az ad app show --id $serviceAppRegAppId --query displayName
$appRegNameWithoutQuotes = $appRegName.Trim('"')

write-host "Going to add scope to app reg:$appRegNameWithoutQuotes"

# Update app registration with App ID URL and api object
az ad app update `
    --id $serviceAppRegAppId `
    --identifier-uris "api://$appRegNameWithoutQuotes" `
    --set api="$api"

错误信息

Going to add scope to app reg:apreg-gis-maps-prod-001
ERROR: Property api in payload has a value that does not match schema

问题解析与修复

核心原因

Azure CLI的--set参数无法直接解析带双引号转义的JSON字符串,而Azure DevOps的PowerShell任务对字符串转义的处理比本地VS Code终端更严格:

  1. ConvertTo-Json生成的JSON包含大量双引号,传入--set api="$api"时,会被截断为不完整的JSON结构
  2. 本地终端可能因PowerShell版本或环境差异意外兼容了错误的传参方式,但流水线环境不会

修复方案

方案1:用临时文件传递JSON(最可靠)

# 将JSON写入临时文件
$apiPath = Join-Path $env:TEMP "api-config.json"
$api | Out-File -FilePath $apiPath -Encoding utf8

# 使用@符号引用文件路径
az ad app update `
    --id $serviceAppRegAppId `
    --identifier-uris "api://$appRegNameWithoutQuotes" `
    --set api=@$apiPath

# 清理临时文件
Remove-Item $apiPath -Force

方案2:逐个添加属性(避免整段JSON)

如果仅需添加Scope,可直接用--add参数单独设置:

# 先设置标识符URI
az ad app update --id $serviceAppRegAppId --identifier-uris "api://$appRegNameWithoutQuotes"

# 添加Scope
az ad app update `
    --id $serviceAppRegAppId `
    --add api.oauth2PermissionScopes @{
        adminConsentDescription="admin description"
        adminConsentDisplayName="admin name"
        isEnabled=$true
        id="$uuid"
        type="User"
        userConsentDescription="user description"
        userConsentDisplayName="user name"
        value="amx.read"
    }

问题2:处理az ad app show输出时结果不完整

原始JSON文件(from-azure.json)

{
   "api":{
      "acceptMappedClaims":null,
      "knownClientApplications":[
         
      ],
      "oauth2PermissionScopes":[
         {
            "adminConsentDescription":"Read amx data",
            "adminConsentDisplayName":"Read amx data",
            "id":"ff9d6262-eb63-4c94-bdfa-0a33372c87bc",
            "isEnabled":true,
            "type":"Admin",
            "userConsentDescription":"Read amx data",
            "userConsentDisplayName":"Read amx data",
            "value":"amx.read"
         }
      ],
      "preAuthorizedApplications":[
         
      ],
      "requestedAccessTokenVersion":2
   }
}

原处理脚本

$json = Get-Content -Raw -Path "from-azure.json"
$apiConfig = $json | ConvertFrom-Json

# Expand the knownClientApplications property
$apiConfig.api.knownClientApplications = $apiConfig.api.knownClientApplications | Select-Object -ExpandProperty value
$apiConfig.api.oauth2PermissionScopes = $apiConfig.api.oauth2PermissionScopes | Select-Object -ExpandProperty value
$apiConfig.api.preAuthorizedApplications = $apiConfig.api.preAuthorizedApplications | Select-Object -ExpandProperty value

# Output the custom PowerShell object
$apiConfig

问题原因

你误用了Select-Object -ExpandProperty value:

  1. knownClientApplications和preAuthorizedApplications是空数组,没有value属性,执行后会被置为$null
  2. oauth2PermissionScopes中的对象没有名为value的属性(你要提取的是对象内部的value字段,而非数组元素的value属性)

修复后的脚本

如果需要提取oauth2PermissionScopes中的所有value值,应该用ForEach-Object遍历:

$json = Get-Content -Raw -Path "from-azure.json"
$apiConfig = $json | ConvertFrom-Json

# 提取oauth2PermissionScopes中的value字段
$apiConfig.api.oauth2PermissionScopes = $apiConfig.api.oauth2PermissionScopes | ForEach-Object { $_.value }

# 空数组无需处理,保持原样即可

# 输出完整结构
$apiConfig | ConvertTo-Json -Depth 3

正确输出

{
  "api": {
    "acceptMappedClaims": null,
    "knownClientApplications": [],
    "oauth2PermissionScopes": [
      "amx.read"
    ],
    "preAuthorizedApplications": [],
    "requestedAccessTokenVersion": 2
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:04:57