The range operator (..) generates an ordered array of contiguous integers between a start and end boundary, inclusive. Combined with foreach or ForEach-Object, numeric ranges provide a clean, declarative alternative to classic index-based for loops for sequential iterations, batch operations, countdown routines, and more.
The Range Operator (..)
Syntax: <start>..<end>
1..101
2
3
4
5
6
7
8
9
10The result is a genuine array, so it supports .Count, indexing, and piping just like any other array.
(1..10).Count10Ascending, Negative, and Descending Ranges
PowerShell automatically determines whether to increment or decrement based on the boundary values.
1..5
-3..2
10..11
2
3
4
5
-3
-2
-1
0
1
2
10
9
8
7
6
5
4
3
2
1To verify the underlying .NET type generated by a range expression:
(1..5).GetType().FullName
(1..5)[0].GetType().FullNameSystem.Object[]
System.Int32Looping Through Numeric Ranges
You can iterate across a range using either the foreach statement for high-speed in-memory loops or the ForEach-Object cmdlet for streaming pipeline workflows.
Using the foreach Statement
foreach ($i in 1..5) {
Write-Output "Processing item $i of 5"
}Processing item 1 of 5
Processing item 2 of 5
Processing item 3 of 5
Processing item 4 of 5
Processing item 5 of 5Where:
1..5generates an array of five integers.$iis assigned the next sequential integer on each iteration.
You can also iterate across practical ranges, such as a block of network ports:
foreach ($port in 8080..8083) {
Write-Output "Auditing local listener on port: $port"
}Auditing local listener on port: 8080
Auditing local listener on port: 8081
Auditing local listener on port: 8082
Auditing local listener on port: 8083Using the Pipeline (ForEach-Object)
Piping a range expression into ForEach-Object streams integers down the pipeline one by one.
1..5 | ForEach-Object { Write-Output "Item $_" }Item 1
Item 2
Item 3
Item 4
Item 5Or with a batch-style message:
1..3 | ForEach-Object { "Processing batch item: $_" }Processing batch item: 1
Processing batch item: 2
Processing batch item: 3Reverse Ranges (10..1)
Reversing the two numbers in a range automatically generates a descending sequence. No special syntax or additional parameters are needed.
10..110
9
8
7
6
5
4
3
2
1Countdown Script
foreach ($i in 10..1) {
Write-Output "T-minus $i..."
Start-Sleep -Seconds 1
}
Write-Output "Liftoff!"T-minus 10...
T-minus 9...
T-minus 8...
T-minus 7...
T-minus 6...
T-minus 5...
T-minus 4...
T-minus 3...
T-minus 2...
T-minus 1...
Liftoff!Where 10..1 detects that the starting boundary (10) is greater than the target boundary (1), so PowerShell automatically decrements by 1 on each step.
Practical Examples
Generating Sequential File Names
foreach ($i in 1..3) {
$fileName = "report_{0:D3}.txt" -f $i
New-Item -ItemType File -Path "C:\Temp\$fileName" -Force | Out-Null
Write-Output "Created: $fileName"
}Created: report_001.txt
Created: report_002.txt
Created: report_003.txtWhere {0:D3} formats the number with leading zeros to a total width of 3 digits.
Subnet IP Sweep
A common use case for range loops is generating sequential IP addresses across a subnet. The following script combines range iteration with string interpolation to scan a block of IP addresses and report reachability.
param (
[string]$SubnetPrefix = "192.168.1",
[int]$StartHost = 10,
[int]$EndHost = 13
)
if ($StartHost -gt $EndHost) {
Write-Warning "Starting host is greater than ending host. Executing reverse sweep."
}
$SweepResults = foreach ($octet in $StartHost..$EndHost) {
$targetIP = "$SubnetPrefix.$octet"
$isReachable = Test-Connection -ComputerName $targetIP -Count 1 -Quiet -ErrorAction SilentlyContinue
[PSCustomObject]@{
HostAddress = $targetIP
HostOctet = $octet
Status = if ($isReachable) { "ONLINE" } else { "UNRESPONSIVE" }
CheckedAt = (Get-Date -Format "HH:mm:ss")
}
}
$SweepResults | Format-Table -AutoSizeWhere:
$StartHost..$EndHostdynamically creates a range array based on user parameters."$SubnetPrefix.$octet"constructs the full IPv4 address via string interpolation.Test-Connection -ComputerName $targetIP -Count 1 -Quietsends a single ICMP ping and returns$trueor$false.$SweepResults = foreach (...)captures all emitted custom objects directly into an array.
Example run:
pwsh ./scan-ip-range.ps1 -SubnetPrefix "127.0.0" -StartHost 1 -EndHost 3HostAddress HostOctet Status CheckedAt
----------- --------- ------ ---------
127.0.0.1 1 ONLINE 23:10:15
127.0.0.2 2 ONLINE 23:10:15
127.0.0.3 3 ONLINE 23:10:15Quick Reference
| Expression | Result |
|---|---|
1..5 |
1 2 3 4 5 |
5..1 |
5 4 3 2 1 |
-3..3 |
-3 -2 -1 0 1 2 3 |
(1..10).Count |
10 |
1..10 | Where-Object { $_ % 2 -eq 0 } |
2 4 6 8 10 |
'A'..'E' |
A B C D E (PowerShell 6+) |