Martin Brandl's helpful answer bypasses your problem with a solution that is preferable anyway (no need for Write-Output
a.k.a echo
).
This answer explains the problem with your approach.
tl;dr
Use double quotes:
echo "$($var):123:zzz" > test.txt
Simplified (no need for echo
):
"$($var):123:zzz" > test.txt
Simplest (note the {}
, which are needed to disambiguate the variable name):
"${var}:123:zzz" > test.txt
"$var`:123:zzz" > test.txt
would work too (escaping the :
)
Your specific problem is that $($var):123:zzz
is parsed as 2 arguments, due to not being enclosed in "
.
In other words: The following 2 statements are equivalent:
echo $($var):123:zzz
echo $($var) :123:zzz
Both yield the following (wether in the console or when redirected to a file), because Write-Output
(that echo
is an alias for) writes its (stringified) arguments separated by a line break:
abcd
:123:zzz
Since you're passing $($var):123:zzz
as an argument to the echo
(Write-Output
) command, it is parsed in argument mode.
In argument mode, an unquoted subexpression-operator expression such as $($var)
at the start of a token is always treated as a separate argument, even if followed directly by more characters.
This answer of mine has more information about how PowerShell parses unquoted tokens in argument mode.
By contrast, double-quoting (enclosing the token in "..."
) ensures parsing as a single argument (though note that the subexpression will then be stringified first).
Thus, this command would work:
echo "$($var):123:zzz" > test.txt
Or, more simply, given that PowerShell outputs an expression's result by default (Write-Output
is usually not needed):
"$($var):123:zzz" > test.txt
Note that while double-quoted strings are used in both commands, the latter command is technically parsed in expression mode (which is PowerShell's other, programming language-like parsing mode), because the command line starts with a "
.