我有一个包含多个订阅和资源的 Azure 环境。我的要求是拥有一个功能,如果我传递用户名或 SPN 名称,它会为我提供该用户/spn 有权访问的所有 azure 资源(从管理组到 azure 资源)以及它的访问权限(读取器/数据读取器)等)。
主要问题是 - 我也想要 PIM 角色分配。有办法获取吗
探索的选项
除了迭代 50 个订阅、获取每个范围的角色分配然后比较对象 id 之外,还有其他更好的方法吗?
@Gjoshevski 分享了一个有用的命令,但您仍然需要循环遍历每个订阅以列出每个订阅的角色分配(如果您的租户中有多个订阅)。
以下 Azure CLI 命令即可完成此工作。
spID='<ObjectID here>' # ObjectID of an Applicatin or Service Principal
$tenantId='<TenantID here>'
az login --tenant 'Your Tenant'
$sub_ids=$(az account list --query id -o tsv)
foreach ($sub_id in $sub_ids) {
az account set --subscription $sub_id
"Subscription Name: $(az account show --query name)"
az role assignment list --all --assignee $spID --include-inherited --include-groups -o table
}
请注意,上面是 PowerShell 语法,但使用的是 Aure CLI 命令
这可能对您有帮助:
az role assignment list --all --assignee <Pricipal_ID>
您可以使用以下 Powershell 脚本获取多个订阅中服务主体名称的角色分配。
Connect-AzAccount
$tenantID = "yourTenantID"
$spn = "serviceprincipalname"
$user= Get-AzADUser -UserPrincipalName $spn
$subscriptions = Get-AzSubscription -TenantId $tenantID
#$subscriptions.Id
foreach ($subscription in $subscriptions) {
$set = Set-AzContext -Subscription $subscription
$set
$roleassignment= Get-AzRoleAssignment -ObjectId $user.Id
$roleassignment
}
输出:
参考:
首先定义要查询的用户的对象ID。连接到 Graph 和 Azure,以便以下所有命令都可以工作。系统上还必须安装 Azure CLI。
$PrincipalToQuery = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
Connect-Graph
Connect-AzAccount
然后你必须根据你想要查询的内容执行不同的代码。
此命令查询用户当前活动的 Entra ID 角色,因此包括所有静态分配的角色(除了当前通过 PIM 启用的角色)。该命令已经尊重通过角色可分配组来的角色。我们添加了两个附加属性以使输出更易于理解。
$AzureRoles = Get-MgBetaRoleManagementDirectoryTransitiveRoleAssignment -All -Filter "principalId eq '$PrincipalToQuery'" -ConsistencyLevel eventual
$Output = foreach ($AzureRole in $AzureRoles) {
$Principal = Get-MgBetaDirectoryObjectById -Ids $AzureRole.principalId
$AzureRole | Add-Member -NotePropertyName PrincipalDisplayName -NotePropertyValue $Principal.AdditionalProperties.displayName
$RoleDefinition = Get-MgBetaRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $AzureRole.roleDefinitionId
$AzureRole | Add-Member -NotePropertyName RoleDefinitionDisplayName -NotePropertyValue $RoleDefinition.DisplayName
$AzureRole
}
$Output | Select-Object RoleDefinitionDisplayName,DirectoryScopeId,PrincipalDisplayName,PrincipalId,RoleDefinitionId,AppScopeId | Out-GridView
此命令仅返回启用 PIM 的 Entra ID 角色。它不尊重通过角色可分配组来的角色,因此我们手动检查主体组并以这种方式构建我们的结果。根据我们是否查询用户或服务主体,我们需要使用
Get-MgBetaUserTransitiveMemberOf
或 Get-MgBetaServicePrincipalTransitiveMemberOf
。如上所述,我们添加了两个附加属性以使输出更容易理解。
$EligibleAzureRolesUnfiltered = Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleInstance -All
$PrincipalToQueryTransitiveMemberOf = Get-MgBetaUserTransitiveMemberOf -All -UserId $PrincipalToQuery
# $PrincipalToQueryTransitiveMemberOf = Get-MgBetaServicePrincipalTransitiveMemberOf -All -ServicePrincipalId $PrincipalToQuery
$EligibleAzureRoles = $EligibleAzureRolesUnfiltered | Where-Object {($_.PrincipalId -eq $PrincipalToQuery) -or ($_.PrincipalId -in $PrincipalToQueryTransitiveMemberOf.Id)}
$Output = foreach ($EligibleAzureRole in $EligibleAzureRoles) {
$Principal = Get-MgBetaDirectoryObjectById -Ids $EligibleAzureRole.principalId
$EligibleAzureRole | Add-Member -NotePropertyName PrincipalDisplayName -NotePropertyValue $Principal.AdditionalProperties.displayName
$RoleDefinition = Get-MgBetaRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $EligibleAzureRole.roleDefinitionId
$EligibleAzureRole | Add-Member -NotePropertyName RoleDefinitionDisplayName -NotePropertyValue $RoleDefinition.DisplayName
$EligibleAzureRole
}
$Output | Select-Object RoleDefinitionDisplayName,DirectoryScopeId,PrincipalDisplayName,PrincipalId,RoleDefinitionId,AppScopeId | Out-GridView
此命令查询用户当前活动的 Azure RBAC 角色,因此包括所有静态分配的角色(除了当前通过 PIM 启用的角色)。该命令已经尊重来自组的角色(它们不必是可分配的角色)。我们添加了一个附加查询,查询分配的范围是哪个订阅,因为默认情况下订阅仅按其 ID 返回。
Group-Object
的存在是为了不多次列出相同的分配(多个订阅可能会从更高层的 Management Group
继承角色分配)。
$Subscriptions = az account list --all | ConvertFrom-Json
$Output = foreach ($Subscription in $Subscriptions) {
# use Azure CLI because the Powershell equivalent 'Get-AzRoleAssignment -ExpandPrincipalGroups' does not expand groups for service principals
az role assignment list --all --assignee $PrincipalToQuery --include-groups --include-inherited --subscription $Subscription.id | ConvertFrom-Json
}
$GroupedOutput = $Output | Group-Object Id | ForEach-Object {$_.Group | Select-Object -First 1}
$GroupedOutput | ForEach-Object {
$IsInsideSubscription = ($_.scope.split('/'))[1] -eq 'subscriptions'
if ($IsInsideSubscription) {
$SubscriptionId = ($_.scope.split('/'))[2]
$SubscriptionName = (Get-AzSubscription -SubscriptionId $SubscriptionId).Name
$_ | Add-Member -NotePropertyName subscriptionName -NotePropertyValue $SubscriptionName
}
}
$GroupedOutput | Select-Object roleDefinitionName,scope,subscriptionName,principalName,principalId,principalType | Out-GridView
此命令仅返回启用 PIM 的 Azure RBAC 角色。它不尊重通过组来的角色(它们不必是可分配的角色),因此我们手动检查委托人的组并以这种方式构建我们的结果。根据我们是否查询用户或服务主体,我们需要使用
Get-MgBetaUserTransitiveMemberOf
或 Get-MgBetaServicePrincipalTransitiveMemberOf
。该命令返回的属性具有足够的可读性,因此我们可以直接输出其结果。 Group-Object
的存在是为了不多次列出相同的分配(多个订阅可能会从更高层的 Management Group
继承角色分配)。
$Subscriptions = az account list --all | ConvertFrom-Json
$PrincipalToQueryTransitiveMemberOf = Get-MgBetaUserTransitiveMemberOf -All -UserId $PrincipalToQuery
# $PrincipalToQueryTransitiveMemberOf = Get-MgBetaServicePrincipalTransitiveMemberOf -All -ServicePrincipalId $PrincipalToQuery
$Output = foreach ($Subscription in $Subscriptions) {
$EligibleRBACRolesUnfiltered = Get-AzRoleEligibilityScheduleInstance -Scope "/subscriptions/$($Subscription.id)"
$EligibleRBACRoles = $EligibleRBACRolesUnfiltered | Where-Object {($_.PrincipalId -eq $PrincipalToQuery) -or ($_.PrincipalId -in $PrincipalToQueryTransitiveMemberOf.Id)}
$EligibleRBACRoles
}
$Output | Group-Object Id | ForEach-Object {$_.Group | Select-Object -First 1 RoleDefinitionDisplayName,ScopeDisplayName,PrincipalDisplayName,ScopeId,PrincipalId,RoleDefinitionId} | Out-GridView