PoshBytes: Mastering Here-Strings in PowerShell
Learn PowerShell here-strings the fast way with practical examples. We cover expandable vs literal, JSON without escaping, regex patterns, file generation, inline scripts, and how to stop your text from fighting back.
This post is a companion for the video embedded below. Scroll down to see the code from the video.
Expandable vs. Literal Here-Strings
Setup
$who = 'The Doctor'
$today = Get-Date -Format 'yyyy-MM-dd'
Expandable: variables & subexpressions expand
$note = @"
Hello $who,
Today is $today.
File path: C:\Users\$who\Documents
Random number: $(Get-Random -Min 100 -Max 999)
"@
$note
Literal: NOTHING expands — great for regex and Windows paths
$literal = @'
Hello $who,
Today is $today.
Path: C:\Users\$who\Documents
Random number: $(Get-Random -Min 100 -Max 999)
'@
$literal
Regex, Paths, and Other Escape Gremlins
Work great for regex
$ssnPattern = @'
^\d{3}-\d{2}-\d{4}$
'@
"123-45-6789" -match $ssnPattern
"abc-def-ghij" -match $ssnPattern
Create config file
$config = @'
Root=C:\Program Files\Contoso\App
Data=C:\Data\Contoso
'@
$config
Generate Files (Configs, INI, Scripts) on the Fly
Auto-generated by PoshBytes
@"
Owner=$who
Date=$today
[Service]
Enabled=true
Port=8080
"@ | Set-Content -Path .\app.config
View the INI
Get-Content .\app.config
Multiline Script Blocks for Other Commands
Send script as here-string to PowerShell
$inline = @'
'From a here-string at ' + (Get-Date)
Get-Process | Select-Object -First 3 | Format-Table -AutoSize
'@
pwsh -NoProfile -Command $inline
Embed Quotes Freely (Because You Can)
Here-strings don’t care about quotes
$quoteParty = @"
He said, "PowerShell is great."
She replied, 'It gets even better with here-strings.'
And everyone clapped.
"@
$quoteParty
Pro Tip: The Finicky Terminator
Correct
$message = @"
Line 1
Line 2
"@
Incorrect — anything before the terminator will cause sadness
$message = @"
Line 1
Line 2
"@
Wrap Up
• @” ” expands variables; @’ ‘ is literal • Perfect for JSON, XML, INI, SQL, and regex patterns • Embed quotes without escaping • Terminator must be on its own line, unindented • Works great with pwsh -Command for inline scripts