批量查询Azure资源权限:获取多资源RG及账号跨层级权限
问题描述
我通常在Resource Group层级分配角色,但偶尔会收到诸如“我需要拥有和同事相同的权限来访问服务器A、B、C”的请求,因此这类脚本对后续扩展很有帮助。
我希望能批量查询多个Azure资源所属的Resource Group,并展示参考账号的访问权限,包括该权限是在Resource Group、Subscription还是Management Group层级。
期望输出格式:
Resource ResourceGroup Subs MG Scope Role(s) ServerA ResourceGroup1 Subscription1 MG1 Direct XXX-Role ServerB ResourceGroup2 Subscription2 MG1 Group XXX-Role ServerC ResourceGroup3 Subscription3 MG2 MgmtGroup XXX-Role
我目前有一个草稿脚本,但无法获取Management Group层级的权限,脚本如下:
#### PART ONE: Get RG of resources #### # Define the list of VM names $vmNames = @( "eusql41", "euapp41", "eusql81", "euapp81" ) # Retrieve all available contexts $contexts = Get-AzContext -ListAvailable # Initialize an array to hold the results $results = @() # Iterate over each context foreach ($context in $contexts) { # Set the current context Set-AzContext -Subscription $context.Subscription # Iterate over each VM name and retrieve its resource group foreach ($vmName in $vmNames) { # Query Azure for the VM $vm = Get-AzVM -Name $vmName -ErrorAction SilentlyContinue # Add VM details to the results array only if VM exists if ($vm -ne $null) { $results += New-Object PSObject -Property @{ VMName = $vm.Name ResourceGroup = $vm.ResourceGroupName Subscription = $context.Subscription Context = $context } } } } # Sort results by Resource Group and then VM Name $sortedResults = $results | Sort-Object ResourceGroup, VMName # Output the sorted results $sortedResults | Format-Table -Property VMName, ResourceGroup, Subscription #### PART TWO: Get Target's assignment #### # Iterate over the sorted results foreach ($result in $sortedResults) { $vmName = $($result.VMName) $resourceGroup = $($result.ResourceGroup) $subscriptionId = $result.Subscription $context = $result.Context Write-Host "Checking $vmName in $($SubscriptionId.Id)" -ForegroundColor Yellow # Set the context for the current iteration Set-AzContext -SubscriptionId $($SubscriptionId.Id) $current = Get-AzContext Write-Host "Now in $current" # Get role assignments for the user in the specific resource group $roleAssignments = Get-AzRoleAssignment -SignInName 'john@contoso.com' -ResourceGroupName $resourceGroup -ErrorAction SilentlyContinue # Check if there are any role assignments if ($roleAssignments) { foreach ($roleAssignment in $roleAssignments) { # Determine the access type based on ObjectType if ($roleAssignment.ObjectType -eq 'User') { $accessType = 'Direct' } elseif ($roleAssignment.ObjectType -eq 'Group') { $accessType = 'Group' } else { $accessType = 'Unknown' } # Prepare the output object $output = [PSCustomObject]@{ VMName = $vmName ResourceGroup = $resourceGroup Subscription = $subscriptionId AccessType = $accessType Role = $roleAssignment.RoleDefinitionName } # Output the details Write-Output $output } } else { Write-Output "No role assignments found for john@contoso.com in $resourceGroup" } }
解决方案
以下是修改后的完整脚本,可实现查询Resource Group、Subscription、Management Group三个层级的权限,并匹配你期望的输出格式:
# 配置参数 $targetUser = 'john@contoso.com' $vmNames = @("eusql41", "euapp41", "eusql81", "euapp81") # 初始化结果数组 $finalResults = @() # 步骤1:获取所有VM的资源组、订阅及对应管理组信息 $contexts = Get-AzContext -ListAvailable foreach ($context in $contexts) { Set-AzContext -Subscription $context.Subscription | Out-Null foreach ($vmName in $vmNames) { $vm = Get-AzVM -Name $vmName -ErrorAction SilentlyContinue if ($vm) { # 获取订阅所属的管理组信息 $subscription = Get-AzSubscription -SubscriptionId $context.Subscription.Id $mg = Get-AzManagementGroup -GroupId $subscription.ManagementGroupId -ErrorAction SilentlyContinue $finalResults += [PSCustomObject]@{ Resource = $vm.Name ResourceGroup = $vm.ResourceGroupName Subs = $context.Subscription.Name SubsId = $context.Subscription.Id MG = if ($mg) { $mg.DisplayName } else { "N/A" } MGId = if ($mg) { $mg.Name } else { "N/A" } } } } } # 去重并排序结果 $finalResults = $finalResults | Sort-Object Resource, ResourceGroup | Select-Object -Unique # 步骤2:查询目标用户在各层级的角色分配并格式化输出 foreach ($item in $finalResults) { $roleAssignments = @() # 查询Resource Group层级权限 $rgAssignments = Get-AzRoleAssignment -SignInName $targetUser -ResourceGroupName $item.ResourceGroup -SubscriptionId $item.SubsId -ErrorAction SilentlyContinue if ($rgAssignments) { $roleAssignments += $rgAssignments } # 查询Subscription层级权限 $subsAssignments = Get-AzRoleAssignment -SignInName $targetUser -SubscriptionId $item.SubsId -ErrorAction SilentlyContinue if ($subsAssignments) { $roleAssignments += $subsAssignments } # 查询Management Group层级权限 if ($item.MGId -ne "N/A") { $mgAssignments = Get-AzRoleAssignment -SignInName $targetUser -Scope "/providers/Microsoft.Management/managementGroups/$($item.MGId)" -ErrorAction SilentlyContinue if ($mgAssignments) { $roleAssignments += $mgAssignments } } # 处理权限结果并输出 if ($roleAssignments) { foreach ($ra in $roleAssignments) { # 判断权限所在层级 $scopeType = switch -Regex ($ra.Scope) { '/managementGroups/' { 'MgmtGroup' } "/subscriptions/$($item.SubsId)$" { 'Subscription' } "/subscriptions/$($item.SubsId)/resourceGroups/$($item.ResourceGroup)" { 'Direct' } default { 'Unknown' } } # 判断权限分配类型 $accessType = if ($ra.ObjectType -eq 'User') { 'Direct' } elseif ($ra.ObjectType -eq 'Group') { 'Group' } else { 'Unknown' } # 生成输出对象 [PSCustomObject]@{ Resource = $item.Resource ResourceGroup = $item.ResourceGroup Subs = $item.Subs MG = $item.MG Scope = $scopeType Role(s) = $ra.RoleDefinitionName } } } else { # 无权限时的默认输出 [PSCustomObject]@{ Resource = $item.Resource ResourceGroup = $item.ResourceGroup Subs = $item.Subs MG = $item.MG Scope = 'None' Role(s) = 'No permissions found' } } } | Format-Table -AutoSize Resource, ResourceGroup, Subs, MG, Scope, Role(s)
关键修改说明
- 新增管理组关联逻辑:通过
Get-AzSubscription获取订阅绑定的管理组ID,再用Get-AzManagementGroup拉取管理组名称,补全原脚本缺失的管理组信息。 - 全层级权限查询:分别从Resource Group、Subscription、Management Group三个维度查询角色分配,确保不遗漏任何权限来源。
- 精准层级判断:通过正则匹配角色分配的
Scope字段,准确识别权限所在的层级类型。 - 输出格式对齐:最终输出严格匹配你要求的列结构,去掉冗余字段,保留核心信息。
内容的提问来源于stack exchange,提问作者ynnaij
相关产品推荐
相关产品推荐

