Private/Resolve-KB4Uri.ps1

function Resolve-KB4Uri
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string] $Path,

        [Parameter()]
        [hashtable] $Query = @{}
    )

    $context = Get-KB4ReportingContextInternal
    $baseUri = ([string] $context.BaseUri).TrimEnd('/')
    $relativePath = $Path.TrimStart('/')
    $builder = [System.UriBuilder]::new("$baseUri/$relativePath")

    if ($Query.Count -gt 0)
    {
        $pairs = [System.Collections.Generic.List[string]]::new()

        # Sort query keys to keep generated URIs deterministic for tests/logs.
        foreach ($key in ($Query.Keys | Sort-Object))
        {
            $value = $Query[$key]
            if ($null -eq $value)
            {
                continue
            }

            foreach ($item in @($value))
            {
                if ($null -eq $item)
                {
                    continue
                }

                if ($item -is [bool])
                {
                    $stringValue = $item.ToString().ToLowerInvariant()
                }
                else
                {
                    $stringValue = [string] $item
                }

                # Escape every key/value so IDs and filter values are URL-safe.
                $encodedKey = [System.Uri]::EscapeDataString([string] $key)
                $encodedValue = [System.Uri]::EscapeDataString($stringValue)
                $pairs.Add(('{0}={1}' -f $encodedKey, $encodedValue))
            }
        }

        $builder.Query = $pairs -join '&'
    }

    $builder.Uri
}