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.