I needed a powershell script today with which i can check if two given IP addresses match or if a given IP address belongs to a subnet or if a smaller subnet belongs to a larger one (or vise vursa). I found a nice script written by Sava from http://www.padisetty.com/ which had part of the functionality i required so i took and modified it to suit my needs. Below you will be able to find the modified script i hope it helps somebody :). The script will return an array of two values, one to indicate true or false and the second the direction. The direction is important as you may want to compare values for a firewall and as such you want to fit one in the other in a particular direction.
Usage example:
- checkSubnet ‘10.185.255.128/26’ ‘10.165.255.166/32’
- checkSubnet ‘10.125.255.128’ ‘10.125.255.166′
- checkSubnet ‘10.140.20.0/21’ ‘10.140.20.0/27’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# Please note i took inspiration form www.padisetty.com # The function will check ip to ip, ip to subnet, subnet to ip or subnet to subnet belong to each other and return true or false and the direction of the check #//////////////////////////////////////////////////////////////////////// function checkSubnet ([string]$addr1, [string]$addr2) { # Separate the network address and lenght $network1, [int]$subnetlen1 = $addr1.Split('/') $network2, [int]$subnetlen2 = $addr2.Split('/') #Convert network address to binary [uint32] $unetwork1 = NetworkToBinary $network1 [uint32] $unetwork2 = NetworkToBinary $network2 #Check if subnet length exists and is less then 32(/32 is host, single ip so no calculation needed) if so convert to binary if($subnetlen1 -lt 32){ [uint32] $mask1 = SubToBinary $subnetlen1 } if($subnetlen2 -lt 32){ [uint32] $mask2 = SubToBinary $subnetlen2 } #Compare the results if($mask1 -and $mask2){ # If both inputs are subnets check which is smaller and check if it belongs in the larger one if($mask1 -lt $mask2){ return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2 }else{ return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1 } }ElseIf($mask1){ # If second input is address and first input is subnet check if it belongs return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2 }ElseIf($mask2){ # If first input is address and second input is subnet check if it belongs return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1 }Else{ # If both inputs are ip check if they match CheckNetworkToNetwork $unetwork1 $unetwork2 } } function CheckNetworkToSubnet ([uint32]$un2, [uint32]$ma2, [uint32]$un1) { $ReturnArray = "" | Select-Object -Property Condition,Direction if($un2 -eq ($ma2 -band $un1)){ $ReturnArray.Condition = $True $ReturnArray.Direction = "Addr1ToAddr2" return $ReturnArray }else{ $ReturnArray.Condition = $False $ReturnArray.Direction = "Addr1ToAddr2" return $ReturnArray } } function CheckSubnetToNetwork ([uint32]$un1, [uint32]$ma1, [uint32]$un2) { $ReturnArray = "" | Select-Object -Property Condition,Direction if($un1 -eq ($ma1 -band $un2)){ $ReturnArray.Condition = $True $ReturnArray.Direction = "Addr2ToAddr1" return $ReturnArray }else{ $ReturnArray.Condition = $False $ReturnArray.Direction = "Addr2ToAddr1" return $ReturnArray } } function CheckNetworkToNetwork ([uint32]$un1, [uint32]$un2) { $ReturnArray = "" | Select-Object -Property Condition,Direction if($un1 -eq $un2){ $ReturnArray.Condition = $True $ReturnArray.Direction = "Addr1ToAddr2" return $ReturnArray }else{ $ReturnArray.Condition = $False $ReturnArray.Direction = "Addr1ToAddr2" return $ReturnArray } } function SubToBinary ([int]$sub) { return ((-bnot [uint32]0) -shl (32 - $sub)) } function NetworkToBinary ($network) { $a = [uint32[]]$network.split('.') return ($a[0] -shl 24) + ($a[1] -shl 16) + ($a[2] -shl 8) + $a[3] } #//////////////////////////////////////////////////////////////////////// |