Modules/Public/InventoryModules/Management/AllSubscriptions.ps1

<#
.Synopsis
Inventory for ALL Azure Subscriptions in the tenant
 
.DESCRIPTION
This script enumerates every subscription the authenticated identity can access,
including empty subscriptions that contain zero resources. Cross-references the
Resource Graph to enrich each subscription with a resource count, resource group
count, and management group path.
Excel Sheet Name: All Subscriptions
 
.Link
https://github.com/thisismydemo/azure-scout/Modules/Public/InventoryModules/Management/AllSubscriptions.ps1
 
.COMPONENT
    This PowerShell Module is part of Azure Scout (AZSC).
 
.CATEGORY Management
 
.NOTES
Version: 1.0.0
First Release Date: February 24, 2026
Authors: AzureScout Contributors
 
#>


<######## Default Parameters. Don't modify this ########>

param($SCPath, $Sub, $Intag, $Resources, $Retirements, $Task, $File, $SmaResources, $TableStyle, $Unsupported)

If ($Task -eq 'Processing')
{
    <######### Insert the resource extraction here ########>

    # $Sub already contains ALL subscriptions retrieved at startup by Get-AZSCSubscriptions.
    # We enrich each subscription with resource/RG counts and MG path.

    # Build resource count and resource group count maps
    $resourceCountMap   = @{}
    $rgCountMap         = @{}

    if ($Resources) {
        foreach ($res in $Resources) {
            $subId = $res.subscriptionId
            if (-not $subId) { continue }
            if ($resourceCountMap.ContainsKey($subId)) { $resourceCountMap[$subId]++ } else { $resourceCountMap[$subId] = 1 }
        }
        # Resource groups appear in Resources as type 'microsoft.resources/subscriptions/resourcegroups'
        $rgResources = $Resources | Where-Object { $_.TYPE -eq 'microsoft.resources/subscriptions/resourcegroups' }
        foreach ($rg in $rgResources) {
            $subId = $rg.subscriptionId
            if (-not $subId) { continue }
            if ($rgCountMap.ContainsKey($subId)) { $rgCountMap[$subId]++ } else { $rgCountMap[$subId] = 1 }
        }
    }

    # Build MG ancestor path map via Resource Graph
    $mgPathMap = @{}
    try {
        $graphQuery = "resourcecontainers | where type == 'microsoft.resources/subscriptions' | extend mgChain = properties.managementGroupAncestorsChain | project subscriptionId, mgChain"
        $graphResult = Search-AzGraph -Query $graphQuery -First 1000 -Debug:$false -ErrorAction SilentlyContinue
        foreach ($row in $graphResult) {
            $subId = $row.subscriptionId
            if ($row.mgChain) {
                # mgChain is ordered from immediate parent → root; reverse for root → leaf display
                $chainItems = @($row.mgChain)
                [array]::Reverse($chainItems)
                $mgPath = ($chainItems | ForEach-Object { $_.displayName }) -join ' / '
            } else {
                $mgPath = 'Tenant Root'
            }
            $mgPathMap[$subId] = $mgPath
        }
    } catch {
        Write-Debug ("AllSubscriptions: MG path lookup failed: $_")
    }

    <######### Insert the resource Process here ########>

    if ($Sub) {
        $tmp = foreach ($1 in $Sub) {
            $ResUCount = 1
            $subId = $1.Id

            $resourceCount   = if ($resourceCountMap.ContainsKey($subId)) { $resourceCountMap[$subId] } else { 0 }
            $rgCount         = if ($rgCountMap.ContainsKey($subId))       { $rgCountMap[$subId] }       else { 0 }
            $mgPath          = if ($mgPathMap.ContainsKey($subId))        { $mgPathMap[$subId] }        else { 'Unknown' }

            $spendingLimit   = try { $1.SubscriptionPolicies.SpendingLimit } catch { 'N/A' }
            $quotaId         = try { $1.SubscriptionPolicies.QuotaId }       catch { 'N/A' }
            $authSource      = try { $1.AuthorizationSource }                catch { 'N/A' }

            $tagsDisplay = if ($1.Tags -and $1.Tags.Count -gt 0) {
                ($1.Tags.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join '; '
            } else { '' }

            $obj = @{
                'ID'                    = $subId;
                'Subscription Name'     = $1.Name;
                'Subscription ID'       = $subId;
                'State'                 = $1.State;
                'Tenant ID'             = $1.TenantId;
                'Management Group Path' = $mgPath;
                'Resource Groups Count' = $rgCount;
                'Resources Count'       = $resourceCount;
                'Spending Limit'        = $spendingLimit;
                'Quota ID'              = $quotaId;
                'Authorization Source'  = $authSource;
                'Tags'                  = $tagsDisplay;
                'Resource U'            = $ResUCount;
            }
            $obj
            if ($ResUCount -eq 1) { $ResUCount = 0 }
        }
        $tmp
    }
}

<######## Resource Excel Reporting Begins Here ########>

Else
{
    <######## $SmaResources.(RESOURCE FILE NAME) ##########>

    if ($SmaResources)
    {
        $TableName = ('AllSubsTable_' + (($SmaResources.'Resource U' | Measure-Object -Sum).Sum))

        $condEmptyRow  = New-ConditionalText -Text '0' -Range 'H:H' -ConditionalTextColor ([System.Drawing.Color]::OrangeRed) -BackgroundColor ([System.Drawing.Color]::White)
        $condDisabled  = New-ConditionalText -Text 'Disabled' -Range 'D:D' -ConditionalTextColor ([System.Drawing.Color]::Gray) -BackgroundColor ([System.Drawing.Color]::WhiteSmoke)
        $condWarned    = New-ConditionalText -Text 'Warned' -Range 'D:D' -ConditionalTextColor ([System.Drawing.Color]::DarkOrange) -BackgroundColor ([System.Drawing.Color]::LightYellow)

        $Style = New-ExcelStyle -HorizontalAlignment Left -AutoSize -NumberFormat '0'

        $Exc = New-Object System.Collections.Generic.List[System.Object]
        $Exc.Add('Subscription Name')
        $Exc.Add('Subscription ID')
        $Exc.Add('State')
        $Exc.Add('Tenant ID')
        $Exc.Add('Management Group Path')
        $Exc.Add('Resource Groups Count')
        $Exc.Add('Resources Count')
        $Exc.Add('Spending Limit')
        $Exc.Add('Quota ID')
        $Exc.Add('Authorization Source')
        $Exc.Add('Tags')
        $Exc.Add('Resource U')

        [PSCustomObject]$SmaResources |
        ForEach-Object { $_ } | Select-Object $Exc |
        Export-Excel -Path $File `
            -WorksheetName 'All Subscriptions' `
            -AutoSize `
            -MaxAutoSizeRows 100 `
            -TableName $TableName `
            -TableStyle $TableStyle `
            -Style $Style `
            -ConditionalText $condEmptyRow, $condDisabled, $condWarned
    }
}