PowerShell String Interpolation: Embed Variables in Strings

One of the most common sources of confusion for new PowerShell users is why their variables sometimes expand inside a string and sometimes appear literally. The answer comes down to quote type. PowerShell string interpolation only happens inside double-quoted strings — single-quoted strings are always literal. This guide resolves that confusion permanently and covers every interpolation pattern you’ll encounter: simple variables, subexpressions, method calls, and multiline here-strings.
Quick Answer / TL;DR
Use double quotes for variable expansion, single quotes for literal text:
$name = 'Alice'
"Hello, $name" # Hello, Alice
'Hello, $name' # Hello, $name (literal)
Double Quotes vs Single Quotes
The rule is simple and absolute:
- Double quotes (
"...") — PowerShell scans for$and replaces variables with their values. Escape sequences like`n(newline) and`t(tab) are processed. - Single quotes (
'...') — Completely literal. No variable expansion, no escape processing. The only exception:''(two single quotes) represents a single quote character inside a single-quoted string.
$server = 'web01'
$port = 443
# Double quotes expand variables
"Connecting to $server on port $port"
# Single quotes are literal — great for regex, file paths, and static text
'C:\Users\Public\Documents\report.txt'
'Hello, $server' # Outputs: Hello, $server
Connecting to web01 on port 443
C:\Users\Public\Documents\report.txt
Hello, $server
Use single quotes as your default. Switch to double quotes only when you need a variable’s value in the string. This prevents accidental expansion of dollar signs that are part of your text (like SQL queries or monetary values).
Embedding Simple Variables
Variable names end at the first non-alphanumeric, non-underscore character, so most simple cases work without any extra syntax:
$prefix = 'APP'
$id = 42
$status = 'Running'
"$prefix-$id status: $status"
# Property access works directly on objects in double quotes
$date = Get-Date
"Today is $($date.DayOfWeek)" # Requires $() for property access
APP-42 status: Running
Today is Monday
Simple variable values expand directly. But accessing a property or calling a method requires the subexpression syntax — just wrapping the variable name in "$variable" does not automatically expose its properties.
Subexpression Syntax $()
Use $() to evaluate any expression inside a string. This is required for property access, method calls, array indexing, and complex expressions:
$files = Get-ChildItem C:\Logs
# Property access
"Found $($files.Count) log files"
# Array indexing
"First file: $($files[0].Name)"
# Arithmetic
"Double the count: $($files.Count * 2)"
# Cmdlet output inline
"Current user: $($env:USERNAME)"
Found 5 log files
First file: app.log
Double the count: 10
Current user: Alice
The $() subexpression can contain any valid PowerShell statement, including pipelines. However, for readability, keep subexpressions short. If the expression is complex, assign it to a variable first and then interpolate the variable.
Calling Methods Inside Strings
Method calls inside strings always require $():
$path = 'C:\Logs\App.log'
# Correct — method call wrapped in $()
"Filename: $([System.IO.Path]::GetFileName($path))"
# Uppercase a value inline
$name = 'alice'
"Username: $($name.ToUpper())"
# Date formatting
"Today: $(Get-Date -Format 'yyyy-MM-dd')"
Filename: App.log
Username: ALICE
Today: 2026-05-04
Multiline Strings with Here-Strings
Here-strings let you write multiline text without escaping quotes. The opening @" and closing "@ must each be on their own line, with "@ at the start of the line:
$server = 'web01'
$port = 80
# Expandable here-string (double-quote version)
$message = @"
Server: $server
Port: $port
Status: Running
"@
Write-Output $message
# Literal here-string (single-quote version — no expansion)
$query = @'
SELECT * FROM users WHERE name = '$username'
'@
Write-Output $query
Server: web01
Port: 80
Status: Running
SELECT * FROM users WHERE name = '$username'
Here-strings are invaluable for SQL queries, JSON templates, email bodies, and any multi-line text that would require messy escaping inside a regular string.
Escaping Special Characters
Inside double-quoted strings, use the backtick (`) as the escape character:
# Literal dollar sign — escape with backtick
"Price: `$49.99"
# Literal double quote inside double-quoted string
"She said `"hello`""
# Newline and tab
"Line1`nLine2`tTabbed"
# Literal backtick
"Path separator: ``"
Price: $49.99
She said "hello"
Line1
Line2 Tabbed
Path separator: `
Common Errors and Fixes
-
Variable not expanding — using single quotes:
'Hello $name'always outputs literal text regardless of what$nameholds. Switch to double quotes:"Hello $name". This is the number-one string interpolation mistake. -
Missing $() around method calls inside strings:
"Count: $files.Count"outputsCount: System.IO.FileInfo[].Count— the string representation of the object plus the literal text.Count. Wrap the expression:"Count: $($files.Count)".
Related Cmdlets / See Also
Wrapping Up
PowerShell string interpolation is controlled entirely by quote type: double quotes expand, single quotes don’t. Use $() for any expression beyond a simple variable name. Reach for here-strings when you have multiline content. Your next step: open a PowerShell session and test these patterns with your own variables to build the muscle memory.


