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
}
}
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.
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.
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?