Peter Core
Peter Core

Reputation: 303

Grab parameters from url and drop them to powershell variables

i have a powershell listener running on my windows-box. Code from Powershell-Gallery: https://www.powershellgallery.com/packages/HttpListener/1.0.2

The "Client" calls the listener with the following example url: With Powershell i do:

invoke-webrequest -Uri "http://127.0.0.1:8888/Test?id='1234'&param2='@@$$'&param3='This is a test!'"

I have no idea, how to drop the parameters from the url to variables with the same name in powershell. I need to bring the parameters to powershellvariables to simply echo them. this is my last missing part. The parameters are separated with & and parameternames are case-sensitive.

To be more detailed, the id from the url should be in a powershell-variable named $id with the value 1234. The Variables can contain spaces, special characters, numbers, alphas. They are case sensitive. The parametervalue could be "My Name is "Anna"! My Pets Name is 'Bello'. " with all the "dirty" Characters like '%$"!{[().

Can someone point me to the right way how to get this solved?

Upvotes: 0

Views: 2959

Answers (1)

Theo
Theo

Reputation: 61068

In a valid url, the $ characters should have been escaped to %24 The other 'dirty' character % in Url escaped form is %25 This means the example url is invalid and should be:

$url = "http://127.0.0.1:8888/Test?id='1234'&param2='@@%24%24'&param3='This is a test!'"

Then the following does work

$url = "http://127.0.0.1:8888/Test?id='1234'&param2='@@%24%24'&param3='This is a test!'"

if ($url -is [uri]) {
    $url = $url.ToString()
}
# test if the url has a query string
if ($url.IndexOf('?') -ge 0) {
    # get the part of the url after the question mark to get the query string
    $query = ($url -split '\?')[1]    
    # or use: $query = $url.Substring($url.IndexOf('?') + 1)

    # remove possible fragment part of the query string
    $query = $query.Split('#')[0]

    # detect variable names and their values in the query string
    foreach ($q in ($query -split '&')) {
        $kv = $($q + '=') -split '='
        $varName  = [uri]::UnescapeDataString($kv[0]).Trim()
        $varValue = [uri]::UnescapeDataString($kv[1])
        New-Variable -Name $varname -Value $varValue -Force
    }
}
else {
    Write-Warning "No query string found as part of the given URL"
}

Prove it by writing the newly created variables to the console

Write-Host "`$id = $id"
Write-Host "`$param2 = $param2"
Write-Host "`$param3 = $param3"

which in this example would print

$id = '1234'
$param2 = '@@$$'
$param3 = 'This is a test!'

However, I personally would not like to create variables like this, because of the risk of overwriting already existing ones. I think it would be better to store them in a hash like this:

# detect variable names and their values in the query string
# and store them in a Hashtable
$queryHash = @{}
foreach ($q in ($query -split '&')) {
    $kv = $($q + '=') -split '='
    $name = [uri]::UnescapeDataString($kv[0]).Trim()
    $queryHash[$name] = [uri]::UnescapeDataString($kv[1])
}
$queryHash

which outputs

Name                           Value
----                           -----
id                             '1234'
param2                         '@@$$'
param3                         'This is a test!'

Upvotes: 2

Related Questions