forked from BornToBeRoot/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Get-IPv4Subnet.ps1
151 lines (117 loc) · 5.39 KB
/
Get-IPv4Subnet.ps1
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
###############################################################################################################
# Language : PowerShell 4.0
# Filename : Get-IPv4Subnet.ps1
# Autor : BornToBeRoot (https://github.com/BornToBeRoot)
# Description : Calculate a subnet based on an IP-Address and the subnetmask or CIDR
# Repository : https://github.com/BornToBeRoot/PowerShell
###############################################################################################################
<#
.SYNOPSIS
Calculate a subnet based on an IP-Address and the subnetmask or CIDR
.DESCRIPTION
Calculate a subnet based on an IP-Address within the subnet and the subnetmask or CIDR. The result includes the NetworkID, Broadcast, total available IPs and usable IPs for hosts.
.EXAMPLE
Get-IPv4Subnet -IPv4Address 192.168.24.96 -CIDR 27
NetworkID Broadcast IPs Hosts
--------- --------- --- -----
192.168.24.96 192.168.24.127 32 30
.EXAMPLE
Get-IPv4Subnet -IPv4Address 192.168.1.0 -Mask 255.255.255.0 | Select-Object -Property *
NetworkID : 192.168.1.0
FirstIP : 192.168.1.1
LastIP : 192.168.1.254
Broadcast : 192.168.1.255
IPs : 256
Hosts : 254
.LINK
https://github.com/BornToBeRoot/PowerShell/blob/master/Documentation/Function/Get-IPv4Subnet.README.md
#>
function Get-IPv4Subnet
{
[CmdletBinding(DefaultParameterSetName='CIDR')]
param(
[Parameter(
Position=0,
Mandatory=$true,
HelpMessage='IPv4-Address which is in the subnet')]
[IPAddress]$IPv4Address,
[Parameter(
ParameterSetName='CIDR',
Position=1,
Mandatory=$true,
HelpMessage='CIDR like /24 without "/"')]
[ValidateRange(0,31)]
[Int32]$CIDR,
[Parameter(
ParameterSetName='Mask',
Position=1,
Mandatory=$true,
Helpmessage='Subnetmask like 255.255.255.0')]
[ValidateScript({
if($_ -match "^(254|252|248|240|224|192|128).0.0.0$|^255.(254|252|248|240|224|192|128|0).0.0$|^255.255.(254|252|248|240|224|192|128|0).0$|^255.255.255.(254|252|248|240|224|192|128|0)$")
{
return $true
}
else
{
throw "Enter a valid subnetmask (like 255.255.255.0)!"
}
})]
[String]$Mask
)
Begin{
}
Process{
# Convert Mask or CIDR - because we need both in the code below
switch($PSCmdlet.ParameterSetName)
{
"CIDR" {
$Mask = (Convert-Subnetmask -CIDR $CIDR).Mask
}
"Mask" {
$CIDR = (Convert-Subnetmask -Mask $Mask).CIDR
}
}
# Get CIDR Address by parsing it into an IP-Address
$CIDRAddress = [System.Net.IPAddress]::Parse([System.Convert]::ToUInt64(("1"* $CIDR).PadRight(32, "0"), 2))
# Binary AND ... this is how subnets work.
$NetworkID_bAND = $IPv4Address.Address -band $CIDRAddress.Address
# Return an array of bytes. Then join them.
$NetworkID = [System.Net.IPAddress]::Parse([System.BitConverter]::GetBytes([UInt32]$NetworkID_bAND) -join ("."))
# Get HostBits based on SubnetBits (CIDR) // Hostbits (32 - /24 = 8 -> 00000000000000000000000011111111)
$HostBits = ('1' * (32 - $CIDR)).PadLeft(32, "0")
# Convert Bits to Int64
$AvailableIPs = [Convert]::ToInt64($HostBits,2)
# Convert Network Address to Int64
$NetworkID_Int64 = (Convert-IPv4Address -IPv4Address $NetworkID.ToString()).Int64
# Calculate the first Host IPv4 Address by add 1 to the Network ID
$FirstIP = [System.Net.IPAddress]::Parse((Convert-IPv4Address -Int64 ($NetworkID_Int64 + 1)).IPv4Address)
# Calculate the last Host IPv4 Address by subtract 1 from the Broadcast Address
$LastIP = [System.Net.IPAddress]::Parse((Convert-IPv4Address -Int64 ($NetworkID_Int64 + ($AvailableIPs - 1))).IPv4Address)
# Convert add available IPs and parse into IPAddress
$Broadcast = [System.Net.IPAddress]::Parse((Convert-IPv4Address -Int64 ($NetworkID_Int64 + $AvailableIPs)).IPv4Address)
# Change useroutput ==> (/27 = 0..31 IPs -> AvailableIPs 32)
$AvailableIPs += 1
# Hosts = AvailableIPs - Network Address + Broadcast Address
$Hosts = ($AvailableIPs - 2)
# Build custom PSObject
$Result = [pscustomobject] @{
NetworkID = $NetworkID
FirstIP = $FirstIP
LastIP = $LastIP
Broadcast = $Broadcast
IPs = $AvailableIPs
Hosts = $Hosts
}
# Set the default properties
$Result.PSObject.TypeNames.Insert(0,'Subnet.Information')
$DefaultDisplaySet = 'NetworkID', 'Broadcast', 'IPs', 'Hosts'
$DefaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$DefaultDisplaySet)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($DefaultDisplayPropertySet)
$Result | Add-Member MemberSet PSStandardMembers $PSStandardMembers
# Return the object to the pipeline
$Result
}
End{
}
}