Private/Resolve-VMSkuRam.ps1

function Resolve-VMSkuRam {
    <#
    .SYNOPSIS
        Resolves a VM SKU name to its total physical RAM (MB), cached per location.

    .DESCRIPTION
        The memory utilisation counter '% Committed Bytes In Use' is derived as a proxy
        from the host metric 'Available Memory Bytes' and the VM's total RAM:
            committedPct = 100 - (AvailableBytes / TotalBytes * 100)
        Total RAM is not in the metric stream, so we look it up from the SKU catalogue
        via Get-AzComputeResourceSku. Results are cached per location for the process
        lifetime to avoid repeated catalogue pulls.

    .PARAMETER SkuName
        The VM size, e.g. 'Standard_D4as_v5'.

    .PARAMETER Location
        Azure region of the VM, e.g. 'westeurope'. Used to scope the SKU catalogue.

    .PARAMETER SkuCache
        Optional hashtable used as the cache (location -> @{ skuName -> memoryMB }).
        Defaults to a module-scoped script cache. Pass your own for testing/isolation.

    .OUTPUTS
        [double] total RAM in MB, or $null when the SKU is not found in the catalogue.
    #>

    [CmdletBinding()]
    [OutputType([double])]
    param(
        [Parameter(Mandatory)] [string] $SkuName,
        [Parameter(Mandatory)] [string] $Location,
        [hashtable] $SkuCache = $script:VMSkuRamCache,
        [object] $AzContext
    )

    if ($null -eq $SkuCache) {
        if ($null -eq $script:VMSkuRamCache) { $script:VMSkuRamCache = @{} }
        $SkuCache = $script:VMSkuRamCache
    }

    $loc = $Location.ToLowerInvariant()
    if (-not $SkuCache.ContainsKey($loc)) {
        $map = @{}
        $skuArgs = @{ Location = $loc; ErrorAction = 'Stop' }
        if ($AzContext) { $skuArgs['DefaultProfile'] = $AzContext }
        $skus = Get-AzComputeResourceSku @skuArgs |
            Where-Object { $_.ResourceType -eq 'virtualMachines' }
        foreach ($s in $skus) {
            $memCap = $s.Capabilities | Where-Object { $_.Name -eq 'MemoryGB' } | Select-Object -First 1
            if ($memCap) {
                $map[$s.Name] = [double]$memCap.Value * 1024.0  # GB -> MB
            }
        }
        $SkuCache[$loc] = $map
    }

    $locMap = $SkuCache[$loc]
    if ($locMap.ContainsKey($SkuName)) {
        return [double] $locMap[$SkuName]
    }
    return $null
}