Arrays & Collections
Note
Learn how to store and work with multiple values in arrays, lists, and other collection types.
Overview
An array is a collection that stores multiple values in a single variable. Instead of having $file1, $file2, $file3, you can have one $files array that holds all three. Arrays are fundamental to PowerShell and you'll use them constantly when working with multiple items like files, users, or processes.
Basic Syntax
# Create an array
$colors = "Red", "Green", "Blue"
$numbers = 1, 2, 3, 4, 5
# Alternative syntax with @()
$fruits = @("Apple", "Banana", "Orange")
# Empty array
$emptyArray = @()
# Access elements by index (starts at 0)
$colors[0] # "Red"
$colors[1] # "Green"
$colors[-1] # "Blue" (last item)
Key Points
- Arrays use index numbers starting at 0 (first item is [0], not [1])
- Arrays in PowerShell are fixed size by default
- Use negative indexes to count from the end ([-1] is last item)
- Arrays can hold mixed types (numbers, strings, objects, etc.)
Creating Arrays
Simple Arrays
# Comma-separated values
$servers = "Server01", "Server02", "Server03"
# Range operator (..)
$numbers = 1..10 # Creates array: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
$letters = 'a'..'e' # Creates array: a, b, c, d, e
# Single item array (requires comma or @())
$singleItem = , "OnlyOne" # Array with one item
$singleItem = @("OnlyOne") # Same thing, clearer syntax
# Mixed types (possible but use carefully)
$mixed = 1, "two", $true, 3.14
Array from Command Output
# Store command results in an array
$files = Get-ChildItem -Path C:\Temp
$processes = Get-Process
$users = Get-ADUser -Filter *
# Force array even if result might be single item
$results = @(Get-Process -Name "notepad")
Accessing Array Elements
$colors = "Red", "Green", "Blue", "Yellow", "Purple"
# Single element
$colors[0] # "Red" (first)
$colors[2] # "Blue" (third)
$colors[-1] # "Purple" (last)
$colors[-2] # "Yellow" (second from end)
# Multiple elements (array slicing)
$colors[0,2,4] # "Red", "Blue", "Purple"
$colors[1..3] # "Green", "Blue", "Yellow" (range)
# Get array length
$colors.Count # 5
$colors.Length # 5 (same as Count)
Common Use Cases
Use Case 1: Looping Through Arrays
What it does: Process each item in an array
# ForEach loop
$servers = "Server01", "Server02", "Server03"
foreach ($server in $servers) {
Write-Output "Checking $server..."
Test-Connection -ComputerName $server -Count 1 -Quiet
}
# Pipeline ForEach
$numbers = 1..5
$numbers | ForEach-Object { $_ * 2 } # Doubles each number
Output:
Use Case 2: Filtering Arrays
What it does: Find specific items in an array
# Get all running processes
$processes = Get-Process
# Filter processes using more than 100MB of memory
$highMemoryProcesses = $processes | Where-Object { $_.WS -gt 100MB }
# Simple array filtering
$numbers = 1..20
$evenNumbers = $numbers | Where-Object { $_ % 2 -eq 0 }
Use Case 3: Adding and Removing Items
What it does: Modify array contents (workaround for fixed-size limitation)
# Standard arrays are FIXED SIZE - use += to "add" (actually creates new array)
$colors = "Red", "Green"
$colors += "Blue" # Now has 3 items (but created a new array)
$colors += "Yellow", "Purple" # Add multiple items
# To remove items, filter them out
$colors = $colors | Where-Object { $_ -ne "Green" } # Removes "Green"
# Better for frequent additions: Use ArrayList
$list = [System.Collections.ArrayList]@()
$list.Add("Red") | Out-Null
$list.Add("Green") | Out-Null
$list.Remove("Green") # Actually removes, doesn't create new array
Use Case 4: Working with Command Output
What it does: Ensure command results are always treated as arrays
# Problem: If command returns 1 item, it's not an array
$result = Get-Process -Name "powershell" # Might be single object or array
$result.Count # Might not work correctly if single object
# Solution: Force array with @()
$result = @(Get-Process -Name "powershell") # ALWAYS an array
$result.Count # Always works, returns 0, 1, or more
# This is especially useful when you need to loop or count
$services = @(Get-Service -Name "Spooler")
foreach ($service in $services) {
# Works whether 0, 1, or many services returned
Write-Output $service.Name
}
Why this matters: Many PowerShell commands return different types depending on result count:
- 0 items =
$null - 1 item = Single object (not an array)
- 2+ items = Array
Using @() ensures consistent behavior.
Use Case 5: Checking if Array is Empty or Has Items
What it does: Test whether an array contains any elements
$files = @(Get-ChildItem -Path C:\Temp -ErrorAction SilentlyContinue)
# Check if array is empty
if ($files.Count -eq 0) {
Write-Output "No files found"
}
# Check if array has items (truthy/falsy evaluation)
if ($files) {
Write-Output "Found $($files.Count) files"
# Process files
}
# Check for specific count
if ($files.Count -gt 10) {
Write-Output "More than 10 files found"
}
Working with Array Data
Sorting
$numbers = 5, 2, 8, 1, 9
$sorted = $numbers | Sort-Object # 1, 2, 5, 8, 9
$descending = $numbers | Sort-Object -Descending # 9, 8, 5, 2, 1
# Sort objects by property
$files = Get-ChildItem
$sortedBySize = $files | Sort-Object -Property Length
Selecting Properties
# Get just filenames (not full file objects)
$files = Get-ChildItem -Path C:\Temp
$fileNames = $files | Select-Object -ExpandProperty Name
# Get first/last items
$first3 = $files | Select-Object -First 3
$last2 = $files | Select-Object -Last 2
Measuring
$numbers = 1..100
# Get statistics
$stats = $numbers | Measure-Object -Average -Sum -Maximum -Minimum
$stats.Sum # 5050
$stats.Average # 50.5
$stats.Maximum # 100
# Count items
$fileCount = (Get-ChildItem).Count
Hash Tables (Associative Arrays)
# Hash table - stores key/value pairs
$user = @{
Name = "Raymond"
Age = 30
Department = "IT"
IsActive = $true
}
# Access values by key
$user["Name"] # "Raymond"
$user.Name # "Raymond" (dot notation)
# Add new key/value
$user["Email"] = "raymond@example.com"
$user.Phone = "555-1234"
# Remove a key
$user.Remove("Phone")
# Loop through hash table
foreach ($key in $user.Keys) {
Write-Output "$key : $($user[$key])"
}
Real-World Examples
Example: Processing Log Files
Scenario: Find and analyze log files from multiple directories
# Define directories to check
$logPaths = @(
"C:\Logs\Application"
"C:\Logs\System"
"C:\Logs\Security"
)
# Collect all .log files
$allLogs = @()
foreach ($path in $logPaths) {
$logs = Get-ChildItem -Path $path -Filter *.log -ErrorAction SilentlyContinue
$allLogs += $logs
}
# Find large log files (over 10MB)
$largeLogs = $allLogs | Where-Object { $_.Length -gt 10MB }
# Display results
Write-Output "Found $($largeLogs.Count) large log files:"
$largeLogs | Select-Object Name, @{Name="SizeMB";Expression={[math]::Round($_.Length/1MB,2)}}
Example: Managing Server List
Scenario: Keep track of server information with hash tables
# Create array of server info (array of hash tables)
$servers = @(
@{ Name = "SQL01"; Role = "Database"; IP = "192.168.1.10" }
@{ Name = "WEB01"; Role = "WebServer"; IP = "192.168.1.20" }
@{ Name = "FILE01"; Role = "FileServer"; IP = "192.168.1.30" }
)
# Find all database servers
$dbServers = $servers | Where-Object { $_.Role -eq "Database" }
# Test connectivity to each server
foreach ($server in $servers) {
$online = Test-Connection -ComputerName $server.IP -Count 1 -Quiet
$status = if ($online) { "Online" } else { "Offline" }
Write-Output "$($server.Name) ($($server.Role)): $status"
}
Explanation: We use an array to hold multiple servers, where each server is a hash table with properties. This makes it easy to filter, sort, and process server information.
ArrayList vs Array
# Standard Array (fixed size, slow to modify)
$array = @()
1..1000 | ForEach-Object { $array += $_ } # SLOW! Creates 1000 new arrays
# ArrayList (dynamic size, fast modifications)
$arrayList = [System.Collections.ArrayList]@()
1..1000 | ForEach-Object {
$arrayList.Add($_) | Out-Null # FAST! Just adds to existing list
}
# Generic List (even better, type-safe)
$list = [System.Collections.Generic.List[string]]::new()
$list.Add("Item1")
$list.Add("Item2")
$list.Remove("Item1")
Tips & Tricks
Force Array Creation
Empty Array Check
Quick Array Uniqueness
+= Creates New Array Every Time
Single Item Arrays
Related Topics
- Variables & Data Types - Understanding basic data storage
- The Pipeline - Using arrays with PowerShell's pipeline
- Object Manipulation - Filtering and transforming array contents
- Loops - Iterating through array elements