IP-Calc.ps1

<#PSScriptInfo
.VERSION 2.0.1
.GUID cb059a0e-09b6-4756-8df4-28e997b9d97f
.AUTHOR saw-friendship@yandex.ru
.COMPANYNAME
.COPYRIGHT
.TAGS IP Subnet Calculator WildCard CIDR
.LICENSEURI
.PROJECTURI https://sawfriendship.wordpress.com/
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
#>


<#
.DESCRIPTION
IP Calculator for calculation IP Subnet
.EXAMPLE
IP-Calc -CIDR 192.168.0.0/24
IP : 192.168.0.0
Mask : 255.255.255.0
PrefixLength : 24
WildCard : 0.0.0.255
IPcount : 256
Subnet : 192.168.0.0
Broadcast : 192.168.0.255
CIDR : 192.168.0.0/24
ToDecimal : 3232235520
IPBin : 11000000.10101000.00000000.00000000
MaskBin : 11111111.11111111.11111111.00000000
SubnetBin : 11000000.10101000.00000000.00000000
BroadcastBin : 11000000.10101000.00000000.11111111
.EXAMPLE
IP-Calc -IPAddress 192.168.0.0 -Mask 255.255.255.0
IP : 192.168.0.0
Mask : 255.255.255.0
PrefixLength : 24
WildCard : 0.0.0.255
IPcount : 256
Subnet : 192.168.0.0
Broadcast : 192.168.0.255
CIDR : 192.168.0.0/24
ToDecimal : 3232235520
IPBin : 11000000.10101000.00000000.00000000
MaskBin : 11111111.11111111.11111111.00000000
SubnetBin : 11000000.10101000.00000000.00000000
BroadcastBin : 11000000.10101000.00000000.11111111
.EXAMPLE
IP-Calc -IPAddress 192.168.3.0 -PrefixLength 23
IP : 192.168.3.0
Mask : 255.255.254.0
PrefixLength : 23
WildCard : 0.0.1.255
IPcount : 512
Subnet : 192.168.2.0
Broadcast : 192.168.3.255
CIDR : 192.168.2.0/23
ToDecimal : 3232236288
IPBin : 11000000.10101000.00000011.00000000
MaskBin : 11111111.11111111.11111110.00000000
SubnetBin : 11000000.10101000.00000010.00000000
BroadcastBin : 11000000.10101000.00000011.11111111
.EXAMPLE
IP-Calc -IPAddress 192.168.0.0 -WildCard 0.0.3.0
IP : 192.168.0.0
Mask : 255.255.252.255
PrefixLength : 30
WildCard : 0.0.3.0
IPcount : 4
Subnet : 192.168.0.0
Broadcast : 192.168.3.0
CIDR : 192.168.0.0/30
ToDecimal : 3232235520
IPBin : 11000000.10101000.00000000.00000000
MaskBin : 11111111.11111111.11111100.11111111
SubnetBin : 11000000.10101000.00000000.00000000
BroadcastBin : 11000000.10101000.00000011.00000000
.EXAMPLE
IP-Calc -IPAddress 172.16.0.0 -PrefixLength 12
IP : 172.16.0.0
Mask : 255.240.0.0
PrefixLength : 12
WildCard : 0.15.255.255
IPcount : 1048576
Subnet : 172.16.0.0
Broadcast : 172.31.255.255
CIDR : 172.16.0.0/12
ToDecimal : 2886729728
IPBin : 10101100.00010000.00000000.00000000
MaskBin : 11111111.11110000.00000000.00000000
SubnetBin : 10101100.00010000.00000000.00000000
BroadcastBin : 10101100.00011111.11111111.11111111
#>
 
[CmdletBinding(DefaultParameterSetName='CIDR')]
    param(
        [Parameter(Mandatory=$true,ParameterSetName='CIDR',Position=0)]
            [ValidateScript({$Array = ($_ -split '\\|\/'); $Array[0] -as [IPAddress] -and [string[]](0..32) -contains $Array[1]})]
            [Alias('DestinationPrefix')]
            [string]$CIDR,
        [parameter(ParameterSetName=('Mask'))][parameter(ParameterSetName=('PrefixLength'))][parameter(ParameterSetName=('WildCard'))]
            [Alias('IP')]
            [IPAddress]$IPAddress,
        [Parameter(Mandatory=$true,ParameterSetName='Mask')]
            [IPAddress]$Mask,
        [parameter(Mandatory=$true,ParameterSetName='PrefixLength')]
            [ValidateRange(0,32)]
            [int]$PrefixLength,
        [parameter(Mandatory=$true,ParameterSetName='WildCard')]
            [IPAddress]$WildCard,
        [Parameter(Position=3)]
            [switch]$CreateIParray,
        [Parameter(Position=4)]
            [switch]$CreateIParrayPassThru
    )

    if($CIDR){
        [IPAddress]$IPAddress = ($CIDR -split '\\|\/')[0]
        [int]$PrefixLength = ($CIDR -split '\\|\/')[1]
        [IPAddress]$Mask = [IPAddress]([string](4gb-([System.Math]::Pow(2,(32-$PrefixLength)))))
    }
    if($PrefixLength -and !$Mask){
        [IPAddress]$Mask = [IPAddress]([string](4gb-([System.Math]::Pow(2,(32-$PrefixLength)))))
    }
    if($WildCard){
        [IPAddress]$Mask = $WildCard.GetAddressBytes().ForEach({255 - $_}) -join '.'
    }
    if(!$PrefixLength -and $Mask){
        $PrefixLength = 32 - ($Mask.GetAddressBytes().ForEach({[System.Math]::Log((256-$_),2)}) | Measure-Object -Sum).Sum
    }
    
    [int[]]$SplitIPAddress = $IPAddress.GetAddressBytes()
    [int64]$ToDecimal = $SplitIPAddress[0]*16mb + $SplitIPAddress[1]*64kb + $SplitIPAddress[2]*256 + $SplitIPAddress[3]
    
    
    [int[]]$SplitMask = $Mask.GetAddressBytes()
    $IPBin = ($SplitIPAddress.ForEach({[System.Convert]::ToString($_,2).PadLeft(8,'0')})) -join '.'
    $MaskBin = ($SplitMask.ForEach({[System.Convert]::ToString($_,2).PadLeft(8,'0')})) -join '.'
    
    if((($MaskBin -replace '\.').TrimStart('1').Contains('1')) -and (!$WildCard)){
        Write-Warning 'Mask Length error, you can try put WildCard'; break
    }
    if(!$WildCard){
        [IPAddress]$WildCard = $SplitMask.ForEach({255 - $_}) -join '.'
    }
    if($WildCard){
        [int[]]$SplitWildCard = $WildCard.GetAddressBytes()
    }

    [IPAddress]$Subnet = $IPAddress.Address -band $Mask.Address
    [int[]]$SplitSubnet = $Subnet.GetAddressBytes()
    [string]$SubnetBin = $SplitSubnet.ForEach({[System.Convert]::ToString($_,2).PadLeft(8,'0')}) -join '.'
    [IPAddress]$Broadcast = @(0..3).ForEach({[int]($SplitSubnet[$_]) + [int]($SplitWildCard[$_])}) -join '.'
    [int[]]$SplitBroadcast = $Broadcast.GetAddressBytes()
    [string]$BroadcastBin = $SplitBroadcast.ForEach({[System.Convert]::ToString($_,2).PadLeft(8,'0')}) -join '.'
    [string]$CIDR = "$($Subnet.IPAddressToString)/$PrefixLength"
    [int64]$IPcount = [System.Math]::Pow(2,$(32 - $PrefixLength))

    $Object_ = [ordered]@{
        IPAddress = $IPAddress.IPAddressToString
        Mask = $Mask.IPAddressToString
        PrefixLength = $PrefixLength
        WildCard = $WildCard.IPAddressToString
        IPcount = $IPcount
        Subnet = $Subnet
        Broadcast = $Broadcast
        CIDR = $CIDR
        ToDecimal = $ToDecimal
        IPBin = $IPBin
        MaskBin = $MaskBin
        SubnetBin = $SubnetBin
        BroadcastBin = $BroadcastBin
        PSTypeName = 'NetWork.IPCalcResult'
    }
    
    [string[]]$DefaultProperties = @('IPAddress','Mask','PrefixLength','WildCard','IPcount','Subnet','Broadcast','CIDR','ToDecimal','IPBin','MaskBin','SubnetBin','BroadcastBin')
    
    if ($CreateIParray){
        $w,$x,$y,$z =  @($SplitSubnet[0]..$SplitBroadcast[0]),@($SplitSubnet[1]..$SplitBroadcast[1]),@($SplitSubnet[2]..$SplitBroadcast[2]),@($SplitSubnet[3]..$SplitBroadcast[3])
        $IParray = $w.ForEach({$wi = $_; $x.ForEach({$xi = $_; $y.ForEach({$yi = $_; $z.ForEach({$zi = $_; $wi,$xi,$yi,$zi -join '.'})})})})
        $Object_['IParray'] = $IParray
        $DefaultProperties += 'IParray'
    }
        
    $Object = [pscustomobject]$Object_
    
    Add-Member -InputObject $Object -MemberType:ScriptMethod -Name Add -Value {
        param([int]$Add,[int]$PrefixLength = $This.PrefixLength)
        IP-Calc -IPAddress ([IPAddress]([String]$($This.ToDecimal + $Add))).IPAddressToString -PrefixLength $PrefixLength
    }
    
    Add-Member -InputObject $Object -MemberType:ScriptMethod -Name Compare -Value {
        param ([Parameter(Mandatory=$true)][IPAddress]$IP)
        $IPBin = -join (($IP)).GetAddressBytes().ForEach({[System.Convert]::ToString($_,2).PadLeft(8,'0')})
        $SubnetBin = $This.SubnetBin.Replace('.','')
        for ($i = 0; $i -lt $This.PrefixLength; $i += 1) {if ($IPBin[$i] -ne $SubnetBin[$i]) {return $false}}
        return $true
    }
    
    $PSPropertySet = New-Object -TypeName System.Management.Automation.PSPropertySet -ArgumentList @('DefaultDisplayPropertySet',$DefaultProperties)
    $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]$PSPropertySet 
    Add-Member -InputObject $Object -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers
    
    Add-Member -InputObject $Object -MemberType AliasProperty -Name IP -Value IPAddress
    
    if(!$CreateIParrayPassThru){
        $Object
    }else{
        $Object.IParray
    }