On this page

PowerShell arrays-Complete Guide

Published on September 6, 2026

Enrico Hochkoeppler Profile

By Enrico Hochkoeppler

Web Developer & TutoriaLibre Founder

PowerShell arrays are the core data structure for handling collections of values and objects. They support flexible creation, powerful indexing, rich operators, and integration with .NET collections, making them essential for any non-trivial script.

Arrays can store mixed types, be strongly typed for safety and performance, represent multidimensional data, and interact with the pipeline. Understanding these behaviors in depth removes many common bugs and performance issues and unlocks more expressive, reliable scripts. Microsoft Learn SS64 Command line reference


Conceptual model of arrays in PowerShell​

An array is a .NET System.Array (usually System.Object[] by default) that stores an ordered collection of items. Each item is accessed by a zero-based index. Microsoft Learn

Key properties:

Arrays can hold:


Creating and initializing arrays​

Comma-separated values​

The simplest way to create an array is to assign multiple values separated by commas:


$colors = "red", "green", "blue"

Explanation:
The comma operator tells PowerShell to create an array. $colors is now an Object[] with three elements: "red", "green", and "blue".

To inspect the type:


$colors.GetType().FullName

Explanation:
This prints System.Object[], confirming that $colors is an array of objects. Microsoft Learn

Single-item arrays with a leading comma​


$single = ,42

Explanation:
The leading comma forces PowerShell to create a one-element array containing 42, instead of treating 42 as a scalar. This is useful when a script must always work with an array, even if there is only one item. Microsoft Learn

Using the range operator​


$numbers = 1..5

Explanation:
The range operator 1..5 creates an array containing 1, 2, 3, 4, 5. This is convenient for loops, test data, and index-based operations. Microsoft Learn

Using the @() array subexpression operator​


$values = @(Get-Process)

Explanation:
@() is the array subexpression operator. It takes whatever the enclosed expression outputs and wraps it into an array, even if there are zero or one results. This guarantees that $values is always an array, which is critical when a command might return a single object or nothing. Microsoft Learn

Another example:


$maybeSingle = "hello"

$alwaysArray = @($maybeSingle)

Explanation:
Regardless of whether $maybeSingle is a single value or already an array, $alwaysArray is an array.

Explicit empty arrays​


$empty = @()

Explanation:
This creates an empty array with zero elements. It is often used as an accumulator that will be filled later.


Strongly typed arrays​

By default, arrays are Object[], which can hold any type. For stricter type safety and potential performance benefits, arrays can be strongly typed. Microsoft Learn

Declaring a strongly typed array​


[int[]]$intArray = 10, 20, 30

[string[]]$names = "Alice", "Bob", "Charlie"

Explanation:
[int[]] and [string[]] declare arrays that can only contain integers or strings. Assigning a value of the wrong type will cause a conversion attempt or an error.

Strongly typed arrays from command output​


[Diagnostics.Process[]]$procs = Get-Process

Explanation:
This creates an array of System.Diagnostics.Process objects. The type constraint ensures that only process objects are stored, which can help catch mistakes early. Microsoft Learn


Accessing and slicing arrays​

Basic indexing​


$colors = "red", "green", "blue"



$first  = $colors[0]

$second = $colors[1]

$third  = $colors[2]

Explanation:
Indexing starts at 0. Each index returns the corresponding element.

Negative indexing​


$last  = $colors[-1]

$secondLast = $colors[-2]

Explanation:
Negative indices count from the end of the array. -1 is the last element, -2 is the second-to-last, and so on.

Range access (slicing)​


$subset = $colors[0..1]

Explanation:
The range operator 0..1 selects indices 0 and 1. $subset becomes a new array containing "red" and "green".

Multiple index access​


$selected = $colors[0, 2]

Explanation:
This selects indices 0 and 2, returning a new array with "red" and "blue".


Array properties and length​

Count and Length​


$colors.Count

$colors.Length

Explanation:
For arrays, Count and Length both return the number of elements. They are interchangeable in this context. Active Directory Tools

Checking for empty arrays​


if (-not $colors -or $colors.Count -eq 0) {

    "Array is empty"

}

Explanation:
This pattern checks whether the array is $null or has zero elements, which is safer than assuming the variable is always an array.


Modifying arrays and performance considerations​

PowerShell arrays are fixed-size internally. Operations that appear to resize them actually create new arrays.

Appending elements with +=​


$colors = "red", "green", "blue"

$colors += "yellow"

Explanation:
+= creates a new array containing all original elements plus "yellow". For small arrays this is fine, but for large arrays or tight loops it can be slow because each append allocates a new array. SS64 Command line reference Active Directory Tools

Concatenating arrays​


$a = 1, 2, 3

$b = 4, 5

$c = $a + $b

Explanation:
The + operator concatenates arrays, producing a new array $c containing 1, 2, 3, 4, 5.

Replacing elements​


$colors[1] = "orange"

Explanation:
This updates the element at index 1 without changing the array size.


Removing elements from arrays​

Because arrays are fixed-size, removal is usually done by creating a new array that excludes certain elements.

Removing by value with Where-Object​


$numbers = 1, 2, 3, 4, 5

$withoutThree = $numbers | Where-Object { $_ -ne 3 }

Explanation:
Where-Object filters out elements that match a condition. Here, all elements except 3 are kept.

Removing by index​


$indexToRemove = 2

$numbers = 1, 2, 3, 4, 5

$withoutIndex = $numbers[0..($indexToRemove-1)] + $numbers[($indexToRemove+1)..($numbers.Count-1)]

Explanation:
This constructs a new array by concatenating the elements before and after the index to remove.

Removing null or empty values​


$values = 1, $null, 2, "", 3

$clean = $values | Where-Object { $_ -ne $null -and $_ -ne "" }

Explanation:
This pattern removes nulls and empty strings, which is common when cleaning data.


Looping through arrays​

foreach loop (language keyword)​


$colors = "red", "green", "blue"



foreach ($color in $colors) {

    "Color: $color"

}

Explanation:
The foreach keyword iterates over each element in the array. It is fast and very readable.

ForEach-Object in the pipeline​


$colors | ForEach-Object {

    "Color: $_"

}

Explanation:
This pipeline-based loop is useful when chaining multiple operations. $_ represents the current element.

for loop with index​


for ($i = 0; $i -lt $colors.Count; $i++) {

    "Index $i: $($colors[$i])"

}

Explanation:
The for loop provides explicit control over the index, which is useful when the index itself is needed or when iterating in non-linear patterns.


Array operators and membership tests​

Contains and not-contains​


$numbers = 1, 2, 3, 4, 5



$hasThree = $numbers -contains 3

$missingTen = $numbers -notcontains 10

Explanation:
-contains checks whether the array contains a value. -notcontains checks that it does not. These operators are optimized for membership tests.

in and notin​


$value = 3

$isInArray = $value -in $numbers

$isNotInArray = $value -notin $numbers

Explanation:
-in and -notin reverse the order: the value is on the left, the array on the right. This often reads more naturally.


Sorting and other array methods​

Arrays expose .NET methods that can be used directly.

Sorting arrays​


$numbers = 5, 3, 1, 4, 2

$numbers = $numbers | Sort-Object

Explanation:
Sort-Object sorts the array and returns a new array with elements in ascending order.

Alternatively, using the underlying .NET method:


[Array]::Sort($numbers)

Explanation:
This sorts the array in place. It is efficient but modifies the original array directly.

Reversing arrays​


[Array]::Reverse($numbers)

Explanation:
This reverses the order of elements in the array in place.

Cloning arrays​


$copy = $numbers.Clone()

Explanation:
Clone() creates a shallow copy of the array. The new array has the same elements but is a different array instance.


Multidimensional and jagged arrays​

PowerShell supports both jagged arrays (arrays of arrays) and true multidimensional arrays via .NET. Stack Overflow powershellfaqs.com

Jagged arrays (arrays of arrays)​


$jagged = @(

    @(1, 2, 3),

    @(4, 5, 6)

)

Explanation:
$jagged is an array with two elements, each of which is itself an array. This structure is flexible because inner arrays can have different lengths.

Accessing elements:


$firstRowFirstCol = $jagged[0][0]  # 1

$secondRowThirdCol = $jagged[1][2] # 6

Explanation:
The first index selects the row (inner array), and the second index selects the element within that row.

True multidimensional arrays​


$matrix = New-Object 'int[,]' 2,3

$matrix[0,0] = 1

$matrix[0,1] = 2

$matrix[0,2] = 3

$matrix[1,0] = 4

$matrix[1,1] = 5

$matrix[1,2] = 6

Explanation:
This creates a 2x3 matrix using a .NET multidimensional array. Indices are specified as [row, column].

Reading elements:


$matrix[1,2]  # 6

Explanation:
This accesses the element in row 1, column 2.

Choosing between jagged and multidimensional​


Arrays vs ArrayList vs generic List[T]​

For large or frequently modified collections, ArrayList or List[T] can be more efficient than plain arrays. SS64 Command line reference Active Directory Tools

Using ArrayList​


$alist = [System.Collections.ArrayList]::new()

$alist.Add("red")    > $null

$alist.Add("green")  > $null

$alist.Add("blue")   > $null

Explanation:
ArrayList is a resizable collection. Add() appends elements without recreating the entire collection, which is faster than repeated += on arrays for large data sets.

Using generic List[T]​


$list = [System.Collections.Generic.List[int]]::new()

$list.Add(1)

$list.Add(2)

$list.Add(3)

Explanation:
List[int] is a strongly typed, resizable list of integers. It offers good performance and type safety.

When to use which​


Common pitfalls and troubleshooting​

Scalar vs array confusion​


$value = Get-Item "C:\Windows"

$value.Count

Explanation:
If Get-Item returns a single object, $value is that object, not an array. .Count may not behave as expected. Using @() ensures an array:


$value = @(Get-Item "C:\Windows")

$value.Count

Explanation:
Now .Count reliably returns the number of items.

“Index was outside the bounds of the array”​


$numbers = 1, 2, 3

$numbers[5]

Explanation:
Accessing an index that does not exist throws an error. Always check Count or use safe patterns:


if ($index -ge 0 -and $index -lt $numbers.Count) {

    $numbers[$index]

}

Performance issues with +=​

Repeatedly appending to large arrays with += can be slow because each append creates a new array. For large or frequently modified collections, prefer ArrayList or List[T]. Active Directory Tools


Real-world array patterns​

Bulk server operations​


$servers = "srv01", "srv02", "srv03"



foreach ($server in $servers) {

    Test-Connection -ComputerName $server -Count 1 -Quiet

}

Explanation:
An array of server names is used to perform the same operation (ping) on each server.

Processing CSV data​


$users = Import-Csv -Path ".\users.csv"



foreach ($user in $users) {

    "User: $($user.Name), Department: $($user.Department)"

}

Explanation:
Import-Csv returns an array of objects. Each object is processed in turn, demonstrating how arrays naturally represent tabular data.

Filtering log entries​


$lines = Get-Content ".\app.log"

$errors = $lines | Where-Object { $_ -like "*ERROR*" }

Explanation:
The log file lines are stored in an array. Filtering produces a new array containing only error lines.


This guide covers the full range of array behavior in PowerShell: creation, typing, indexing, slicing, modification, operators, multidimensional structures, performance considerations, and real-world usage patterns, with explanations designed to be accessible even to beginners while remaining technically precise.

Found this helpful? Share the knowledge...

... or support this project to keep it alive!

Buy Me a Coffee

Previous

Scalar Variables

Next

Hash Tables