我正在为自动化 DevOps 管道创建 BICEP 资源,该管道可自动在 Microsoft EntraID 中创建应用程序注册。 BICEP 使用 Microsoft.Resources/deploymentScripts@2023-08-01 资源,该资源包含一段脚本,该脚本实际上调用 Azure 服务中的 powershell 脚本。基本实现来自Medium Automate App Registrations。
我修改了脚本,它还添加了一些应用程序角色,这些角色必须应用于(在本例中已经存在)应用程序(应用程序资源)。
目前我可以创建一个应用程序并使用例如秘密、API 权限等对其进行更新...返回 BadRequest 的唯一内容是应用程序角色的更新(AppRoles Resource)。 PowerShell示例中的具体模型我使用了微软自己给出的示例:AppRoles更新示例。在我的 powershell 中,我使用 Azure 请求调用,到目前为止,它仅响应 BadRequest,没有任何特定消息,仅显示“从 JSON 读取时发现意外的“PrimitiveValue”节点。预计会出现“StartArray”节点。” JSON 内容中的 App Roles 数组已经是 Microsoft 示例中的数组。
到目前为止,这是我最新的 POC 代码,它必须应用应用程序角色。我验证了应用程序注册存在。此外,配置的托管用户身份具有足够的访问权限:
foreach ($role in $roles) {
$splitRole = $role.Split(";")
$roleName = $splitRole[0]
$roleDescription = $splitRole[1]
Write-Host "RoleName: $($roleName)"
Write-Host "RoleDescription: $($roleDescription)"
$appRegistration = (Invoke-RestMethod -Method GET -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)")
Write-Host "App Registration: $($appRegistration)"
# Convert the JSON output to a PowerShell object
$appRoles = $appRegistration.appRoles
Write-Host "App Registration Roles: $($appRoles)"
# Extract and filter the app roles based on the DisplayName
$filteredRoles = $appRoles | Where-Object { $_.displayName -eq $roleName }
Write-Host "App Registration filtered roles: $($filteredRoles)"
if ($null -eq $filteredRoles) {
Write-Host "Role not found, create new role..."
$newAppRole = @{
appRoles = @(
@{
allowedMemberTypes = @(
"Application"
)
description = $($roleDescription)
displayName = $($roleName)
id = [Guid]::NewGuid()
isEnabled = $false
origin = "Application"
value = $($roleName)
})
}
Write-Host "Updated App Registration:"
Write-Host ($newAppRole.appRoles | Format-Table | Out-String)
Write-Host "Updated as JSON: $($newAppRole | ConvertTo-Json)"
try {
$createdAppRole = Invoke-RestMethod -Method PATCH -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)" -Body ($newAppRole | ConvertTo-Json)
Write-Host("App Registration patch result: $($createdAppRole)")
}
catch {
Write-Host "Failed to patch app roles:"
Write-Host ($_ | Format-Table | Out-String)
Write-Host "Other properties:"
Write-Host ($_.message)
Write-Host ($_.message | Format-Table | Out-String)
Write-Host ($_.Exception.Response)
Write-Host ($_.message)
Write-Host ($_.message)
$_.Exception.Response
Write-Host "Exception details: "
$e = $_.Exception
Write-Host ("`tMessage: " + $e.Message)
Write-Host ("`tStatus code: " + $e.Response.StatusCode)
Write-Host ("`tStatus description: " + $e.Response.StatusDescription)
}
}
}
在我的日志记录中,应用程序角色的 JSON 结果是:
{
"appRoles": [
{
"origin": "Application",
"id": "b1d3d9dd-1cf6-4e2e-bcf1-b586a2a62244",
"displayName": "app.customers",
"allowedMemberTypes": "Application",
"value": "app.customers",
"description": "System has access to all functionalities in customer module.",
"isEnabled": false
}
]
}
我不是一个很好的 PowerShell 开发人员,所以也许我做错了什么或忽略了一些愚蠢的事情;-) 希望有人可以提供帮助。
更新: 我发现另一个线程看起来与这个问题类似:Other thread。但是,该消息并不指向特定属性“allowedMemberTypes”。也不在innerException 中。 JSON Convert 不会从该属性创建数组。将尝试强制 ConvertTo-Json 获取真正的 JSON 数组表示形式。
更新: 我注意到我学到了有关 PowerShell 的新东西。 Mathias R. Jessen 关于 JSON 部门的说法是正确的。这解决了我的问题。非常感谢!
我注意到我学到了有关 PowerShell 的新东西。 Mathias R. Jessen 关于 JSON 部门的说法是正确的。这解决了我的问题。非常感谢!
新的 AppRole 脚本如下所示,其部门足够大以供将来使用:
$newAppRole = @{
appRoles = @(
@{
allowedMemberTypes = @(
"Application"
)
description = $($roleDescription)
displayName = $($roleName)
id = [Guid]::NewGuid()
isEnabled = $true
origin = "Application"
value = $($roleName)
})
}
Write-Host "Updated App Registration:"
Write-Host ($newAppRole.appRoles | Format-Table | Out-String)
try {
$createdAppRole = Invoke-RestMethod -Method PATCH -Headers $headers -Uri "https://graph.microsoft.com/beta/applications/$($app.id)" -Body ($newAppRole | ConvertTo-Json -Depth 5)
Write-Host("App Registration patch result: $($createdAppRole)")
}
catch {
Write-Host "Failed to patch app roles:"
Write-Host ($_ | Format-Table | Out-String)
}