- Courses
- đź’»Programming Languages
- 🪟PowerShell
- Scripting Fundamentals
- Variables & Types
- Arrays
On this page
PowerShell arrays-Complete Guide
Published on September 6, 2026
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:
- Ordered collection: Items keep insertion order.
- Zero-based indexing: First element is index
0. - Reference type: The variable holds a reference to the array object.
- Fixed-size under the hood: Operations that “resize” an array actually create a new array.
Arrays can hold:
- Simple values (strings, integers, booleans).
- Complex objects (processes, files, custom objects).
- Other arrays (jagged or multidimensional structures).
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​
- Jagged arrays: More flexible, easier to work with in pure PowerShell, can have rows of different lengths.
- Multidimensional arrays: More rigid, but closer to mathematical matrices and sometimes more efficient for fixed-size grids.
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​
- Array: Best for fixed-size collections, simple scripts, and when interacting with cmdlets that expect arrays.
- ArrayList: Good for dynamic collections when type safety is less critical.
- List[T]: Best for performance-critical code with known element types.
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!
Previous
Scalar Variables
Next
Hash Tables
-
Conceptual model of arrays in PowerShell
-
Creating and initializing arrays
- Comma-separated values
- Single-item arrays with a leading comma
- Using the range operator
- Using the @() array subexpression operator
- Explicit empty arrays
-
Strongly typed arrays
- Declaring a strongly typed array
- Strongly typed arrays from command output
-
Accessing and slicing arrays
- Basic indexing
- Negative indexing
- Range access (slicing)
- Multiple index access
-
Array properties and length
- Count and Length
- Checking for empty arrays
-
Modifying arrays and performance considerations
- Appending elements with +=
- Concatenating arrays
- Replacing elements
-
Removing elements from arrays
- Removing by value with Where-Object
- Removing by index
- Removing null or empty values
-
Looping through arrays
- foreach loop (language keyword)
- ForEach-Object in the pipeline
- for loop with index
-
Array operators and membership tests
- Contains and not-contains
- in and notin
-
Sorting and other array methods
- Sorting arrays
- Reversing arrays
- Cloning arrays
-
Multidimensional and jagged arrays
- Jagged arrays (arrays of arrays)
- True multidimensional arrays
- Choosing between jagged and multidimensional
-
Arrays vs ArrayList vs generic List[T]
- Using ArrayList
- Using generic List[T]
- When to use which
-
Common pitfalls and troubleshooting
- Scalar vs array confusion
- “Index was outside the bounds of the array”
- Performance issues with +=
-
Real-world array patterns
- Bulk server operations
- Processing CSV data
- Filtering log entries
