IPv4Range.psm1

function Convert-IPtoInt32 () { 
  param (
    [parameter(Mandatory=$true)]
    [ipaddress]$ip
  ) 
  $octets = ([string]($ip)).split(".") 
  return [uint32]([uint32]$octets[0] * 16777216 + [uint32]$octets[1] * 65536 + [uint32]$octets[2] * 256 + [uint32]$octets[3])
} 

function Convert-Int32toIP() { 
  param (
    [parameter(Mandatory=$true)]
    [uint32]$int
  ) 
  return (([math]::truncate($int / 16777216)).tostring() + "." + ([math]::truncate(($int % 16777216) / 65536)).tostring() + "." + ([math]::truncate(($int % 65536) / 256)).tostring() + "." + ([math]::truncate($int % 256)).tostring() )
} 


function Get-IPv4Range {
  <#
  .SYNOPSIS
    Get the IP addresses in a range
  .EXAMPLE
   Get-IPrange -start 192.168.8.2 -end 192.168.8.20
  .EXAMPLE
   Get-IPrange -IPv4Address 192.168.8.2 -NetMask 255.255.255.0
  .EXAMPLE
   Get-IPrange -IPv4Address 192.168.8.3 -CIDRMask 24 -Addressable
#>
 
  [CmdletBinding(DefaultParameterSetName='mask')]
  param ( 
    [Parameter(Mandatory=$true, ParameterSetName='range')]
    [ipaddress]$Start, 
    [Parameter(Mandatory=$true, ParameterSetName='range')]
    [ipaddress]$End,

    [Parameter(Mandatory=$true, ParameterSetName='mask', Position=0)]
    [Parameter(Mandatory=$true, ParameterSetName='cidr', Position=0)]
    [ipaddress]$IPv4Address, 

    [Parameter(ParameterSetName='mask')]
    [ipaddress]$NetMask = '255.255.255.0', 
    
    [ValidateRange(0,32)]
    [Parameter(ParameterSetName='cidr')]
    [uint32]$CIDRMask = 24,

    [switch]$Addressable
  ) 
 
  Switch -Regex ($PSCmdlet.ParameterSetName) {
    'mask|cidr' {
      $ipaddr = [Net.IPAddress]::Parse($IPv4Address)
      if ($PSCmdlet.ParameterSetName -eq 'cidr') { 
        $maskaddr = [Net.IPAddress]::Parse((Convert-Int32toIP -int ([convert]::ToInt64(("1" * $CIDRMask + "0" * (32 - $CIDRMask)), 2)))) 
      } else { 
        $maskaddr = [Net.IPAddress]::Parse($NetMask)
      }

      $networkaddr = New-Object net.ipaddress ($maskaddr.address -band $ipaddr.address)
      $broadcastaddr = New-Object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $maskaddr.address -bor $networkaddr.address))
    
      $startaddr = Convert-IPtoInt32 -ip $networkaddr.ipaddresstostring 
      $endaddr = Convert-IPtoInt32 -ip $broadcastaddr.ipaddresstostring 
    }
    'range' { 
      $startaddr = Convert-IPtoInt32 -ip $Start 
      $endaddr = Convert-IPtoInt32 -ip $End 
    }
  }

  if ($Addressable) {
    $startaddr++
    $endaddr--
  }

  for ($i = $startaddr; $i -le $endaddr; $i++) { 
    Convert-Int32toIP -int $i 
  }
}

function Get-IPv4Info {
  [CmdletBinding()]
  param(
    [parameter(Mandatory=$true)]
    [ipaddress]$IPAddress
  )
  $networks = @(
    [PSCustomObject] @{end=167772159;  Class='A'; Type='Public';    IPStart='0.0.0.0';     IPEnd='126.255.255.255'}, # 0.0.0.0 - 9.255.255.255
    [PSCustomObject] @{end=184549375;  Class='A'; Type='Private';   IPStart='10.0.0.0';    IPEnd='10.255.255.255'},  # 10.0.0.0/8
    [PSCustomObject] @{end=2130706431; Class='A'; Type='Public';    IPStart='0.0.0.0';     IPEnd='126.255.255.255'}, # 11.0.0.0 - 126.255.255.255
    [PSCustomObject] @{end=2147483647; Class='-'; Type='Localhost'; IPStart='127.0.0.0';   IPEnd='127.255.255.255'}, # 127.0.0.0/8
    [PSCustomObject] @{end=2886729727; Class='B'; Type='Public';    IPStart='128.0.0.0';   IPEnd='191.255.255.255'}, # 128.0.0.0 - 172.15.255.255
    [PSCustomObject] @{end=2887778303; Class='B'; Type='Private';   IPStart='172.16.0.0';  IPEnd='172.31.255.255'},  # 172.16.0.0/12
    [PSCustomObject] @{end=3221225471; Class='B'; Type='Public';    IPStart='128.0.0.0';   IPEnd='191.255.255.255'}, # 172.32.0.0 - 191.255.255.255
    [PSCustomObject] @{end=3232235519; Class='C'; Type='Public';    IPStart='192.0.0.0';   IPEnd='223.255.255.255'}, # 192.0.0.0 - 192.167.255.255
    [PSCustomObject] @{end=3232301055; Class='C'; Type='Private';   IPStart='192.168.0.0'; IPEnd='192.168.255.255'}, # 192.168.0.0/16
    [PSCustomObject] @{end=3758096383; Class='C'; Type='Public';    IPStart='192.0.0.0';   IPEnd='223.255.255.255'}, # 192.169.0.0 - 223.255.255.255
    [PSCustomObject] @{end=4026531839; Class='D'; Type='Multicast'; IPStart='224.0.0.0';   IPEnd='239.255.255.255'}, # 224.0.0.0 - 239.255.255.255
    [PSCustomObject] @{end=4294967295; Class='E'; Type='Reserved';  IPStart='240.0.0.0';   IPEnd='255.255.255.255'}  # 240.0.0.0 - 255.255.255.255
  )
  $ip = Convert-IPtoInt32 $IPAddress
  $net = $networks | Where-Object end -ge $ip | Select-Object -First 1 | Select-Object Class,Type,IpStart,IPEnd
  $net | Add-Member -Name IPAddress -Value $IPAddress -MemberType NoteProperty
  return $net
}

New-Alias -Name gir -Value Get-IPv4Range