In an earlier post “Active Directory Powershell to manage sites – Part 1 (New-XADSite)” Jairo explained in detail about how to create a Site in Active Directory using AD Powershell. In today’s post I am going to discuss about how to create Subnets using AD Powershell.
Before going into details of creating a subnet object, first let us understand what is a Site and Subnet.
The following definition is from: http://technet.microsoft.com/en-us/library/cc782048(WS.10).aspx
In Active Directory, a site is a set of computers well-connected by a high-speed network, such as a local area network (LAN). All computers within the same site typically reside in the same building, or on the same campus network. A single site consists of one or more Internet Protocol (IP) subnets. Subnets are subdivisions of an IP network, with each subnet possessing its own unique network address. A subnet object in AD DS groups neighboring computers in much the same way that postal codes group neighboring postal addresses. Sites and subnets are represented in Active Directory by site and subnet objects. Each site object is associated with one or more subnet objects. By associating a site with one or more subnets, you assign a set of IP addresses to the site.
In Active Directory, a site is a set of computers well-connected by a high-speed network, such as a local area network (LAN). All computers within the same site typically reside in the same building, or on the same campus network. A single site consists of one or more Internet Protocol (IP) subnets. Subnets are subdivisions of an IP network, with each subnet possessing its own unique network address. A subnet object in AD DS groups neighboring computers in much the same way that postal codes group neighboring postal addresses.
Sites and subnets are represented in Active Directory by site and subnet objects. Each site object is associated with one or more subnet objects. By associating a site with one or more subnets, you assign a set of IP addresses to the site.
NOTE: The term "subnet" in AD DS does not have the strict networking definition of the set of all addresses behind a single router. The only requirement for an AD DS subnet is that the address prefix conforms to the IP version 4 (IPv4) or IP version 6 (IPv6) format.
A subnet object (objectClass=subnet) in AD DS stores the prefix information in its name and the site information in attribute siteObject. It should be created under “CN=Subnets,CN=Sites,<Configuration-NC>”. For documentation on “how to determine the prefix of a subnet” bing for the phrase “Entering Address Prefixes”.
I have written a function below called New-XADSubnet that creates a new subnet. It accepts the subnet-prefix, site name, description and location of the subnet as input. The function also does some validation to provide a reliable experience, for example: it validates whether the specified subnet prefix length is correct or not. If a prefix length is not specified then this function will auto-generate the prefix length based on the number of trailing zero bits found in the prefix-ip-address.
NOTE: The script below uses Test-XADObject function published in a previous post.
1: #
2: # Advanced Function to create a new subnet.
3: #
4: function New-XADSubnet() {
5: [CmdletBinding(ConfirmImpact="Low")]
6: Param (
7: [Parameter(Mandatory=$true,
8: Position=0,
9: ValueFromPipeline=$true,
10: HelpMessage="Prefix of the subnet to be created. This should be a combination of IP Address followed by / and Prefix length. IPv4 example: 157.54.208.0/20 IPv6 example: 3FFE:FFFF:0:C000::/64 . NOTE: If the prefix length is not specified then this cmdlet will auto-generate the prefix length based on the number of trailing zero bits. For example: If supplied Prefix is 157.54.208.0 then the subnet created is 157.54.208.0/20. Another example: If supplied Prefix is 3FFE:FFFF:0:C000:: then the subnet created is 3FFE:FFFF:0:C000::/34"
11: )]
12: [String] $Prefix,
13: [Parameter(Mandatory=$false,
14: Position=1,
15: ValueFromPipeline=$false,
16: HelpMessage="Site to which the subnet will be applied. Accepts Site name, Guid, DN or ADObject representing the site"
17: )]
18: [Object] $Site,
19: [Parameter(Mandatory=$false,
20: ValueFromPipeline=$false,
21: HelpMessage="Description"
22: )]
23: [String] $Description,
24: [Parameter(Mandatory=$false,
25: ValueFromPipeline=$false,
26: HelpMessage="Location"
27: )]
28: [String] $Location
29: )
30: PROCESS {
31:
32: if ([String]::IsNullOrEmpty($Prefix)) {
33: throw New-Object System.Management.Automation.PSArgumentException("Prefix name cannot be an empty string, please try again.")
34: }
35:
36: $newSubnetName = $Prefix
37:
38: if ($Prefix.Contains("/")) {
39: $subnetIPAddressStr,$prefixLengthStr = $newSubnetName.Split("/")
40: $subnetIPAddress = [System.Net.IPAddress]::Parse($subnetIPAddressStr)
41: $specifiedPrefixLength = [int]::Parse($prefixLengthStr)
42:
43: $ipAddressPrefixLength = GetIPAddressPrefixLength $subnetIPAddress
44: if ($ipAddressPrefixLength -gt $specifiedPrefixLength) {
45: throw New-Object System.Management.Automation.PSArgumentException("The subnet prefix length you specified is incorrect. Please check the prefix and try again.")
46: }
47:
48: } else {
49: $subnetIPAddress = [System.Net.IPAddress]::Parse($newSubnetName)
50: $prefixLength = GetIPAddressPrefixLength $subnetIPAddress
51: $newSubnetName = $newSubnetName + "/" + $prefixLength
52: }
53:
54: # Get the configuration partition DN, the sites container and build the new site DN
55: $configNCDN = (Get-ADRootDSE).ConfigurationNamingContext
56: $subnetContainerDN = ("CN=Subnets,CN=Sites," + $configNCDN)
57: $newSubnetDN = ("CN=" + $newSubnetName +"," + $subnetContainerDN)
58: $siteDN = $null
59: if ($Site -ne $null) {
60: $siteDN = (Get-XADSite $Site).DistinguishedName
61: }
62:
63: # Verify if the subnet already exists
64: $subnetExists = Test-XADObject -Identity $newSubnetDN
65: if ($subnetExists) {
66: throw New-Object System.Management.Automation.PSArgumentException("Subnet already exists. Please check the name and try again.")
67: }
68:
69: [Hashtable] $ht = new-object -type hashtable
70: if ($siteDN -ne $null) {
71: $ht.Add("siteObject", $siteDN)
72: }
73: if (-not [String]::IsNullOrEmpty($Description)) {
74: $ht.Add("description", $Description)
75: }
76: if (-not [String]::IsNullOrEmpty($Location)) {
77: $ht.Add("location", $Location)
78: }
79:
80:
81: # Create subnet object
82: if ($ht.Count -eq 0) {
83: New-ADObject -Name $newSubnetName -Path $subnetContainerDN -Type subnet
84: } else {
85: New-ADObject -Name $newSubnetName -Path $subnetContainerDN -Type subnet -OtherAttributes $ht
86: }
87:
88: # Fetch the subnet object
89: Get-ADObject $newSubnetDN -properties "siteObject", "description", "location"
90:
91: }
92: }
93:
94:
95:
96: #
97: # Internal utility function
98: # This function returns the number of trailing zeroes in the input byte
99: #
100: function GetNumberOfTrailingZeroes {
101: Param ([byte] $x)
102: $numOfTrailingZeroes = 0;
103: if ( $x -eq 0) {
104: return 8
105: }
106: if ( $x % 2 -eq 0) {
107: $numOfTrailingZeroes ++;
108: $numOfTrailingZeroes += GetNumberOfTrailingZeroes($x/2);
109: }
110: return $numOfTrailingZeroes
111: }
112:
113:
114:
115:
116: #
117: # Internal utility function
118: # This function returns the number of non-zero bits in an ip-address
119: #
120: function GetIPAddressPrefixLength {
121: Param ([System.Net.IPAddress] $ipAddress)
122: $byteArray = $ipAddress.GetAddressBytes()
123: $numOfTrailingZeroes = 0;
124: for ($i = $byteArray.Length - 1; $i -ge 0; $i--) {
125: $numOfZeroesInByte = GetNumberOfTrailingZeroes($byteArray[$i]);
126: if ($numOfZeroesInByte -eq 0) {
127: break;
128: }
129: $numOfTrailingZeroes += $numOfZeroesInByte;
130: }
131: (($byteArray.Length * 8) - $numOfTrailingZeroes)
132: }
Sample usage in my test environment:
PS AD:\>PS AD:\> New-XADSubnet "10.10.0.0/16" -Location "Redmond,WA" -Description "Redmond Subnet" Description : Redmond SubnetDistinguishedName : CN=10.10.0.0/16,CN=Subnets,CN=Sites,CN=Configuration,DC=dsw amipat-w7-vm1,DC=nttest,DC=microsoft,DC=comlocation : Redmond,WAName : 10.10.0.0/16ObjectClass : subnetObjectGUID : e4c924ff-ee39-47e3-8b92-71a8600188af
PS AD:\>PS AD:\> New-XADSubnet "10.10.0.0/16" -Location "Redmond,WA" -Description "Redmond Subnet"
Description : Redmond SubnetDistinguishedName : CN=10.10.0.0/16,CN=Subnets,CN=Sites,CN=Configuration,DC=dsw amipat-w7-vm1,DC=nttest,DC=microsoft,DC=comlocation : Redmond,WAName : 10.10.0.0/16ObjectClass : subnetObjectGUID : e4c924ff-ee39-47e3-8b92-71a8600188af
Cheers,
Swami
--
Swaminathan Pattabiraman
Developer – Active Directory Powershell Team