I have a powershell script that runs az cli to add a scope to an existing app registration.
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"
If I run this directly from VS Code it works fine. However, when run from an Azure DevOps pipeline and AzurePowerShell@5 task, I get the following error:
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
Can anyone see which property of the api object it could be complaining about? Also why would this work from vs code terminal but not from Azure DevOps?
Following Jesse's advice, I ran az ad app show which gave:
{
"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
}
}
I saved this to a file named from-azure.json, then ran the following:
$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
The output was as follows:
@{acceptMappedClaims=; knownClientApplications=; oauth2PermissionScopes=amx.read; preAuthorizedApplications=; requestedAccessTokenVersion=2}
This seems incomplete?
My problem was a lack of understanding of how the az command works against Azure. It submits a http Patch request to the Azure api that presents the collection of oauth2PermissionScopes. If any of these scopes currently exist in an active state, they must first be disabled or an error will be raised.