Private/New-AzureUtilsResourceInventoryQuery.ps1

function New-AzureUtilsResourceInventoryQuery {
    <#
        .SYNOPSIS
            Builds the Resource Graph (KQL) query for a projected resource inventory.
        .DESCRIPTION
            Pure, side-effect-free. Wraps New-AzureUtilsResourceQuery (resource-group
            and name-contains filters) with an optional resource-type filter and a
            stable projection used by Get-AzureUtilsResourceInventory. Type values are
            escaped against query injection.
        .PARAMETER ResourceGroupName
            Restrict to these resource groups.
        .PARAMETER NameContains
            Keep only resources whose name contains this text.
        .PARAMETER ResourceType
            Restrict to these ARM resource types (e.g. 'microsoft.compute/virtualmachines').
        .OUTPUTS
            System.String (the KQL query)
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [string[]] $ResourceGroupName,
        [string]   $NameContains,
        [string[]] $ResourceType
    )

    # Escape a value for use inside a single-quoted KQL string literal.
    $escape = { param($value) ($value -replace '\\', '\\') -replace "'", "\'" }

    $clauses = [System.Collections.Generic.List[string]]::new()
    $clauses.Add((New-AzureUtilsResourceQuery -ResourceGroupName $ResourceGroupName -NameContains $NameContains))

    if ($ResourceType) {
        $quoted = ($ResourceType | ForEach-Object { "'$(& $escape $_)'" }) -join ', '
        $clauses.Add("| where type in~ ($quoted)")
    }

    $clauses.Add('| project id, name, type, resourceGroup, location, subscriptionId, kind, skuName = tostring(sku.name), tags')

    return ($clauses -join "`n")
}