You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量查询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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:21:05