Get-PowerIPRange.ps1

<#
.SYNOPSIS
Generates IPv4 address lists with the provided Start and End IPv4 address.
.DESCRIPTION
Function utilized by Test-PowerPing to generate IPv4 Address lists.
.NOTES
Author: Hunter Hirsch
#>

function Get-PowerIPRange {
[CmdletBinding()]
[OutputType([System.Collections.ArrayList],[System.Collections.Queue])]
    Param (
    [Parameter(Mandatory)]
    [string]
    $Start,
    [Parameter(Mandatory)]
    [string]
    $End,
    [Parameter()]
    [string[]]
    $Filter
    )
Begin {
Try{
    $starr = ([ipaddress] $Start).GetAddressBytes()
    $edarr = ([ipaddress] $End).GetAddressBytes()
    [string]$adbal = ($edarr[0] - $starr[0]),($edarr[1] - $starr[1]),($edarr[2] - $starr[2]),($edarr[3] - $starr[3])
    $adbal = $adbal.Replace(" ",'')
    if ($adbal[0] -eq '-' -or $adbal -match "^[0]{1,3}-"){
        $starr = ([ipaddress] $End).GetAddressBytes()
        $edarr = ([ipaddress] $Start).GetAddressBytes()
        }
    $endip = [ipaddress]$edarr
    if ($Filter){
        $Filter = $Filter.Split(',')
        filter ppafilter {
            [uint32]$cnt = $Filter.Count -1
            for ($i = 0; $i -le $cnt; $i++){
                if ($_ -like $Filter[$i]){
                    return
                    }
                }
            $fqueue.enqueue($_)
            }
        }
    $address = [System.Collections.ArrayList]::new()
    $adqueue = [System.Collections.Queue]::new()
    }
Catch{
    $address = $null
    Throw $_.Exception.errorrecord
    }
    }
Process{
##Address generation loop. Uses limitations of Byte value (max 255) to apply counter logic. If count up hits error, max is reached, octet is set to zero, and preceding octet is counted up one time.##
##Errors are accounted for from try/catch progression. Parent function attempts to clear all errors if present to reduce log bloat. Error must match 'cannot convert value "256"', these are the only errors cleared.##
##Microsoft documentation advises there is no way to bypass the initial write to global $error variable. (https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.4).##
Try{
    $adqueue.Enqueue([string][ipaddress]$starr)
    while ([ipaddress]$starr -ne $endip){
        Try{
            $starr[3]++
            }
        Catch{
            $starr[3] = 0
            Try{
                $starr[2]++
                }
            Catch{
                $starr[2] = 0
                Try{
                    $starr[1]++
                    }
                Catch{
                    $starr[1]=0
                    Try{
                        $starr[0]++
                        }
                    Catch{
                        }
                    }
                }
            }
        $adqueue.Enqueue([string][ipaddress]$starr)
        }
    $null = $address.AddRange($adqueue)
    $adqueue.Clear()
   }
Catch{
    $address = $null
    $adqueue = $null
    Throw $_.Exception.errorrecord
    [system.gc]::Collect()
    }
}
End {
Try{
    if ($Filter){
        $fqueue = New-Object System.Collections.Queue
        $address | ppafilter
        $address.clear()
        $fqueue
        }
    Else{
        $address
        }
    if ($Filter){
        $fqueue = $null
        }
    $address = $null; $adqueue = $null
    }
Catch{
    if ($Filter){
        $fqueue = $null
        }
    $address = $null
    [system.gc]::Collect()
    Throw $_.exception.errorrecord
    }
Finally{
    [system.gc]::Collect()
    }
}
}