Enumerate all IPs between two addresses

Hi everyone,

I am going to write a PS script to scan availability of computers between two IP addresses (say Start IP and End IP) and do it extremely fast! (10ms maybe less for each IP in the LAN)

At last despite all searches and efforts, I have difficulty to create an object to store all those IPs and pass that object to the scan module. For example I want to enumerate all IPs between 10.0.0.0 to 10.0.2.255 (765 IPs in this case).

{$x = @(all IPs from 10.0.0.0 to 10.0.2.255)}

This the code I have for the first part, it maybe looks weird and cumbersome but it is written in this fashion for educational purposes.

I would appreciate your kind help.

# URL: https://gallery.technet.microsoft.com/scriptcenter/A-short-tip-to-validate-IP-4f039260
# URL: https://ridicurious.com/2018/11/14/4-ways-to-validate-ipaddress-in-powershell/

Function Test-IP {

param
(
[Parameter()]
[String]$start,
[Parameter()]
[String]$end
)

$x = `
$(
try {[IPAddress]$start}
catch
{
Write-Host “<code>nError has occured! {$start} is NOT a valid IP address"</code>
-BackgroundColor Red `
-ForegroundColor Yellow ;
$start=$null ;
break
}
)

$y = `
$(
try {[IPAddress]$end}
catch
{
Write-Host “<code>nError has occured! [$end] is NOT a valid IP address"</code>
-BackgroundColor Red `
-ForegroundColor White ;
$end=$null ;
break
}
)

Write-Host “<$start> has accepted as Satrt IP” -BackgroundColor Green -ForegroundColor White
Write-Host “<$end> has accepted as End IP” -BackgroundColor Green -ForegroundColor White

$s1 = [byte[]]$start.Split(“.”)[0]
$s2 = [byte[]]$start.Split(“.”)[1]
$s3 = [byte[]]$start.Split(“.”)[2]
$s4 = [byte[]]$start.Split(“.”)[3]

$e1 = [byte[]]$End.Split(“.”)[0]
$e2 = [byte[]]$End.Split(“.”)[1]
$e3 = [byte[]]$End.Split(“.”)[2]
$e4 = [byte[]]$End.Split(“.”)[3]

$err = $true

if ($($s1) -lt $($e1)) {$err = $false}
elseif($($s1) -eq $($e1)) {
if ($($s2) -lt $($e2)) {$err = $false}
elseif($($s2) -eq $($e2)) {
if($($s3) -lt $($e3)) {$err = $false}
elseif($($s3) -eq $($e3)) {
if ($($s4) -lt $($e4)) {$err = $false}
elseif($($s4) -eq $($e4)) {$err = $true
}
}
}
}

if($err)
{
Write-Host “nStart IP MUST be lower then End IP"
-BackgroundColor Red `
-ForegroundColor Yellow
$err = $false
$x = $start = $null
$y = $end = $null
}

}

Maybe this will help

$range1 = @(1…2)
$range2 = @(1…255)
foreach($octet3 in $range1) {
foreach($octet4 in $range2) {
write-host “10.0.$octet3.$octet4”
}
}

A couple other considerations I would add is it may be difficult to get the speed you are looking for in a PS script. I would use a workflow with a foreach -parallel to improve performance. https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_foreach-parallel?view=powershell-5.1

Also, I don’t fully understand your requirement from a networking perspective. Typically IP addresses are valid for a specific subnet CIDR (/24, /16 /8) not every address from 0-255 per octet is necessarily valid.

Unless you are doing this for an academic reason, fping is a pretty good solution already out there.

Very good hint Tony, thanks.

With 4 nested “foreach” and it worked perfectly for any given IP range.

 

thanks for your reply Mike,

For the first part, you are absolutely right, it’s difficult but quite feasible.

Actually I have tested it against a list of predefined IP addresses in a text file as fast as 5 msec per each IP and it worked fine (in LAN), also the timeout is adjustable for WAN.

for the second part, again you are right but by doing so I wanted to give other people flexibility, assuming that not everyone is a network (wo)man.

By the way, I will have a fully functional copy of the script here (maybe as a new post) as soon as it is finished and it’s not far from it.

Hmm, I was trying to do it mathematically but failed:

$a = [ipaddress]'10.0.0.0' ; $b = [ipaddress]'10.0.2.255'
& { for ($i = $a.address; $i -le $b.address; $i++) { 
  ([ipaddress]$i).ipaddresstostring } } | select -first 10

10.0.0.0
11.0.0.0
12.0.0.0
13.0.0.0
14.0.0.0
15.0.0.0
16.0.0.0
17.0.0.0
18.0.0.0
19.0.0.0

I think there is a big problem with this piece of code that I have

[System.Array]$range

$range = `
foreach ($i in ($($s1)..$($e1))) {

foreach ($j in ($($s1)..$($e1))) {

foreach ($k in ($($s3)..$($e3))) {

foreach ($l in ($($s4)..$($e4))) {

Write-Output "$i.$j.$k.$l"
}
}
}
}

$range

It works fine if you don’t hit the end of an octet (255) and not to surpass it.

For example if a user would like a range from 10.0.254.0 ($s1.$s2.$s3.$s4) to 10.1.0.100 ($e1.$e2.$e3.$e4),

because of " foreach ($k in ($($s3)…$($e3))) " It actually enumerate in descending mode instead of ascending,

and it’s not surprising from that code! (254…0)

This code has a major flaw! and must be rewritten again. Does anyone have an idea?

I need the output it in this fashion:

10.0.254.0 , 10.0.254.1 , … , 10.0.254.255 , 10.0.255.0 , 10.0.255.1 , … , 10.0.255.255 , 10.1.0.0 , 10.1.0.1 , … , 10.1.0.100

I have this piece of code but I think there is a big problem with it

[System.Array]$range

$range = `
foreach ($i in ($($s1)..$($e1))) {

foreach ($j in ($($s1)..$($e1))) {

foreach ($k in ($($s3)..$($e3))) {

foreach ($l in ($($s4)..$($e4))) {

Write-Output "$i.$j.$k.$l"
}
}
}
}

$range

It works fine if you don’t hit the end of an octet (255) and not to surpass it.

For example if a user would like to have a range from 10.0.254.0 ($s1.$s2.$s3.$s4) to 10.1.0.100 ($e1.$e2.$e3.$e4),

because of " foreach ($k in ($($s3)…$($e3))) " It actually enumerate IPs in descending mode instead of ascending, and it’s not surprising doing so from that code! (254…0)

This code has a major flaw! and must be rewritten. Does anyone have an idea?

I need the output looks like this list:

10.0.254.0 , 10.0.254.1 , … , 10.0.254.255 , 10.0.255.0 , 10.0.255.1 , … , 10.0.255.255 , 10.1.0.0 , 10.1.0.1 , … , 10.1.0.100

Use the Next-IP function of the AZSBTOOLS PS module as in:

$startIP = $CurentIP = '10.0.254.0'
$endIP = '10.1.0.100'

$MyIPList = while ($CurentIP -ne $endIP) { 
    $CurentIP = Next-IP -IPAddress $CurentIP
    $CurentIP
}

$MyIPList.Count # 612
$MyIPList

With output like:

10.0.254.1
10.0.254.2
10.0.254.3
10.0.254.4
10.0.254.5
10.0.254.6
10.0.254.7
10.0.254.8
10.0.254.9
10.0.254.10
10.0.254.11
10.0.254.12
10.0.254.13
10.0.254.14
10.0.254.15
10.0.254.16
10.0.254.17
10.0.254.18
10.0.254.19
10.0.254.20
10.0.254.21
10.0.254.22
10.0.254.23
10.0.254.24
10.0.254.25
10.0.254.26
10.0.254.27
10.0.254.28
10.0.254.29
10.0.254.30
10.0.254.31
10.0.254.32
10.0.254.33
10.0.254.34
10.0.254.35
10.0.254.36
10.0.254.37
10.0.254.38
10.0.254.39
10.0.254.40
10.0.254.41
10.0.254.42
10.0.254.43
10.0.254.44
10.0.254.45
10.0.254.46
10.0.254.47
10.0.254.48
10.0.254.49
10.0.254.50
10.0.254.51
10.0.254.52
10.0.254.53
10.0.254.54
10.0.254.55
10.0.254.56
10.0.254.57
10.0.254.58
10.0.254.59
10.0.254.60
10.0.254.61
10.0.254.62
10.0.254.63
10.0.254.64
10.0.254.65
10.0.254.66
10.0.254.67
10.0.254.68
10.0.254.69
10.0.254.70
10.0.254.71
10.0.254.72
10.0.254.73
10.0.254.74
10.0.254.75
10.0.254.76
10.0.254.77
10.0.254.78
10.0.254.79
10.0.254.80
10.0.254.81
10.0.254.82
10.0.254.83
10.0.254.84
10.0.254.85
10.0.254.86
10.0.254.87
10.0.254.88
10.0.254.89
10.0.254.90
10.0.254.91
10.0.254.92
10.0.254.93
10.0.254.94
10.0.254.95
10.0.254.96
10.0.254.97
10.0.254.98
10.0.254.99
10.0.254.100
10.0.254.101
10.0.254.102
10.0.254.103
10.0.254.104
10.0.254.105
10.0.254.106
10.0.254.107
10.0.254.108
10.0.254.109
10.0.254.110
10.0.254.111
10.0.254.112
10.0.254.113
10.0.254.114
10.0.254.115
10.0.254.116
10.0.254.117
10.0.254.118
10.0.254.119
10.0.254.120
10.0.254.121
10.0.254.122
10.0.254.123
10.0.254.124
10.0.254.125
10.0.254.126
10.0.254.127
10.0.254.128
10.0.254.129
10.0.254.130
10.0.254.131
10.0.254.132
10.0.254.133
10.0.254.134
10.0.254.135
10.0.254.136
10.0.254.137
10.0.254.138
10.0.254.139
10.0.254.140
10.0.254.141
10.0.254.142
10.0.254.143
10.0.254.144
10.0.254.145
10.0.254.146
10.0.254.147
10.0.254.148
10.0.254.149
10.0.254.150
10.0.254.151
10.0.254.152
10.0.254.153
10.0.254.154
10.0.254.155
10.0.254.156
10.0.254.157
10.0.254.158
10.0.254.159
10.0.254.160
10.0.254.161
10.0.254.162
10.0.254.163
10.0.254.164
10.0.254.165
10.0.254.166
10.0.254.167
10.0.254.168
10.0.254.169
10.0.254.170
10.0.254.171
10.0.254.172
10.0.254.173
10.0.254.174
10.0.254.175
10.0.254.176
10.0.254.177
10.0.254.178
10.0.254.179
10.0.254.180
10.0.254.181
10.0.254.182
10.0.254.183
10.0.254.184
10.0.254.185
10.0.254.186
10.0.254.187
10.0.254.188
10.0.254.189
10.0.254.190
10.0.254.191
10.0.254.192
10.0.254.193
10.0.254.194
10.0.254.195
10.0.254.196
10.0.254.197
10.0.254.198
10.0.254.199
10.0.254.200
10.0.254.201
10.0.254.202
10.0.254.203
10.0.254.204
10.0.254.205
10.0.254.206
10.0.254.207
10.0.254.208
10.0.254.209
10.0.254.210
10.0.254.211
10.0.254.212
10.0.254.213
10.0.254.214
10.0.254.215
10.0.254.216
10.0.254.217
10.0.254.218
10.0.254.219
10.0.254.220
10.0.254.221
10.0.254.222
10.0.254.223
10.0.254.224
10.0.254.225
10.0.254.226
10.0.254.227
10.0.254.228
10.0.254.229
10.0.254.230
10.0.254.231
10.0.254.232
10.0.254.233
10.0.254.234
10.0.254.235
10.0.254.236
10.0.254.237
10.0.254.238
10.0.254.239
10.0.254.240
10.0.254.241
10.0.254.242
10.0.254.243
10.0.254.244
10.0.254.245
10.0.254.246
10.0.254.247
10.0.254.248
10.0.254.249
10.0.254.250
10.0.254.251
10.0.254.252
10.0.254.253
10.0.254.254
10.0.254.255
10.0.255.0
10.0.255.1
10.0.255.2
10.0.255.3
10.0.255.4
10.0.255.5
10.0.255.6
10.0.255.7
10.0.255.8
10.0.255.9
10.0.255.10
10.0.255.11
10.0.255.12
10.0.255.13
10.0.255.14
10.0.255.15
10.0.255.16
10.0.255.17
10.0.255.18
10.0.255.19
10.0.255.20
10.0.255.21
10.0.255.22
10.0.255.23
10.0.255.24
10.0.255.25
10.0.255.26
10.0.255.27
10.0.255.28
10.0.255.29
10.0.255.30
10.0.255.31
10.0.255.32
10.0.255.33
10.0.255.34
10.0.255.35
10.0.255.36
10.0.255.37
10.0.255.38
10.0.255.39
10.0.255.40
10.0.255.41
10.0.255.42
10.0.255.43
10.0.255.44
10.0.255.45
10.0.255.46
10.0.255.47
10.0.255.48
10.0.255.49
10.0.255.50
10.0.255.51
10.0.255.52
10.0.255.53
10.0.255.54
10.0.255.55
10.0.255.56
10.0.255.57
10.0.255.58
10.0.255.59
10.0.255.60
10.0.255.61
10.0.255.62
10.0.255.63
10.0.255.64
10.0.255.65
10.0.255.66
10.0.255.67
10.0.255.68
10.0.255.69
10.0.255.70
10.0.255.71
10.0.255.72
10.0.255.73
10.0.255.74
10.0.255.75
10.0.255.76
10.0.255.77
10.0.255.78
10.0.255.79
10.0.255.80
10.0.255.81
10.0.255.82
10.0.255.83
10.0.255.84
10.0.255.85
10.0.255.86
10.0.255.87
10.0.255.88
10.0.255.89
10.0.255.90
10.0.255.91
10.0.255.92
10.0.255.93
10.0.255.94
10.0.255.95
10.0.255.96
10.0.255.97
10.0.255.98
10.0.255.99
10.0.255.100
10.0.255.101
10.0.255.102
10.0.255.103
10.0.255.104
10.0.255.105
10.0.255.106
10.0.255.107
10.0.255.108
10.0.255.109
10.0.255.110
10.0.255.111
10.0.255.112
10.0.255.113
10.0.255.114
10.0.255.115
10.0.255.116
10.0.255.117
10.0.255.118
10.0.255.119
10.0.255.120
10.0.255.121
10.0.255.122
10.0.255.123
10.0.255.124
10.0.255.125
10.0.255.126
10.0.255.127
10.0.255.128
10.0.255.129
10.0.255.130
10.0.255.131
10.0.255.132
10.0.255.133
10.0.255.134
10.0.255.135
10.0.255.136
10.0.255.137
10.0.255.138
10.0.255.139
10.0.255.140
10.0.255.141
10.0.255.142
10.0.255.143
10.0.255.144
10.0.255.145
10.0.255.146
10.0.255.147
10.0.255.148
10.0.255.149
10.0.255.150
10.0.255.151
10.0.255.152
10.0.255.153
10.0.255.154
10.0.255.155
10.0.255.156
10.0.255.157
10.0.255.158
10.0.255.159
10.0.255.160
10.0.255.161
10.0.255.162
10.0.255.163
10.0.255.164
10.0.255.165
10.0.255.166
10.0.255.167
10.0.255.168
10.0.255.169
10.0.255.170
10.0.255.171
10.0.255.172
10.0.255.173
10.0.255.174
10.0.255.175
10.0.255.176
10.0.255.177
10.0.255.178
10.0.255.179
10.0.255.180
10.0.255.181
10.0.255.182
10.0.255.183
10.0.255.184
10.0.255.185
10.0.255.186
10.0.255.187
10.0.255.188
10.0.255.189
10.0.255.190
10.0.255.191
10.0.255.192
10.0.255.193
10.0.255.194
10.0.255.195
10.0.255.196
10.0.255.197
10.0.255.198
10.0.255.199
10.0.255.200
10.0.255.201
10.0.255.202
10.0.255.203
10.0.255.204
10.0.255.205
10.0.255.206
10.0.255.207
10.0.255.208
10.0.255.209
10.0.255.210
10.0.255.211
10.0.255.212
10.0.255.213
10.0.255.214
10.0.255.215
10.0.255.216
10.0.255.217
10.0.255.218
10.0.255.219
10.0.255.220
10.0.255.221
10.0.255.222
10.0.255.223
10.0.255.224
10.0.255.225
10.0.255.226
10.0.255.227
10.0.255.228
10.0.255.229
10.0.255.230
10.0.255.231
10.0.255.232
10.0.255.233
10.0.255.234
10.0.255.235
10.0.255.236
10.0.255.237
10.0.255.238
10.0.255.239
10.0.255.240
10.0.255.241
10.0.255.242
10.0.255.243
10.0.255.244
10.0.255.245
10.0.255.246
10.0.255.247
10.0.255.248
10.0.255.249
10.0.255.250
10.0.255.251
10.0.255.252
10.0.255.253
10.0.255.254
10.0.255.255
10.1.0.0
10.1.0.1
10.1.0.2
10.1.0.3
10.1.0.4
10.1.0.5
10.1.0.6
10.1.0.7
10.1.0.8
10.1.0.9
10.1.0.10
10.1.0.11
10.1.0.12
10.1.0.13
10.1.0.14
10.1.0.15
10.1.0.16
10.1.0.17
10.1.0.18
10.1.0.19
10.1.0.20
10.1.0.21
10.1.0.22
10.1.0.23
10.1.0.24
10.1.0.25
10.1.0.26
10.1.0.27
10.1.0.28
10.1.0.29
10.1.0.30
10.1.0.31
10.1.0.32
10.1.0.33
10.1.0.34
10.1.0.35
10.1.0.36
10.1.0.37
10.1.0.38
10.1.0.39
10.1.0.40
10.1.0.41
10.1.0.42
10.1.0.43
10.1.0.44
10.1.0.45
10.1.0.46
10.1.0.47
10.1.0.48
10.1.0.49
10.1.0.50
10.1.0.51
10.1.0.52
10.1.0.53
10.1.0.54
10.1.0.55
10.1.0.56
10.1.0.57
10.1.0.58
10.1.0.59
10.1.0.60
10.1.0.61
10.1.0.62
10.1.0.63
10.1.0.64
10.1.0.65
10.1.0.66
10.1.0.67
10.1.0.68
10.1.0.69
10.1.0.70
10.1.0.71
10.1.0.72
10.1.0.73
10.1.0.74
10.1.0.75
10.1.0.76
10.1.0.77
10.1.0.78
10.1.0.79
10.1.0.80
10.1.0.81
10.1.0.82
10.1.0.83
10.1.0.84
10.1.0.85
10.1.0.86
10.1.0.87
10.1.0.88
10.1.0.89
10.1.0.90
10.1.0.91
10.1.0.92
10.1.0.93
10.1.0.94
10.1.0.95
10.1.0.96
10.1.0.97
10.1.0.98
10.1.0.99
10.1.0.100

Dear Sam,

Your “AZSBTools” Module is not only a practical utility but also a masterpiece.

By the way, the “Next-IP” function (alongside the while loop) works like a charm,

appreciate it.