powershell array of strings is an ordered collection of string elements created with @() syntax and accessed via zero-based indices.
$fruit = @('Apples','Oranges','Bananas')
$fruit.Count # 3
$fruit[0] # Apples
$fruit[-1] # Bananas
Syntax Reference
The @() subexpression operator always produces an array, even for a single item. The comma separates elements. Use negative indices for offset from the end: $array[-1] returns the last element. Indexing beyond $array.Count - 1 returns $null without error.
# Create fixed array
$a = @('one','two')
# Access and modify
$a[0] = 'updated'
# Remove via filter (returns new array)
$a = $a -ne 'removed'
# Join elements
$a -join ', '
# Check membership
$fruit -eq 'Apples' # returns matching string or $null
$fruit -ne 'Oranges' # returns array without 'Oranges'
Rapid Reference Cheat Sheet
| Action | CLI Command | Key Flag/Operator | Impact / Result |
|---|---|---|---|
| Create fixed array | $a = @('one','two') |
@() |
Array of two strings; size fixed |
| Create empty array | $a = @() |
@() |
Count is 0; cannot add with += (creates new) |
| Access element | $a[0] |
Index integer | Returns first element (zero‑based) |
| Access last element | $a[-1] |
Negative index | Returns last element; supports -2, etc. |
| Add element (inefficient) | $a += 'new' |
+= |
Creates new array; reallocates memory |
| Filter matching strings | $a -eq 'target' |
-eq |
Returns matching strings (or null) |
| Exclude strings | $a -ne 'remove' |
-ne |
Returns array without matching |
| Join into single string | $a -join ',' |
-join |
Concatenates with delimiter |
| Embed array in string | "Value: $($a[1])" |
$() |
Subexpression expands element value |
| Iterate via pipeline | $a | ForEach-Object { $_ } |
Pipeline | |
Unwraps array element by element |
Advanced Implementation & Parameters
Index Tricks and Off‑by‑One
PowerShell arrays use zero‑based indexing. $a[$a.Count] returns $null. Negative indices beyond -$a.Count also return $null. The Count property is read-only; use $a.Length interchangeably.
$a = @('zero','one','two')
$a[5] # $null
$a[-5] # $null
$a[$a.Count] # $null
Write‑Output and Array Creation
When you assign the output of Write-Output to a variable, the array is unwrapped and re‑assembled as a new array. Use the unary comma operator to preserve a single‑element array: ,$element.
# Direct assignment retains structure
$data = @('a','b','c')
$data.GetType().IsArray # True
# Pipeline assignment can flatten nested arrays
$data2 = Write-Output @('a','b','c')
$data2.GetType().IsArray # True (single dimension)
Strongly‑Typed String Arrays
Default @() arrays are [Object[]]. For type checking and performance, declare [string[]]:
[string[]]$names = @('Alice','Bob')
$names[0] = 123 # InvalidOperationException
Error Resolution & Troubleshooting
| Error / Symptom | Root Cause | Remediation Command |
|---|---|---|
| Cannot index into a null array | Variable is $null, not an array |
|
"I have $a[2] apples" prints incorrectly |
String interpolation interprets $a then [2] as separate tokens |
|
| Array appears empty after pipeline filtering | Pipeline returns scalar $null when no match |
|
Get-Member shows element methods, not array methods |
Pipeline unwraps arrays; Get-Member sees each element |
|
Slow performance with += in loops |
Each += creates a new array and copies all elements |
|
Production‑Grade Implementation
Choosing Between Fixed Array and ArrayList
A fixed @() array is immutable in size. For dynamic collection building, use [System.Collections.ArrayList] or [System.Collections.Generic.List[string]] to avoid repeated allocations.
$list = [System.Collections.ArrayList]@()
$list.Add('entry1') > $null
$stringArray = [string[]]$list
Pipeline vs. ForEach Loop
The pipeline (| ForEach-Object) adds overhead per element. For large arrays (10,000+), use the foreach keyword or the .ForEach() method for 2–5× speed gain.
$largeArray.ForEach({ Process-Item $_ })
Security and Input Validation
When accepting string arrays from external sources, validate with parameter attributes to prevent injection or type confusion.
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string[]]$FilePaths
)
Frequently Asked Questions
What is the difference between @() and [string[]] when creating a powershell array of strings?
Answer: @() forces an array even for a single item; [string[]] casts to a strongly-typed string array.
@("item1") always produces an array (even with one element). [string[]]"item1" creates a single-element string array. Use @() for dynamic lists; [string[]] for type safety and performance. Example:
$arr1 = @("single")
$arr1.GetType().Name # Object[]
$arr2 = [string[]]("one","two")
$arr2.GetType().Name # String[]
When should I use the -split operator versus the .Split() method for a powershell array of strings?
Answer: Use -split when you need regex-based splitting; use .Split() for literal character splits and better performance.
-split supports regular expressions and automatically trims empty entries. .Split() is a .NET method that takes literal characters and is faster for simple splits. Example:
"a,b;c" -split ",|;" # -> a, b, c
("a,b,c").Split(',') # -> a, b, c
How do I fix the error “Cannot index into a null array” when working with a powershell array of strings?
Answer: Initialize the array with @() or check for $null before indexing.
This error occurs when a variable is $null and you attempt access like $null[0]. Avoid by declaring:
$myArray = @()
$myArray += "item"
# Or check before using
if ($myArray -ne $null) { $myArray[0] }
Does the powershell array of strings syntax @("a","b") work identically on Windows PowerShell and PowerShell Core on Linux?
Answer: Yes, basic array creation with @() and comma-separated strings is fully cross-platform on PowerShell 7+.
Syntax $arr = @("alpha","beta") produces an Object[] array on both platforms. However, .NET methods like .Split() may behave differently on Linux due to culture settings. For maximum portability, stick to PowerShell-native operators (-split, -join).
What is the fastest way to create a large powershell array of strings (100,000+ elements) with minimal overhead?
Answer: Use System.Collections.Generic.List[string] to avoid reallocation.
Avoid += which copies the whole array on each addition. Example:
$list = [System.Collections.Generic.List[string]]::new()
0..99999 | ForEach-Object { $list.Add("string$_$_") }
$array = $list.ToArray()
This method is ~10x faster than += for large data.

Command Line Expert & Software Engineer
Welcome! I’m Thomas Heinrich, a software engineer and system administrator with a deep passion for the Command Line Interface (CLI). With years of experience navigating the terminal, building backend architectures, and automating server deployments, I created this space to share practical, real-world terminal knowledge.
Whether you are a beginner taking your first steps in a Linux environment or a seasoned DevOps engineer looking to optimize your deployment scripts, you will find actionable solutions here. My goal is to help you ditch the mouse, speed up your workflow, and harness the full power of the command line.