Expanding variables and subexpressions in strings
In PowerShell, you can define a string with single or double quotes. There is a difference between these two methods. In a string with single quotes, variables and subexpressions are not expanded; while in a string with double quotes, variables and subexpressions are expanded.
Let's look at an example of variable expansion in a double-quoted string:
PowerCLI C:\> $Number = 3 PowerCLI C:\> "The number is: $Number" The number is: 3
In the preceding example, the string is defined with double quotes and the $Number
variable is expanded. Let's see what happens if you use single quotes:
PowerCLI C:\> $Number = 3 PowerCLI C:\> 'The number is: $Number' The number is: $Number
Using a single-quoted string, PowerShell doesn't expand the $Number
variable. Let's try to put the number of virtual CPUs of a virtual machine in a double-quoted string:
PowerCLI C:\> $vm = Get-VM -Name dc1 PowerCLI C:\> "The number of vCPU's of the vm is: $vm.NumCpu" The number of vCPU's of the vm is: dc1.NumCpu
The output is not what you intended. What happened? The $
in front of a variable name tells PowerShell to evaluate the variable. In the string used in the preceding example, $vm
evaluates the variable vm
but does not evaluate $vm.NumCpu
. To evaluate $vm.NumCpu
, you have to use another $
sign before and parentheses around the code that you want to evaluate, like so: $($vm.NumCpu)
. This is called a subexpression notation.
In the corrected example, you will get the number of virtual CPUs:
PowerCLI C:\> $vm = Get-VM -Name dc1 PowerCLI C:\> "The number of vCPU's of the vm is: $($vm.NumCpu)" The number of vCPU's of the vm is: 2
You can use subexpression evaluation to evaluate any PowerShell code. In the next example, you will use PowerShell to calculate the sum of 3 and 4:
PowerCLI C:\> "3 + 4 = $(3+4)" 3 + 4 = 7
Understanding what expands a string
A string will be expanded when it is assigned to a variable. It will not be reevaluated when the variable is used later. The following example shows this behavior:
PowerCLI C:\> $Number = 3 PowerCLI C:\> $String = "The number is: $Number" PowerCLI C:\> $String The number is: 3 PowerCLI C:\> $Number = 4 PowerCLI C:\> $String The number is: 3
As you can see, $String
is assigned before $Number
gets the value 4
. The $String
variable stays "The number is: 3"
.
Expanding a string when it is used
Want to know how to delay the expansion of the string until you use it? PowerShell has a predefined variable called $ExecutionContext
. You can use the InvokeCommand.ExpandString()
method of this variable to expand the string:
PowerCLI C:\> $Number = 3 PowerCLI C:\> $String = 'The number is: $Number' PowerCLI C:\> $ExecutionContext.InvokeCommand.ExpandString($String) The number is: 3 PowerCLI C:\> $Number = 4 PowerCLI C:\> $ExecutionContext.InvokeCommand.ExpandString($String) The number is: 4
The preceding example defines $String
as a single-quoted string, so $Number
is not expanded at the assignment of $String
. The $ExecutionContext.InvokeCommand.ExpandString($String)
command expands the string every time the command is executed.