如何通过PowerShell或API查询Azure资源RBAC分配状态并导出CSV?
可以通过PowerShell和Azure REST API实现你的需求,以下是具体实现方式:
PowerShell可以分别获取Active状态(常规RBAC分配)和Eligible状态(Azure AD特权身份管理PIM的资格分配)的角色分配,支持递归/非递归查询并导出CSV。
非递归查询
1. Active状态分配
使用Get-AzRoleAssignment命令,通过-NoRecurse限制仅查询指定作用域:
# 替换为你的目标作用域(订阅/资源组/资源ID) $targetScope = "/subscriptions/xxx-xxx-xxx/resourceGroups/your-rg" # 获取非递归的Active状态分配 $activeNonRecursive = Get-AzRoleAssignment -Scope $targetScope -NoRecurse | Select-Object DisplayName, SignInName, RoleDefinitionName, Scope, @{Name="AssignmentState"; Expression={"Active"}} # 导出到CSV $activeNonRecursive | Export-Csv -Path "Active_RBAC_NonRecursive.csv" -NoTypeInformation
2. Eligible状态分配
Eligible分配属于PIM范畴,需要先安装Az.PrivilegedIdentityManagement模块,再查询:
# 安装PIM模块(首次运行需执行) Install-Module -Name Az.PrivilegedIdentityManagement -Force -AllowClobber $targetScope = "/subscriptions/xxx-xxx-xxx/resourceGroups/your-rg" # 获取非递归的Eligible状态分配 $eligibleNonRecursive = Get-AzADPrivilegedRoleAssignment -ProviderId "AzureResources" -ResourceId $targetScope -AssignmentState "Eligible" | Select-Object @{Name="DisplayName"; Expression={$_.PrincipalDisplayName}}, @{Name="SignInName"; Expression={$_.PrincipalEmail}}, @{Name="RoleDefinitionName"; Expression={$_.RoleDefinitionDisplayName}}, @{Name="Scope"; Expression={$_.ResourceId}}, @{Name="AssignmentState"; Expression={"Eligible"}} # 导出到CSV $eligibleNonRecursive | Export-Csv -Path "Eligible_RBAC_NonRecursive.csv" -NoTypeInformation
递归查询
1. Active状态分配
移除-NoRecurse参数,命令会自动递归查询指定作用域下的所有子资源:
$targetScope = "/subscriptions/xxx-xxx-xxx" # 获取递归的Active状态分配 $activeRecursive = Get-AzRoleAssignment -Scope $targetScope | Select-Object DisplayName, SignInName, RoleDefinitionName, Scope, @{Name="AssignmentState"; Expression={"Active"}} # 导出到CSV $activeRecursive | Export-Csv -Path "Active_RBAC_Recursive.csv" -NoTypeInformation
2. Eligible状态分配
PIM命令不直接支持递归,需手动遍历所有子资源并收集分配:
$targetScope = "/subscriptions/xxx-xxx-xxx" # 获取当前作用域及所有子资源的ID $allResources = Get-AzResource -ResourceId $targetScope -Recurse | Select-Object -ExpandProperty ResourceId $allResources += $targetScope # 包含根作用域 # 遍历收集Eligible分配 $eligibleRecursive = @() foreach ($resource in $allResources) { $assignments = Get-AzADPrivilegedRoleAssignment -ProviderId "AzureResources" -ResourceId $resource -AssignmentState "Eligible" | Select-Object @{Name="DisplayName"; Expression={$_.PrincipalDisplayName}}, @{Name="SignInName"; Expression={$_.PrincipalEmail}}, @{Name="RoleDefinitionName"; Expression={$_.RoleDefinitionDisplayName}}, @{Name="Scope"; Expression={$_.ResourceId}}, @{Name="AssignmentState"; Expression={"Eligible"}} $eligibleRecursive += $assignments } # 去重后导出到CSV $eligibleRecursive | Select-Object -Unique * | Export-Csv -Path "Eligible_RBAC_Recursive.csv" -NoTypeInformation
合并两种状态到单一CSV
如果需要将Active和Eligible分配合并导出:
$combinedAssignments = $activeRecursive + $eligibleRecursive $combinedAssignments | Export-Csv -Path "All_RBAC_Assignments.csv" -NoTypeInformation
通过API同样可以实现需求,需先获取Azure AD访问令牌,再调用对应接口。
非递归查询
1. Active状态分配
调用RBAC角色分配API,通过$filter=atScope()限制非递归:
GET https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01&$filter=atScope()
响应中所有条目均为Active状态,解析后提取字段并标记AssignmentState=Active,再导出CSV。
2. Eligible状态分配
调用PIM特权角色分配API,指定assignmentState=Eligible:
GET https://management.azure.com/{scope}/providers/Microsoft.Authorization/privilegedRoleAssignments?api-version=2018-07-01-preview&$filter=assignmentState+eq+'Eligible'
解析响应后标记AssignmentState=Eligible,导出CSV。
递归查询
1. Active状态分配
移除$filter=atScope(),API默认返回当前作用域及所有子作用域的分配:
GET https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01
2. Eligible状态分配
API不直接支持递归,需先调用资源列表API获取所有子资源ID,再逐个调用PIM接口收集分配,最后合并结果导出CSV。
示例:PowerShell调用API并导出
$accessToken = (Get-AzAccessToken).Token $headers = @{Authorization = "Bearer $accessToken"} $targetScope = "/subscriptions/xxx-xxx-xxx" # 获取递归Active分配并导出 $activeApiUrl = "https://management.azure.com$targetScope/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01" $activeResponse = Invoke-RestMethod -Uri $activeApiUrl -Headers $headers -Method Get $activeApiAssignments = $activeResponse.value | ForEach-Object { [PSCustomObject]@{ DisplayName = $_.properties.principalName SignInName = $_.properties.principalEmail RoleDefinitionName = $_.properties.roleDefinitionName Scope = $_.properties.scope AssignmentState = "Active" } } $activeApiAssignments | Export-Csv -Path "Active_RBAC_API_Recursive.csv" -NoTypeInformation
内容的提问来源于stack exchange,提问作者Bandz

