How to Create a Variable with Multiple Values in PowerShell

To create a variable with multiple values in PowerShell, assign a comma-separated list to it. PowerShell turns the list into an array, and every value stays inside that one variable:

$cities = 'Austin', 'Denver', 'Seattle'

Arrays aren’t the only option, though. When each value needs a label, a hashtable fits better, and when each item is a whole record, an array of objects does.

In this tutorial, I’ll show you every common way to build a variable with multiple values, how to add and remove values, and the PowerShell 7 vs Windows PowerShell 5.1 differences I hit while testing.

Store multiple values in an array

An array is an ordered collection, and the comma is all it takes to make one. Each value gets an index that starts at 0, and negative indexes count back from the end:

$cities = 'Austin', 'Denver', 'Seattle', 'Boston'

"Type:   $($cities.GetType().FullName)"
"Count:  $($cities.Count)"
"First:  $($cities[0])"
"Last:   $($cities[-1])"
"Middle: $($cities[1..2] -join ', ')"

Output:

Type:   System.Object[]
Count:  4
First:  Austin
Last:   Boston
Middle: Denver, Seattle

Without a type, PowerShell creates a System.Object[] array, so the values can be strings, numbers or objects mixed together. Count tells you how many there are, which I cover more in getting the array length.

The range inside the brackets, [1..2], returns a slice of the array. To print it on one line, I joined it with -join, the same trick as converting an array to a string.

Indexing past the end doesn’t throw an error unless strict mode is on. $cities[10] simply returns nothing, so check Count before you rely on a position. For the full picture of indexing and loops, see my PowerShell arrays guide.

Create an array with @(), a range or a single item

The comma isn’t the only syntax. The array subexpression operator @() always returns an array, even when the command inside it returns zero or one object. That makes it the safe choice for command output:

$empty  = @()
$single = ,'Austin'
$found  = @(Get-ChildItem -Path C:\Windows -Filter 'notepad.exe')
$months = 1..12

"Empty array:     $($empty.Count) items"
"Single item:     $($single.Count) item, type $($single.GetType().Name)"
"@() of a search: $($found.Count) item, type $($found.GetType().Name)"
"Range 1..12:     $($months.Count) items, last is $($months[-1])"

Output:

Empty array:     0 items
Single item:     1 item, type Object[]
@() of a search: 1 item, type Object[]
Range 1..12:     12 items, last is 12

Here’s what each line does:

  • @() creates an empty array you can fill later.
  • ,'Austin' uses the unary comma to make a one-item array instead of a plain string.
  • @(Get-ChildItem ...) keeps the result an array, even though only one file matched.
  • 1..12 is the range operator. It builds every whole number from 1 to 12.

Without @(), that single notepad.exe match would be a FileInfo object, not an array. Code that expects .Count or an index then behaves differently when one result comes back instead of many.

Letter ranges work only in PowerShell