Private/New-ShellPhishParameterString.ps1

function New-ShellPhishParameterString {
    <#
    .SYNOPSIS
        Converts a hashtable of parameters into a URL query string including the API key.
    .DESCRIPTION
        Takes your custom query parameters (if any) and appends the API key,
        returning a properly URL-encoded string for use in Phish.net API calls.
    .PARAMETER QueryParams
        A hashtable of additional query parameters (e.g. @{ limit=10; order_by='name' }).
        If omitted or empty, only the API key will be included.
    .PARAMETER ApiKey
        Your Phish.net API key.
    .EXAMPLE
        PS C:\> New-ShellPhishParameterString -QueryParams @{ limit=5; direction='asc' } -ApiKey 'ABC123'
        limit=5&direction=asc&apikey=ABC123
    .EXAMPLE
        PS C:\> New-ShellPhishParameterString -ApiKey 'ABC123'
        apikey=ABC123
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)]
        [hashtable]$QueryParams = @{},

        [Parameter(Mandatory=$true)]
        [string]$ApiKey
    )

    # @() forces an array even when foreach produces a single item,
    # preventing scalar string concatenation on the += below.
    [array]$parts = @(foreach ($k in $QueryParams.Keys) {
        [uri]::EscapeDataString($k) + '=' +
        [uri]::EscapeDataString($QueryParams[$k])
    })

    if ($parts.Count -gt 0) {
        $parts += "apikey=$ApiKey"
        return $parts -join '&'
    }
    else {
        return "apikey=$ApiKey"
    }
}