Public/ConvertTo-QueryString.ps1
|
<# .SYNOPSIS Converts a hashtable to a URL query string. .DESCRIPTION The ConvertTo-QueryString function builds a query string such as 'a=1&b=x%20y' from a hashtable or ordered dictionary: - Keys and values are escaped with [Uri]::EscapeDataString (spaces become %20). - An ordered dictionary keeps its order; the keys of a plain hashtable are sorted, so the result is always the same. - Array values repeat the key: @{ id = 1, 2 } becomes 'id=1&id=2'. - $null values are left out. Booleans are written as 'true' and 'false', dates as ISO 8601 (round-trip 'o' format) and numbers with the invariant culture. An empty dictionary returns an empty string. The '?' is not included. .PARAMETER InputObject The hashtable or ordered dictionary of query parameters. .INPUTS System.Collections.IDictionary You can pipe a hashtable to ConvertTo-QueryString. .OUTPUTS System.String .EXAMPLE ConvertTo-QueryString -InputObject ([ordered]@{ jql = 'project = OPS'; maxResults = 50 }) Returns 'jql=project%20%3D%20OPS&maxResults=50'. .EXAMPLE $query = ConvertTo-QueryString @{ expand = 'body.storage', 'version'; limit = 25 } Invoke-RestMethod -Uri "https://example.com/wiki/rest/api/content?$query" Returns 'expand=body.storage&expand=version&limit=25' and uses it in a request. .NOTES Author: Nigel Tatschner Company: TheCodeSaiyan #> function ConvertTo-QueryString { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory, Position = 0, ValueFromPipeline, HelpMessage = 'The query parameters.')] [AllowEmptyCollection()] [System.Collections.IDictionary]$InputObject ) process { $keys = @($InputObject.Keys) if ($InputObject -isnot [System.Collections.Specialized.IOrderedDictionary]) { $keys = @($keys | Sort-Object -Property { [string]$_ }) } $pairs = New-Object System.Collections.Generic.List[string] foreach ($key in $keys) { $value = $InputObject[$key] if ($null -eq $value) { continue } $values = if ($value -is [System.Collections.IEnumerable] -and $value -isnot [string]) { @($value) } else { @(, $value) } foreach ($item in $values) { if ($null -eq $item) { continue } $text = if ($item -is [bool]) { $item.ToString().ToLowerInvariant() } elseif ($item -is [datetime] -or $item -is [System.DateTimeOffset]) { $item.ToString('o', [System.Globalization.CultureInfo]::InvariantCulture) } elseif ($item -is [System.IFormattable]) { $item.ToString($null, [System.Globalization.CultureInfo]::InvariantCulture) } else { [string]$item } $pairs.Add(('{0}={1}' -f [Uri]::EscapeDataString([string]$key), [Uri]::EscapeDataString($text))) } } return ($pairs -join '&') } } |