How to Convert an Array to a String in PowerShell

To convert an array to a string in PowerShell, use the -join operator with the separator you want between the items:

$servers = 'WEB01', 'WEB02', 'SQL01'
$servers -join ', '

Output:

WEB01, WEB02, SQL01

-join works with any separator, including none. It’s the method I’d reach for first, because it’s short, clear and works the same in every PowerShell version.

I ran every example in PowerShell 7.6 and Windows PowerShell 5.1. The only differences are the PowerShell 7 extras, which I point out.

Join with different separators

Put any text after -join. Put -join in front of the array instead, and the items are joined with nothing in between:

$servers = 'WEB01', 'WEB02', 'SQL01'

"Comma:     $($servers -join ',')"
"Semicolon: $($servers -join '; ')"
"Nothing:   $($servers -join '')"
"Unary:     $(-join $servers)"

Output:

Comma:     WEB01,WEB02,SQL01
Semicolon: WEB01; WEB02; SQL01
Nothing:   WEB01WEB02SQL01
Unary:     WEB01WEB02SQL01

To put each item on its own line, join with a line break:

$servers = 'WEB01', 'WEB02', 'SQL01'
$servers -join [Environment]::NewLine

Output:

WEB01
WEB02
SQL01

[Environment]::NewLine uses the right line ending for the system, which is carriage return plus line feed on Windows.

Cast the array or put it in quotes

Casting an array to [string], or putting it inside double quotes, also joins it. The separator comes from the $OFS variable, which is a space unless you change it:

$servers = 'WEB01', 'WEB02', 'SQL01'

"Cast:           $([string]$servers)"
"In quotes:      $servers"

$OFS = ' | '
"With `$OFS set: $servers"

Output:

Cast:           WEB01 WEB02 SQL01
In quotes:      WEB01 WEB02 SQL01
With $OFS set: WEB01 | WEB02 | SQL01

I’d avoid changing $OFS in scripts. It affects every array that’s turned into a string later on, which makes bugs hard to trace. Use -join where you need a separator.

The .NET Join method

[string]::Join() gives the same result as -join. You’ll see it in code copied from C#:

$servers = 'WEB01', 'WEB02', 'SQL01'
[string]::Join(', ', $servers)

Output:

WEB01, WEB02, SQL01

Use Join-String in PowerShell 7

PowerShell 7 added Join-String, which works in the pipeline and can quote items or add a prefix for you:

$servers = 'WEB01', 'WEB02', 'SQL01'

$servers | Join-String -Separator ', '
$servers | Join-String -Separator ', ' -SingleQuote
$servers | Join-String -Separator ', ' -OutputPrefix 'Servers: '

Output in PowerShell 7:

WEB01, WEB02, SQL01
'WEB01', 'WEB02', 'SQL01'
Servers: WEB01, WEB02, SQL01
PowerShell 7 Join-String with -Separator, -SingleQuote and -OutputPrefix
Join-String options (PowerShell 7)

Windows PowerShell 5.1 doesn’t have it and stops with “The term ‘Join-String’ is not recognized”. Stick with -join in scripts that run on both.

Quote each item in 5.1

For a quoted list, for example to build a SQL IN (...) clause, join with the closing quote, separator and opening quote, then add one quote at each end:

$servers = 'WEB01', 'WEB02', 'SQL01'

"'" + ($servers -join "', '") + "'"
'"' + ($servers -join '", "') + '"'

Output:

'WEB01', 'WEB02', 'SQL01'
"WEB01", "WEB02", "SQL01"

Convert an array of objects to a string

This is the most common surprise. Joining custom objects doesn’t give you their values. It gives you almost nothing:

$users = @(
    [pscustomobject]@{ Name = 'Maria Garcia'; City = 'Austin' }
    [pscustomobject]@{ Name = 'James Smith'; City = 'Dallas' }
)

$users -join ', '

Output:

,
PowerShell -join on an array of objects returns only the separator
Joining objects returns only the separator (PowerShell 7)

Each object turns into an empty string, so only the separator is left. Pick the property you want first, or build the text for each object yourself:

$users = @(
    [pscustomobject]@{ Name = 'Maria Garcia'; City = 'Austin' }
    [pscustomobject]@{ Name = 'James Smith'; City = 'Dallas' }
)

$users.Name -join ', '
($users | ForEach-Object { "$($_.Name) ($($_.City))" }) -join '; '

Output:

Maria Garcia, James Smith
Maria Garcia (Austin); James Smith (Dallas)

Get an array of strings from objects

When you need a list of strings rather than one string, Select-Object -ExpandProperty gives you exactly that:

$users = @(
    [pscustomobject]@{ Name = 'Maria Garcia'; City = 'Austin' }
    [pscustomobject]@{ Name = 'James Smith'; City = 'Dallas' }
)

$names = $users | Select-Object -ExpandProperty Name
"$($names.Count) names, each a $($names[0].GetType().Name)"

Output:

2 names, each a String

In PowerShell 7, Join-String -Property picks the property and joins in one step:

$users = @(
    [pscustomobject]@{ Name = 'Maria Garcia'; City = 'Austin' }
    [pscustomobject]@{ Name = 'James Smith'; City = 'Dallas' }
)

$users | Join-String -Property Name -Separator ', '

Output in PowerShell 7:

Maria Garcia, James Smith

More on getting values out of objects in PowerShell Select-Object.

Skip empty values

Empty strings and $null still get a separator, which leaves gaps. Filter them out first:

$cities = 'Austin', '', $null, 'Dallas'

"As is:     $($cities -join ', ')"
"Filtered:  $(($cities | Where-Object { $_ }) -join ', ')"