5

This will surely be easy-goings for someone. When I reference an array item in a string, it is not producing the desired result. I expected the last statement to produce a string containing "abc", but it does not.

PS C:\src\powershell> $mylist = @("abc", "def")
PS C:\src\powershell> $mylist
abc
def
PS C:\src\powershell> $mylist[0]
abc
PS C:\src\powershell> $mylist[1]
def
PS C:\src\powershell> "$mylist[0]"
abc def[0]s
0

2 Answers 2

6

Note: While this answer covers many aspects of string interpolation in PowerShell, a more comprehensive treatment of that topic can be found in this answer.

When embedding variable references in double-quoted strings, only simple variable references can be embedded without enclosing the expression in the so-called subexpression operator, $(...):

PS> $mylist = @("abc", "def") # define an array

PS> "$mylist[0]" # WRONG: $mylist (the whole array) is expanded, and "[0]" is a literal.
abc def[0]

PS> "$($mylist[0])" # OK: $(...) ensures that the subscript is recognized.
abc

To be more precise, you can directly embed the following variable references in double-quoted strings / here-strings in order to have them expanded (interpolated):

  • a variable referenced by name only; e.g., "I'm $HOME."
  • a variable with a scope specifier; e.g., "I'm on a spiritual $env:PATH."

To disambiguate a variable name from subsequent characters, enclose it in {...}; e.g.,
"I'm ${HOME}:"
Note that without {...}, the final : would have been interpreted as part of the variable name, and would have caused an error.
Alternatively, you could escape the : as `: and, similarly, use `$ to escape (create a literal) $.

For everything else, including accessing an array variable's subscript or an object variable's property, you need the subexpression operator, $(...).
Note that $(...) allows you to embed entire command lines in a string; e.g.:

PS> "Today is $((Get-Date).ToString('d'))."
Today is 10/13/16.                         # en-US culture

Documentation note: Get-Help about_Quoting_Rules covers string interpolation, but, as of PSv5, not in-depth.


For alternatives to string interpolation (expansion) for building strings, see Ansgar Wiecher's answer.

Sign up to request clarification or add additional context in comments.

Comments

2

PowerShell doesn't recognize more complex variable constructs (e.g. index operations ($mylist[0]) or property/method access ($mylist.Count)) when expanding variables in strings. It will simply expand the variable and leave the rest of the string alone. Hence the expression "$mylist[0]" becomes "abc def[0]".

Basically you have three options to deal with this limitation:

Of course there are also more "exotic" approaches, like using the -join operator:

"-", $mylist[0], "-" -join ""

or replacement operations:

'-%x%-' -replace '%x%', $mylist[0]
'-%x%-'.Replace('%x%', $mylist[0])

but those already verge on obfuscation.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.