A Story of PowerShell Quoting Rules

This will be a fairly brief article that talks about single quotes vs. double quotes in the PowerShell automation language.

Single Quotes

In PowerShell, single quotes are commonly used to define string literals. If you want to include a single quote inside of a single-quoted string literal, then you simply put two single quotes next to each other. For example, let’s say that you were building a string of stock tickers.

'Some great stock tickers are: $AAPL $GOOG and $NVDA.'
RESULT: Some great stock tickers are: $AAPL $GOOG and $NVDA.

'Did you know that you can write a PowerShell sub-expression using this syntax? $(Get-Process -Name System)'
RESULT: Did you know that you can write a PowerShell sub-expression using this syntax? $(Get-Process -Name System)

As you can see from the above example, single quotes give you exactly what you put inside them. Pretty easy, right?

Double Quotes

In PowerShell, double quotes can also be used to define string literals, but there’s a catch. Double quoted strings in PowerShell switch on the string interpolation feature. Interpolation performs substitution for variables and even PowerShell sub-expressions.

Let’s start by taking a look at variables being interpolated:

"Some great stock tickers are: $AAPL $GOOG and $NVDA."
RESULT: Some great stock tickers are: and .

See what happened? Instead of treating the stock tickers as string literals, PowerShell tried to substitute the values of three different variables into the string. Because these variables didn’t exist in the PowerShell session, we got a really bizarre, unexpected result.

Now, let’s take a look at sub-expressions being interpolated in double-quoted strings.

"Did you know that you can write a PowerShell sub-expression using this syntax? $(Get-Process -Name System)"
RESULT: Did you know that you can write a PowerShell sub-expression using this syntax? System.Diagnostics.Process (System)

PowerShell Quoting Rules

See what happened there? Instead of actually showing the sub-expression syntax, the sub-expression was actually evaluated, and the resulting value was returned, and interpolated with the string. Now, sometimes you might want this, but if you don’t, you’ll want to make sure that you use single quoted strings.

Granted, there are other ways of working around this, like putting a backtick before the dollar sign, but at that point, you might as well just make it look prettier and use single quoted strings.

An Easier Approach

Instead of relying upon double-quoted strings for interpolation in PowerShell, I have a different recommendation: don’t use double-quoted strings at all! Instead, take a little bit of time to learn about .NET string formatting. You can think of .NET string formatting like “templates for string values,” but it’s a bit more powerful than just that.

This might look like a relatively daunting topic for beginners to PowerShell, but if you’re interested in taking on a new challenge, I recommend that you learn about this concept. In fact, PowerShell even offers native support for .NET string formatting, using the -f operator. Trust me, once you learn about .NET string formatting, you will feel much more empowered in writing PowerShell automation scripts!

Let’s take a simple look at how .NET string formatting works, using an example below.

### Define two custom PowerShell objects, each with a FirstName and LastName property
$Person1 = [PSCustomObject]@{ FirstName = 'Trevor'; LastName = 'Sullivan'; }
$Person2 = [PSCustomObject]@{ FirstName = 'Daniel'; LastName = 'Williams'; }

### Define a string template that uses each object
$String = 'Hello, my name is {0}, and my last name is {1}.'

### Perform .NET string formatting using the first person object
$String -f $Person1.FirstName, $Person1.LastName
RESULT: Hello, my name is Trevor, and my last name is Sullivan.

### Perform .NET string formatting using the second person object
$String -f $Person2.FirstName, $Person2.LastName
RESULT: Hello, my name is Daniel, and my last name is Williams.

As you can see from the above example, we created a template string, and then substituted values for the placeholders {0} and {1}. This is a very simplified and straightfoward use of .NET string formatting, but it also has much more powerful capabilities that you can explore yourself.

In the long run, using .NET string formatting should give you more predictable results, and avoid the unexpected results you can sometimes get with double-quoted string interpolation in PowerShell.

Conclusion

The bottom line is: use the quoting rules that work best for you, but before you make a decision, make sure that you understand how they work. If you start off by using single quotes for string literals, but later on say “ah-ha, I want this string to support interpolation!” then you can simply change the single quotes to double quotes. Better yet, you can use .NET string formatting, and solve your problems once and for all!