IPBasicNetworking.psm1
# Basic Network Module # --- This module consists of a set of basic powershell functions for some common network based work you might want to do function Get-IPNetDetails { <# .SYNOPSIS Provides Basic network information about a given IP Adddress .DESCRIPTION Given an IP Address in CIDR format calculate and return the following details about the Network the IP is part of: - The CidrMask for the Network - The Subnet Mask for the Network of the IP - The Network ID for the Network - The First usable host IP address in the Network - The Last usable host IP address in the Network .EXAMPLE Get-GatewayAddress -IPCidr 10.1.1.3/24 IP : 10.1.1.3 CidrMask : 22 SubnetMask : 255.255.252.0 NetworkId : 10.1.0.0 FirstIP : 10.1.0.1 LastIP : 10.1.3.254 .PARAMETER IPCidr A host IP Address with CIDR Mask .INPUTS None. You cannont pipe objects .OUTPUTS PSObject. Returns a Custom PS object with the IP Details #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true,Position=0)][string]$IPCidr ) # Split IP into IP and Mask $IPAddress = $IPCidr.Split('/')[0] $CidrMask = $IPCidr.Split('/')[1] if ( $IPAddress -eq $null -or $CidrMask -eq $null -or $CidrMask -NotIn 8..32 ) { throw "IP Address invalid - Check that you have submitted the IP in CIDR format" } # Convert the IP to Binary $HostBinary = ([Convert]::toString(([IPAddress][String]([IPAddress]$($IPAddress)).Address).Address,2)).PadLeft(32, "0") if ($HostBinary -eq $null) { throw "Invalid IP Address" } #Split the Binary IP into Network/Host based on the Interfaces subnet mask - Keep the Network Binary part (the First part of the string) $NetworkSection = ($HostBinary | Where {$_ -match "^(.{$($CidrMask)})"} | ForEach{ [PSCustomObject]@{ 'BinaryNet' = $Matches[0] } }).BinaryNet $NetworkId = $NetworkSection $FirstIP = $NetworkSection $LastIP = $NetworkSection #Tell us what the Network ID is While ( $NetworkId.Length -le 31 ) { $NetworkId = [string]$NetworkId + "0" } # Find the First usable IP in the network - Fill the host section with 0 except the last Number While ( $FirstIP.Length -le 30 ) { $FirstIP = [String]$FirstIP + 0 } if ($FirstIP.Length -eq 31) { $FirstIP = [string]$FirstIP + 1 } # Find the Last usable IP in the network - Fill the host section with 0 except the last Number While ( $LastIP.Length -le 30 ) { $LastIP = [String]$LastIP + 1 } if ($LastIP.Length -eq 31) { $LastIP = [string]$LastIP + 0 } # Tell me the Subnet Mask $SubnetMask = "" While ($SubnetMask.Length -le ([int]$CidrMask -1 ) ) { $SubnetMask = [String]$SubnetMask + 1 } While ($SubnetMask.Length -le 31 ) { $SubnetMask = [string]$SubnetMask + 0 } # Convert the Binary IP back into Dotted Quad $GatewayDetails = New-Object psobject $GatewayDetails | Add-Member -MemberType NoteProperty -Name IP -Value $IPAddress $GatewayDetails | Add-Member -MemberType NoteProperty -Name CidrMask -Value $CidrMask $GatewayDetails | Add-Member -MemberType NoteProperty -Name SubnetMask -Value $(([System.Net.IPAddress]"$([System.Convert]::ToInt64($SubnetMask,2))").IPAddressToString) $GatewayDetails | Add-Member -MemberType NoteProperty -Name NetworkId -Value $(([System.Net.IPAddress]"$([System.Convert]::ToInt64($NetworkId,2))").IPAddressToString) $GatewayDetails | Add-Member -MemberType NoteProperty -Name FirstIP -Value $(([System.Net.IPAddress]"$([System.Convert]::ToInt64($FirstIP,2))").IPAddressToString) $GatewayDetails | Add-Member -MemberType NoteProperty -Name LastIP -Value $(([System.Net.IPAddress]"$([System.Convert]::ToInt64($LastIP,2))").IPAddressToString) $GatewayDetails | Add-Member -MemberType NoteProperty -Name NetworkBinary -Value $NetworkId $GatewayDetails | Add-Member -MemberType NoteProperty -Name HostBinary -Value $HostBinary return $GatewayDetails } function Test-IPInRange { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][string]$IPAddress, [Parameter(Mandatory=$true)][string[]]$Networks ) $IPSubjectBinary = Get-IPNetDetails -IPCidr "$($IPAddress)/32" $IPInRange = New-Object System.Collections.ArrayList $IPOutRange = New-Object System.Collections.ArrayList foreach ($Network in $Networks ) { $NetworkDetails = Get-IPNetDetails -IPCidr $Network if ( ($NetworkDetails.NetworkBinary).Substring(0,$($NetworkDetails.CidrMask)) -eq (($IPSubjectBinary.HostBinary).Substring(0,$($NetworkDetails.CidrMask))) ) { [void]$IPInRange.Add("$($Network)") } else { [void]$IPOutRange.Add("$($Network)") } } $ReturnObject = New-Object psobject $ReturnObject | Add-Member -MemberType NoteProperty -Name InRange -Value $IPInRange $ReturnObject | Add-Member -MemberType NoteProperty -Name OutRange -Value $IPOutRange $ReturnObject | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPAddress return $ReturnObject } function Get-IPRangeDetails { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][string]$FirstIP, [Parameter(Mandatory=$true)][string]$LastIP ) # Add CIDR mask if its not added If ( $FristIP -notlike "*/*") { $FirstIP = "$($FirstIP)/32" } If ( $LastIP -notlike "*/*") { $LastIP = "$($LastIP)/32" } # Grab the Basic Network Details $FirstIPDetails = Get-IPNetDetails -IPCidr $FirstIP $LastIPDEtails = Get-IPNetDetails -IPCidr $LAstIP # Convert it to an Integer so we can treat them like numbers $FirstIPInt = [Convert]::ToInt32( $($FirstIPDetails.HostBinary), 2) $LastIPInt = [Convert]::ToInt32( $($LastIPDetails.HostBinary), 2) # Create a return Object $IPRangeObject = New-Object PSObject $IPRangeObject | Add-Member -MemberType NoteProperty -Name FirstIP -Value $FirstIP $IPRangeObject | Add-Member -MemberType NoteProperty -Name LastIP -Value $LastIP # The Difference between the Int's will be the number of IP's in the range $IPRangeObject | Add-Member -MemberType NoteProperty -Name IPCount -Value $( $LastIPInt - $FirstIPInt ) $IPIntRange = $FirstIPInt..$LastIPInt # Lets suggest a subnet that would cover these networks # Convert the Binary Network details to an array $FirstIPBinArray = ($FirstIPDetails.HostBinary).ToCharArray() $LastIPBinArray = ($LastIPDEtails.HostBinary).ToCharArray() $Counter = 0 $DiffFound = $False # Loop through the array till we find a difference between the binary of the first and last IP # This will give us the number of bits required for a host that spans these ranges foreach ( $FirstIPBin in $FirstIPBinArray ) { if ( $FirstIPBin -ne $LastIPBinArray[$Counter] -and $DiffFound -eq $False ) { $DiffIndex = $Counter $DiffFound = $True } $Counter++ } # Calculate the subnet that jumps both of these $SuperNet = Get-IPNetDetails -IPCidr "$($FirstIPDetails.IP)/$($DiffIndex )" $IPRangeObject | Add-Member -MemberType NoteProperty -Name SuperNet -Value "$($SuperNet.NetworkId)/$($SuperNet.CidrMask)" # Calculate each IP in the range #### LIMITED TO 500 IP's in range to fix up performance in conversion if ( $IPIntRange.Count -le 500 ) { $IPRange = New-Object System.Collections.ArrayList Foreach ( $IPInt in $IPIntRange ) { $IPIntBinary = ([Convert]::toString( $($IPInt),2)).PadLeft(32, "0") $IPAddress = $(([System.Net.IPAddress]"$([System.Convert]::ToInt64($IPIntBinary,2))")) [void]$IPRange.Add( $($IPAddress.IPAddressToString)) } $IPRangeObject | Add-Member -MemberType NoteProperty -Name IPAdddresses -Value $IPRange } return $IPRangeObject } |