Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to configure DHCP address conflict detection.
Microsoft Scripting Guy, Ed Wilson, is here. Well, it’s the weekend here in Charlotte, North Carolina. This morning it is foggy, and the air is crisp but not cold. The naked trees in my front yard seem content despite the occasional forlorn abandoned bird nest. I decide to open the windows on our lanai and sip on a cup of English Breakfast tea with a bit of organic rose petals and a cinnamon stick. I think back over the week and decide there are still a couple of things I want to do with the Windows PowerShell DHCP server module.
Note This is the third article in a series of Hey, Scripting Guy! Blog posts where I talk about using Windows PowerShell to work with Microsoft DHCP servers. I began the series with Use PowerShell to Query AD DS for DHCP Servers, in which I talked about using the Get-ADObject cmdlet to query for DHCP servers. I followed this with Use PowerShell Functions to Authorize DHCP Servers.
In this blog post, I talk about using several Windows PowerShell functions from the DHCPServer module. I query for DHCP servers, authorize DHCP servers, and deauthorize DHCP servers in this article. Today’s article builds on these articles, and I would recommend you read them in order because the concepts build, and I am not level-setting in each article.
Sending DHCP server addresses over the pipeline
In an enterprise setting, having more than one DHCP server is likely. To make specific configuration changes to all of the servers requires querying to find the authorized DHCP servers that reside in Active Directory Domain Services (AD DS). As I illustrated yesterday, I can use a function from the DHCPServer module to query for authorized DHCP servers. This command and its associated output appear here.
PS C:\> Get-DhcpServerInDC
IPAddress DnsName
--------- -------
192.168.0.152 wds1.iammred.net
Cool, now I want to pipe this DHCP server information to the Get-DHCPServerSetting cmdlet. Unfortunately, as shown in the image here, an error arises from the command.
Ok, so this is not going to be as easy as it could be. Now, I need to see what properties return from the Get-DHCPServerInDC function and compare it with the input syntax for the Get-DHCPServerSetting function. I pipe the first function to Format-List, for the second function, I use Get-Help, and I expand the syntax. The commands and associated output from those commands are shown in the image here.
Dude, that is not a problem. I can use the DNSName property and supply it to the ComputerName property. No sweat! So I use an Up Arrow, and change the command a bit, and quickly press Enter. Bummer! An error arises. In fact, this time it appears to be a bogus error because it says the parameter is null or empty, and I know good and well that my first cmdlet returns information for that property. The clue here is that it says it cannot validate the argument for ComputerName. The command and associated error are shown here.
Look back at the permissible value for the ComputerName parameter for Get-DHCPSetting—it only accepts a single value and not an array. Using this as a clue, I pipe the results of Get-DHCPServerInDC to the Foreach-Object cmdlet, and then I work with a single item (shades of VBScript Batman!).
Note Here Get-DHCPServerInDC returns a single server object. But it could return multiple values, and therefore, it appears as an array. Supplying an array to a parameter that wants a single item causes the error seen in the previous image. Sending single items through Foreach was a standard scripting technique in the old-fashioned VBScript days.
The revised command appears here, along with the associated output.
PS C:\> Get-DhcpServerInDC | % {Get-DhcpServerSetting -ComputerName $_.dnsname}
IsDomainJoined : True
IsAuthorized : True
DynamicBootp : True
RestoreStatus : False
ConflictDetectionAttempts : 0
NpsUnreachableAction : Full
NapEnabled : False
ActivatePolicies : True
Setting DHCP conflict detection
DHCP conflict detection attempts determine whether the DHCP server sends a test ping for an available IP address prior to handing out the address to a DHCP client. A successful ping means that the IP address currently exists on the network; therefore, the DHCP server does not hand out that address.
A ping request failure means the address does not exist and therefore the DHCP server will hand out that address. This is useful in scenarios in which you set up a new DHCP server to take over handing out address from a failed server when no backup exists, and therefore, there is no record of addresses from the scope that are in existence.
Because the DHCP server with IP address conflict detection checks for address existence prior to handing the address out to the DHCP client, IP address conflicts should not be a problem. Obviously, this is an exception case, and by default, IP address conflict detection is off.
The default value for conflict detection attempts is zero, but I can set the value between zero and six. Each number (1..6) determines the number of pings issued before handing out the IP address to a DHCP client. Each additional attempt adds 1 second to the amount of time a DHCP client waits prior to receiving the address.
Therefore, setting the conflict detection attempts to six would cause a six-second delay for each client requesting an IP address. This increases the load on the DHCP server. The Best Practice Analyzer for Dynamic Host Configuration Protocol (DHCP) generates a warning if the IP address conflict detection has a value greater than 3. TechNet recommends a value of no greater than two for this parameter.
To set DHCP server IP address conflict detection attempts to two, I use the Windows PowerShell Set-DHCPServerSetting function—it has a ConflictDetectionAttemptsparameter. Here is the command I use to make this change to every DHCP server in the enterprise.
Get-DhcpServerInDC |
% {Set-DhcpServerSetting -ComputerName $_.dnsname -ConflictDetectionAttempts 2}
I then use the Up Arrow to check to ensure the changes took place. The use of the two commands and the associated output are shown here.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy