Variables and string expansion appear on nearly every line of a PowerShell script.
Variables start with $ and are created on assignment: $name = 'Ada'. Spaces around = are fine. Names are case-insensitive. Values keep their .NET type: $count = 3 is an Int32, 3.5 a Double, 'x' a String, $true a Boolean; $null means nothing.
Strings come in two flavours:
- Double quotes expand variables:
"Hello $name". For anything more than a plain variable, such as a property or an expression, use a subexpression$( ):"Files: $($files.Count)". - Single quotes are literal:
'Cost: $5'.
The escape character is the backtick (` n ` newline, t `` tab), not the backslash, which is just a normal character, convenient for Windows paths.
PowerShell converts types automatically, and the left operand decides: '42' + 1 gives the string 421, while 1 + '42' gives 43. Cast explicitly with [int]'42'. Putting a type before a variable at assignment, [int]$age = '30', constrains it, and later assignments must also convert to int.
Environment variables live in the env: drive: $env:PATH, $env:HOME. Automatic variables include $PSVersionTable, $PID, $HOME, $true, $false and $null. When comparing with $null, put it on the left: $null -eq $x.
Example
$name = 'Ada'
$count = 3
"Hello $name, you have $count new messages" # expands variables
'Hello $name' # Hello $name (single quotes: literal)
"Total: $($count * 2)" # Total: 6 ($() for expressions)
"Tab:`tdone" # Tab: done (backtick escapes)
$count.GetType().Name # Int32
'42' + 1 # 421 (left operand is a string)
1 + '42' # 43
[int]'42' + 1 # 43
[int]$age = '30' # constrained to int
$age.GetType().Name # Int32
# $age = 'thirty' # error: cannot convert value "thirty" to type "System.Int32"
$null -eq $undefinedVariable # True
$env:HOME # /home/you (environment variable)Remember
- Double quotes expand $var and $(expr); single quotes are literal
- The left operand's type drives conversion: '42' + 1 is '421'
- Backtick is the escape character; $env:NAME reads environment variables
Watch out for
- Writing "Size: $file.Length" and getting the whole object followed by '.Length'; use $($file.Length).