To concatenate strings in PowerShell, put the variables inside double quotes, or join them with the + operator. The -f format operator works too:
$first = 'Alice'
$last = 'Johnson'
"$first $last"
$first + ' ' + $last
'{0}, {1}' -f $last, $first
Output:
Alice Johnson
Alice Johnson
Johnson, Alice
All three give the same result here. The differences show up with numbers, dates, object properties and loops. I ran every example in PowerShell 7.6 and Windows PowerShell 5.1.
Concatenate a string and a number
With +, the value on the left decides what happens. A number on the left means addition, and a string on the left means joining text:
"1 + '2' = $(1 + '2')"
"'1' + 2 = $('1' + 2)"
"'Order ' + 1042 = $('Order ' + 1042)"
Output:
1 + '2' = 3
'1' + 2 = 12
'Order ' + 1042 = Order 1042

If you start with a string, PowerShell converts the number for you. Putting everything in double quotes avoids the question entirely: "Order $id".
Concatenate a string and a date
A string plus a date works, but a date plus a string doesn’t. Format the date yourself so you control how it looks:
$shipDate = [datetime]'2026-09-28 14:30'
'Report_' + $shipDate
'Report_' + $shipDate.ToString('yyyy-MM-dd') + '.csv'
try { $shipDate + '_Report' } catch { "Date first: $($_.Exception.GetType().Name)" }
Output:
Report_09/28/2026 14:30:00
Report_2026-09-28.csv
Date first: MethodException
PowerShell converts the date in the first line with a fixed format (month/day/year and 24-hour time), whatever your regional settings are. For file names, use .ToString('yyyy-MM-dd'), which sorts correctly.
Put object properties inside a string
Inside double quotes, PowerShell only expands the variable name, not the property after the dot. Wrap it in $():
$user = [pscustomobject]@{ Name = 'Alice Johnson'; City = 'Austin' }
"Wrong: $user.Name"
"Right: $($user.Name) from $($user.City)"
Output:
Wrong: @{Name=Alice Johnson; City=Austin}.Name
Right: Alice Johnson from Austin

The same goes for method calls and math, like "Total: $($price * $qty)". Microsoft explains the rules in about_Quoting_Rules.
Format numbers and currency with -f
For decimals and dollar amounts, the -f operator gives you control over the format:
$price = 1234.5
$qty = 3
"Plain: $price"
'Two places: {0:N2}' -f $price
'Currency: {0:C}' -f ($price * $qty)
Output:
Plain: 1234.5
Two places: 1,234.50
Currency: $3,703.50
{0:N2} adds thousands separators and two decimal places. {0:C} formats currency using the computer’s regional settings, which is dollars on a US system.
Join a list with a delimiter
-join concatenates every item in an array, with the delimiter between them:
$states = 'Texas', 'California', 'Florida'
"Joined: $($states -join ', ')"
$names = 'Washington', $null, 'Lincoln', '', 'Roosevelt'
"With blanks: $($names -join ' | ')"
"Blanks removed: $(($names | Where-Object { $_ }) -join ' | ')"
Output:
Joined: Texas, California, Florida
With blanks: Washington | | Lincoln | | Roosevelt
Blanks removed: Washington | Lincoln | Roosevelt
Empty and $null items aren’t skipped. They become empty spots between delimiters, so filter them out first. Microsoft covers the operator in about_Join.
Join-String in PowerShell 7
PowerShell 7 also has Join-String, which can add quotes around each item as it joins:
'Texas', 'California', 'Florida' | Join-String -Separator ', ' -SingleQuote
Output in PowerShell 7:
'Texas', 'California', 'Florida'
Join-String doesn’t exist in Windows PowerShell 5.1. There, use -join. To join with line breaks instead of commas, see how to add a new line in a string.
Concatenate strings inside a loop
Adding to a string with += in a loop is the most common way, and the slowest. I built a 20,000-item string three ways:
$count = 20000
$plus = Measure-Command {
$text = ''
foreach ($i in 1..$count) { $text += "Line $i," }
}
$builder = Measure-Command {
$sb = [System.Text.StringBuilder]::new()
foreach ($i in 1..$count) { [void]$sb.Append("Line $i,") }
$text = $sb.ToString()
}
$join = Measure-Command {
$text = $(foreach ($i in 1..$count) { "Line $i" }) -join ','
}
'+= in a loop: {0,6:N0} ms' -f $plus.TotalMilliseconds
'StringBuilder: {0,6:N0} ms' -f $builder.TotalMilliseconds
'-join at end: {0,6:N0} ms' -f $join.TotalMilliseconds
Output in PowerShell 7 (your times will differ):
+= in a loop: 727 ms
StringBuilder: 130 ms
-join at end: 23 ms
Output in Windows PowerShell 5.1:
+= in a loop: 2,069 ms
StringBuilder: 26 ms
-join at end: 33 ms

Each += copies the whole string, so the time grows quickly with the number of items. For a few dozen items, it doesn’t matter. For thousands, collect the items and -join them once, or use a StringBuilder.
Frequently Asked Questions
How do I concatenate strings in PowerShell?
Use double quotes, like "$first $last", or the + operator: $first + ' ' + $last. For lists, use $items -join ', '.
How do I concatenate a string and a number in PowerShell?
Put the string first, like 'Order ' + 1042, or use double quotes: "Order $id". A number first means addition.
Why does “$user.Name” print the whole object?
Double quotes only expand the variable, not the property. Use "$($user.Name)" to expand the property.
Does -join skip empty values in PowerShell?
No. $null and empty strings become empty spots between delimiters. Filter them first with Where-Object { $_ }.
What’s the fastest way to concatenate strings in a loop?
Collect the pieces and use -join once, or use a System.Text.StringBuilder. Using += in a large loop is much slower.
If you’re building strings, these guides help too:
- Add a new line in a string
- Split a string in PowerShell
- Convert an array to a string
- Format dates in PowerShell
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.