1

I have a powershell post request using Invoke-WebRequest but when I include the ? it thinks its all one variable, any way to escape this, here is my code

Invoke-WebRequest -UseBasicParsing -Method POST https://192.168.240.1:443/recive/$name?result=$sendback

It thinks name and everything after is a variable, I know this as I can see it all highlighted green in winddows terminal

mklement0
  • 382,024
  • 64
  • 607
  • 775
Jonathan Coletti
  • 448
  • 4
  • 13

2 Answers2

5

To complement jswanson's effective solution:

While using ` (a backtick, PowerShell's escape character) before the first post-variable-name character is always an option (in unquoted and double-quoted arguments), there is a direct way to delineate variable names in (implicit) expandable strings: Enclose the name in {...}, e.g. ${name}:

Write-Output https://192.168.240.1:443/receive/${name}?result=$sendback

While something like ${name}? is more cumbersome to type than $name`?, it has two distinct advantages:

  • It is more readable (visually distinct).
  • It works in all cases, whereas `-escaping the post-name character could accidentally turn that character into an escape sequence; e.g., say variable $foo should be followed by literal bar:
    • Write-Output $foo`bar - Broken, because the `b becomes a backspace character.
    • Write-Output ${foo}bar - OK, thanks to {...} enclosure

Optional reading: Why does PowerShell allow ? in identifiers (variable names)?

Most scripting and programming languages do not allow ? to be part of identifiers such as variable names, typically because ? is a metacharacter (a character with special meaning).

Even though ? in PowerShell has special meaning too, depending on context, ? in identifiers (variable names, function names, alias names, ...) are permitted.

While it is commendable on the one hand that PowerShell allows identifiers containing unusual characters, it would make sense to require {...} enclosure for such names[1] - as indeed is already required for other unusual characters, notably . and -:

# With ".", {...} is required.
PS> ${foo.bar} = 'bar'; ${foo.bar} # Without {...}, .bar would be a *property access*.
bar

Regrettably, use of ? does not require {...}:

# !! With "?", {...} is NOT required.
PS> $foo? = 'bar'; $foo?
bar

This behavior actively interferes with the PowerShell (Core) v7.1+ null-conditional operators, ?. and ?[].

For instance, say I want null-conditional access to a property of variable $var:

# FAILS, because "?" is considered part of the variable name.
Set-StrictMode -Version 3; $var = Get-Item foo*.txt; $var?.Length

The error message is InvalidOperation: The variable '$var?' cannot be retrieved because it has not been set.; that is, expression $var?.Length was interpreted as wanting to perform regular property access (.) on a variable named $var? - instead of the intended null-conditional access on variable $var.

{...} is required in this case even though the name $var itself does not contain special characters:

# OK, due to {...} - but this shouldn't be necessary
Set-StrictMode -Version 3; $var = Get-Item foo*.txt; ${var}?.Length

Given that this is both counterintuitive and cumbersome, GitHub proposal #11379 asks for this behavior to be changed. Even though it is technically a breaking change, analysis has revealed that real-world use of variable names ending in ? is vanishingly rare and that, conversely, such use was often erroneous, i.e. based on the expectation that a trailing ? is not a part of a variable name.


[1] Note that given that only variable names, not also functions, ..., support {...} enclosure, this would limit ?-containing names to variables.

mklement0
  • 382,024
  • 64
  • 607
  • 775
3

As @Abraham Zinala implies, The versatile Backtick (`) is an escape character in PowerShell. You can verify the effect by changing the placement of a Backtick in this line

echo https://192.168.240.1:443/recive/$name?result=$sendback

I believe what you are looking for is this

echo https://192.168.240.1:443/recive/$name`?result=$sendback
jswanson
  • 76
  • 1
  • 2