Private/RoleManagement/Azure/Get-AzureScopeInfo.ps1

function Get-AzureScopeInfo {
    <#
    .SYNOPSIS
        Converts Azure scope to display information matching Entra portal format.
     
    .DESCRIPTION
        Parses Azure ARM scope strings and returns formatted display information
        that aligns with how roles are displayed in the Entra portal.
     
    .PARAMETER Scope
        The Azure ARM scope string (e.g., /subscriptions/xxx/resourceGroups/yyy).
     
    .EXAMPLE
        Get-AzureScopeInfo -Scope "/subscriptions/12345/resourceGroups/myRG"
         
        Returns scope information formatted for display.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Scope
    )
    
    if ($Scope -eq "/" -or $Scope -eq "") {
        return @{
            ResourceDisplay = "/"
            ScopeType       = "Tenant"
        }
    }
    
    # Parse management group scope
    if ($Scope -match "^/providers/Microsoft\.Management/managementGroups/([^/]+)$") {
        $mgName = $matches[1]
        
        # Check if this is the tenant root group (often matches tenant ID format)
        if ($mgName -match "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") {
            $displayName = "Tenant Root Group"
        }
        else {
            $displayName = $mgName
        }
        
        return @{
            ResourceDisplay = $displayName
            ScopeType       = "Management group"
        }
    }
    
    # Parse subscription-level scope
    if ($Scope -match "^/subscriptions/([^/]+)$") {
        $subscriptionId = $matches[1]
        try {
            $subscription = Get-AzSubscription -SubscriptionId $subscriptionId -ErrorAction SilentlyContinue
            $subscriptionName = if ($subscription) { $subscription.Name } else { $subscriptionId }
        }
        catch {
            $subscriptionName = $subscriptionId
        }
        
        return @{
            ResourceDisplay = $subscriptionName
            ScopeType       = "Subscription"
        }
    }
    
    # Parse resource group scope
    if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)$") {
        return @{
            ResourceDisplay = $matches[2]
            ScopeType       = "Resource Group"
        }
    }
    
    # Parse specific resource scope - handle complex resource paths
    if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/([^/]+)/([^/]+)/(.+)$") {
        $subscriptionId = $matches[1]
        $resourceGroupName = $matches[2]
        $resourceProviderNamespace = $matches[3]
        $resourceType = $matches[4]
        $resourcePath = $matches[5]
        
        # Handle nested resources (like storage account file shares)
        $pathSegments = $resourcePath.Split('/')
        
        # For storage accounts with nested resources like file shares
        if ($resourceProviderNamespace -eq 'Microsoft.Storage' -and $pathSegments.Count -gt 1) {
            $storageAccountName = $pathSegments[0]
            $nestedResourceType = $pathSegments[1] # e.g., "fileServices", "default", etc.
            $nestedResourceName = if ($pathSegments.Count -gt 2) { $pathSegments[-1] } else { $pathSegments[1] }
            
            # Special handling for file shares
            if ($nestedResourceType -eq 'fileServices' -and $pathSegments.Count -gt 3) {
                $fileShareName = $pathSegments[-1]
                return @{
                    ResourceDisplay = "$fileShareName ($storageAccountName)"
                    ScopeType       = "Fileshare"
                }
            }
            # General nested storage resource
            return @{
                ResourceDisplay = "$nestedResourceName ($storageAccountName)"
                ScopeType       = "Storage resource"
            }
        }
        
        # Extract the final resource name from potentially nested path
        $resourceName = $pathSegments[-1]
        
        # Format the resource type for display
        $displayResourceType = switch ($resourceProviderNamespace) {
            'Microsoft.Storage' { 
                switch ($resourceType) {
                    'storageAccounts' { 'Storage account' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Compute' {
                switch ($resourceType) {
                    'virtualMachines' { 'Virtual machine' }
                    'disks' { 'Disk' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Web' {
                switch ($resourceType) {
                    'sites' { 'App Service' }
                    'serverfarms' { 'App Service plan' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.KeyVault' {
                switch ($resourceType) {
                    'vaults' { 'Key vault' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Network' {
                switch ($resourceType) {
                    'virtualNetworks' { 'Virtual network' }
                    'networkSecurityGroups' { 'Network security group' }
                    'publicIPAddresses' { 'Public IP address' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Sql' {
                switch ($resourceType) {
                    'servers' { 'SQL server' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Authorization' {
                switch ($resourceType) {
                    'roleDefinitions' { 'Role definition' }
                    'policyDefinitions' { 'Policy definition' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.Resources' {
                switch ($resourceType) {
                    'resourceGroups' { 'Resource group' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            'Microsoft.DesktopVirtualization' {
                switch ($resourceType) {
                    'applicationgroups' { 'Application group' }
                    'hostpools' { 'Host pool' }
                    'workspaces' { 'Workspace' }
                    default { "$resourceProviderNamespace/$resourceType" }
                }
            }
            default { 
                # Format as readable text for common patterns
                if ($resourceType -eq 'clusters') { 'Cluster' }
                elseif ($resourceType -eq 'databases') { 'Database' }
                elseif ($resourceType -eq 'accounts') { 'Account' }
                else { "$resourceProviderNamespace/$resourceType" }
            }
        }
        
        return @{
            ResourceDisplay = $resourceName
            ScopeType       = $displayResourceType
        }
    }
    
    # Handle nested resource scopes (like SQL databases)
    if ($Scope -match "^/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/([^/]+)/.+$") {
        $resourceProviderNamespace = $matches[3]
        
        # Extract the last segment as resource name
        $segments = $Scope.Split('/')
        $resourceName = $segments[-1]
        
        return @{
            ResourceDisplay = $resourceName
            ScopeType       = $resourceProviderNamespace
        }
    }
    
    # Fallback for unknown scope format
    return @{
        ResourceDisplay = $Scope
        ScopeType       = "Unknown"
    }
}