Here's something that tripped me the other day in a Windows PowerShell script. Let's say that you have to variables $user and $machine, and want to print a string with the value of both of them separated by a colon (':').

You can obviously do it using string concatenation:

$user = 'tomasr'
$machine = 'arcano'

write ($user + ':' + $machine)

That works, but doesn't PowerShell support that nice string interpolation feature? Why, yes it does! So why don't we just rewrite it like this:

write "$user:$machine"

But wait! If you run that last line, all you get is the value of the $machine variable... where did $user go?

The answer is that the colon has a special meaning in PowerShell variable names: It's used to associate the variable with a specific scope or namespace. There are a few scopes defined by PowerShell, such as script and global; so for example a global variable might be named $global:var.

But haven't we also seen that syntax elsewhere? Sure, how about $env:PATH? Same thing; except here env isn't a scope by itself, but a PSDrive. So the part before the ':' can either be either an actual scope defined by PS or a PSDrive. Heck, you can even try something like "${c:autoexec.bat}" and watch the magic happen!

So the problem with our string interpolation is that when PowerShell sees "$user:$machine", it expects to find a scope/psdrive named 'user' and expects a variable name to follow the ':', but '$' isn't valid, and 'user' isn't a scope or a PSDrive either, which confuses PowerShell a bit. But since he's too much of a gentleman he just fixes it up as best as he can and ignores everything up to this point and just dumps $machine without complaining. Nice of him, but it can really trip you up if you don't expect it!

Can we avoid this? Yes, we can, by simply delimiting variable names exactly for PowerShell by using '{}', like this:

write "${user}:$machine"

Section 5.8 on page 141 of Bruce Payette's excellent Windows PowerShell in Action covers the topic of variables in PowerShell and gave me the clue to work around this issue.

Technorati tags:

Tomas Restrepo

Software developer located in Colombia.