解决PowerShell中Azure AD服务主体权限替换而非累加的问题
解决权限被替换而非累加的问题
核心原因
两个函数执行时权限被替换,大概率是函数内部添加新权限前未保留已有权限(比如误执行了移除所有权限的操作,或是用了会覆盖现有权限的命令),或是没有对要添加的权限做去重校验,导致重复操作触发覆盖逻辑。
具体修改方案
我们可以调整Add-Two-Permissions函数,让它合并Add-Permissions中的Microsoft Graph角色权限,再统一添加所有需要的权限,同时确保只添加服务主体尚未拥有的权限。
步骤1:整合权限集合
先把两个函数的权限按类型区分整合:
# 来自Add-Permissions的Microsoft Graph应用权限(角色权限) $graphAppPermissions = @('User.Read.All','Group.Read.All','GroupMember.Read.All','GroupMember.ReadWrite.All','Directory.Read.All','AuditLog.Read.All') # Add-Two-Permissions中的Windows Azure Service Management API委派权限(示例为user_impersonation,替换为你的实际权限) $azureMgmtPermissions = @('user_impersonation') # Add-Two-Permissions中的Microsoft Graph委派权限(替换为你的实际权限) $graphDelegatedPermissions = @('示例范围权限1','示例范围权限2')
步骤2:修改函数实现累加逻辑
以下是调整后的Add-Two-Permissions函数(基于AzureAD模块,若使用Az模块可对应替换命令):
function Add-Two-Permissions { param( [Parameter(Mandatory=$true)] [string]$ServicePrincipalId # 服务主体的ObjectId或AppId ) # 定义所有需要添加的权限 $graphAppPermissions = @('User.Read.All','Group.Read.All','GroupMember.Read.All','GroupMember.ReadWrite.All','Directory.Read.All','AuditLog.Read.All') $azureMgmtResourceId = "797f4846-ba00-4fd7-ba43-dac1f8f63013" # Windows Azure Service Management API固定资源ID $azureMgmtPermissions = @('user_impersonation') $graphResourceId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph固定资源ID $graphDelegatedPermissions = @('示例范围权限1','示例范围权限2') # 获取目标服务主体 $sp = Get-AzureADServicePrincipal -Filter "ObjectId eq '$ServicePrincipalId' or AppId eq '$ServicePrincipalId'" if (-not $sp) { Write-Error "未找到指定的服务主体" return } # -------------------------- # 处理Microsoft Graph应用权限 # -------------------------- $graphSp = Get-AzureADServicePrincipal -Filter "AppId eq '$graphResourceId'" $existingAppRoles = Get-AzureADServicePrincipalAppRoleAssignment -ObjectId $sp.ObjectId | Where-Object {$_.ResourceId -eq $graphSp.ObjectId} $existingAppRoleIds = $existingAppRoles | ForEach-Object {$_.Id} foreach ($perm in $graphAppPermissions) { $targetRole = $graphSp.AppRoles | Where-Object {$_.Value -eq $perm} if ($targetRole -and $targetRole.Id -notin $existingAppRoleIds) { New-AzureADServicePrincipalAppRoleAssignment -ObjectId $sp.ObjectId -ResourceId $graphSp.ObjectId -Id $targetRole.Id -PrincipalId $sp.ObjectId Write-Host "已添加Microsoft Graph应用权限:$perm" } elseif ($targetRole -and $targetRole.Id -in $existingAppRoleIds) { Write-Host "服务主体已拥有Microsoft Graph应用权限:$perm,跳过" } else { Write-Warning "未找到Microsoft Graph应用权限:$perm" } } # -------------------------- # 处理Windows Azure Service Management API委派权限 # -------------------------- $azureMgmtSp = Get-AzureADServicePrincipal -Filter "AppId eq '$azureMgmtResourceId'" $existingOAuthGrants = Get-AzureADServicePrincipalOAuth2PermissionGrant -All $true | Where-Object {$_.ClientId -eq $sp.ObjectId} $existingScopes = $existingOAuthGrants | ForEach-Object {$_.Scope -split ' '} foreach ($perm in $azureMgmtPermissions) { $targetScope = $azureMgmtSp.OAuth2Permissions | Where-Object {$_.Value -eq $perm} if ($targetScope -and $perm -notin $existingScopes) { New-AzureADServicePrincipalOAuth2PermissionGrant -ClientId $sp.ObjectId -ResourceId $azureMgmtSp.ObjectId -Scope $perm -ConsentType "AllPrincipals" Write-Host "已添加Windows Azure Service Management API权限:$perm" } elseif ($targetScope -and $perm -in $existingScopes) { Write-Host "服务主体已拥有Windows Azure Service Management API权限:$perm,跳过" } else { Write-Warning "未找到Windows Azure Service Management API权限:$perm" } } # -------------------------- # 处理Microsoft Graph委派权限 # -------------------------- foreach ($perm in $graphDelegatedPermissions) { $targetScope = $graphSp.OAuth2Permissions | Where-Object {$_.Value -eq $perm} if ($targetScope -and $perm -notin $existingScopes) { New-AzureADServicePrincipalOAuth2PermissionGrant -ClientId $sp.ObjectId -ResourceId $graphSp.ObjectId -Scope $perm -ConsentType "AllPrincipals" Write-Host "已添加Microsoft Graph委派权限:$perm" } elseif ($targetScope -and $perm -in $existingScopes) { Write-Host "服务主体已拥有Microsoft Graph委派权限:$perm,跳过" } else { Write-Warning "未找到Microsoft Graph委派权限:$perm" } } }
关键说明
- 权限去重:先获取服务主体已有的应用角色分配和OAuth2权限授予,对比要添加的权限,只添加未存在的条目,避免重复或覆盖。
- 权限类型区分:应用权限(角色权限)用
New-AzureADServicePrincipalAppRoleAssignment添加,委派权限(范围权限)用New-AzureADServicePrincipalOAuth2PermissionGrant添加,两类逻辑分开处理。 - 固定资源ID:Windows Azure Service Management API和Microsoft Graph的资源ID是固定值,无需修改。
替代方案:修改原函数逻辑
如果不想重构Add-Two-Permissions,也可以给Add-Permissions加上上述的去重逻辑,然后先调用Add-Permissions再调用Add-Two-Permissions,这样两个函数执行时会自动累加权限。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

