Networking is fundamental to all organizations. Your servers and client systems communicate with each other via your network. Your users access a myriad of devices via your internal networks. Your internal networks connect to the Internet to help your users and customers interact. It is no surprise that PowerShell supports you in configuring and managing your network.
Networking has been built into Windows more or less since its beginning. Windows for Workgroups 3.11 contained built‐in networking, as did Windows NT 3.1. But the later versions of NT (including Windows 10 and Windows Server 2019) come with a TCP/IP stack that supports both IPv4 and IPv6.
This chapter looks at how to use PowerShell to configure a network, how to test for network connectivity, and how to set up, configure, and manage both Dynamic Host Configuration Protocol (DHCP) and Domain Name Service (DNS).
DC1.Reskit.Org
into an IP address. Once the host resolves the IP address, the TCP/IP stack can connect to the remote system and interoperate with the remote host. As you see in “Implement a Standalone DNS Server,” adding DNS to Windows Server 2019 is simple.In this chapter, you use PowerShell 7 to manage various networking aspects. The scripts in this chapter make use of the following servers:
DC1
provided DNS services for the
Reskit.Org
domain. This chapter extends the DNS service.For the purposes of this chapter, you should ensure that DNS is set up and working on this server (Chapter 3, “Managing Active Directory,” shows how to set up DNS Servers while installing Active Directory).
Figure 4.1 shows the systems in use in this chapter.
Figure 4.1: Systems used in this chapter
You also need to have PowerShell 7 and, optionally, Visual Studio Code (VS Code) installed on each host. You can use the scripts shown in Chapter 1 for this purpose.
The setup process you use when you install Windows on any host does a great job of detecting the network adapters built into your system's “hardware.” That includes both the physical hardware components in your computer and any virtual hardware you provision inside a virtual machine. In both cases, after the setup process has completed, your NICs are detected and set to get their IP address and other configuration details via DHCP.
If you are installing client computers, this is a great default—install Windows, and networking just works. Server systems, however, generally need to be configured manually, as we do in this chapter's first example. Some organizations use DHCP to assign IP configuration to server systems but make use of a DHCP reservation. Each server gets its correct address with the configured DHCP options. This chapter does not show that approach.
You run the code in this section on
SRV2.Reskit.Org
, which you build using Windows Server 2019 installed with the Desktop Experience feature. As noted earlier, the default Windows Server Installation sets the server's single NIC to get IP address information from DHCP. If you created the
SRV2
server using the Reskit build scripts on GitHub (github.com/doctordns/ReskitBuildScripts), then you would have set up
SRV2
to have a static IP address. In this case, before running the following code, you can use
ncpa.cpl
to change the IPv4 settings to get an address from DHCP.
You also need to have PowerShell 7 and, optionally, VS Code installed on all systems.
Before updating your server's IP address, it is useful to check the current state of the network adapter. You can do this as follows:
# 1. Get the adapter, adapter Interface and Adapter Interface Index
# for later use
$IPType = 'IPv4'
$Adapter = Get-NetAdapter |
Where-Object Status -eq 'Up'
$Interface = $Adapter |
Get-NetIPInterface -AddressFamily $IPType
$Index = $Interface.IfIndex
Get-NetIPAddress -InterfaceIndex $Index -AddressFamily $IPType |
Format-Table -Property Interface*, IPAddress, PrefixLength
This code returns the IP address details shown in Figure 4.2. Note that with no DHCP server on the network and the VM configured to use any virtual switch but the default, the IP address for
SRV2
is in the 169.254.0.0/16 network range (also known as automatic private IP addressing, or APIPA, range).
Figure 4.2: IP address details returned after checking the current state
As mentioned earlier, by default the Windows setup process detects each NIC in the host and configures it to get IPv4 configuration via DHCP. And by default, when creating a new VM, Hyper‐V adds a single NIC to the VM, which it sets to get an IPv4 address via DHCP. If you used the Reskit build scripts in GitHub (github.com/doctordns/ReskitBuildScripts), the scripts assign a static IPv4 address to this host. Consider using
ncpa.cpl
to reset the NIC to the default of getting IPv4 configuration details from DHCP.
Once you confirm that the server's NIC is set to DHCP, use the following code to configure the NIC to have a specific IPv4 address, subnet, and default gateway:
# 2. Set a new IP address for the NIC, and then check it
$IPHT = @{
InterfaceIndex = $Index
PrefixLength = 24
IPAddress = '10.10.10.51'
DefaultGateway = '10.10.10.254'
AddressFamily = $IPType # IPv4
}
New-NetIPAddress @IPHT | Out-Null
This sets the NIC's IP address and subnet mask. It can take a few seconds to create this new address.
You can use the
Get‐NetIPAddress
command to verify the new IP address, as follows:
# 3. Verify the new IP address
Get-NetIPAddress -InterfaceIndex $Index -AddressFamily $IPType |
Format-Table IPAddress, InterfaceIndex, PrefixLength
Figure 4.3 shows the output from this snippet.
Figure 4.3: Verifying the NIC IP address
You should now see the specified IPv4 address of 10.10.10.51 and no longer an IP address in the APIPA range.
Using the
New‐NetIPAddress
cmdlet only sets the NIC's IP address, subnet mask, and default gateway. You also need to configure the NIC to use a specific IP address for the DNS server as follows:
# 4. Set DNS Server IP address
$CAHT = @{
InterfaceIndex = $Index
ServerAddresses = '10.10.10.10'
}
Set-DnsClientServerAddress @CAHT
Once you complete these steps, you can validate your IP address settings as well as do some basic connectivity testing, with the following code:
# 5. Verify the New IP configuration
# Verify the IPv4 address is set as required
Get-NetIPAddress -InterfaceIndex $Index -AddressFamily IPv4
# Test that SRV2 can see the domain controller
Test-NetConnection -ComputerName DC1.Reskit.Org
# Test the DNS server on DC1.Reskit.Org correctly resolves
# the A record for SRV2.
Resolve-DnsName -Name SRV2.Reskit.Org -Server DC1.Reskit.Org -Type A
The output of these three steps looks like Figure 4.4.
Figure 4.4: Verifying the new IP configuration
Once you have configured networking and an IP address on a system, it is useful to test the connectivity to other servers and services on the network and indeed to the Internet.
Before PowerShell was available, we used tools such as
ipconfig.exe
,
tracert.exe
,
ping.exe
, and
pathping.exe
to test and verify network connectivity. Today, we can use two PowerShell commands:
Test‐Connection
and
Test‐NetConnection
. These newer commands return objects, which makes automation easier.
Test‐Connection
sends Internet Control Message Protocol (ICMP) Echo Request packets to a remote machine and looks for an ICMP Echo Reply response. The command‐line tool
ping.exe
also uses ICMP Echo Request/Reply. This works well on most intranet LANs, but across the Internet or on more secure networks, it may not help because many routers, and hosts, simply drop ICMP Echo requests.
Test‐NetConnection
allows you to test an actual connection to a specific port on the remote server. While a web server or a router might drop ICMP packets, you should be able to connect to that server over specific service‐related TCP ports. You can test the connection either with a “well‐known” port name (such as SMB for testing SMB connectivity to the remote machine) or with a specific port number.
For this section, you need two systems up and running:
DC1.Reskit.Org
and
SRV2.Reskit.Org
. Note that
SRV2.Reskit.Org
is the system you are testing connectivity from.
DC1.Reskit.Org
is the system you are attempting to connect with. You configured
SRV2.Reskit.Org
with an IP address in “Configuring IP Addressing.”
Note also that
SRV2.Reskit.Org
is a domain‐joined server in the
Reskit.Org
domain and that
DC1.Reskit.Org
is both a DNS server and a domain controller.
One of the first things to verify is whether TCP/IP connectivity to the local loopback address is up and working, using
Test‐Connection
and
Test‐NetConnection
.
# 1. Verify SRV2 itself is up and that loopback is working
Test-Connection -ComputerName SRV2 -Count 1 -IPv4
Test-NetConnection -ComputerName SRV2 -CommonTCPPort WinRM
These commands check that the TCP/IP client is working and can connect via the loopback. The output of this step looks like Figure 4.5.
Figure 4.5: Testing the TCP/IP stack
Note that both commands can, by default, use either IPv4 or IPv6 to test the connection.
Test‐Connection
enables you to specify explicitly to use IPv4 (or IPV6).
Because
SRV2.Reskit.Org
is joined to a domain, the next thing to check is that basic connectivity to the domain controller (
DC1.Reskit.Org
) exists, as follows:
# 2. Test Basic Connectivity to the DC
Test-Connection -ComputerName DC1.Reskit.Org -Count 1
Assuming the domain controller is up and running, the expected output from this command should resemble Figure 4.6.
Figure 4.6: Verifying connectivity to
DC1
For reliable domain operations,
SRV2.Reskit.Org
needs to be able to connect to the LDAP and SMB ports on the DC. A Windows host also needs SMB access to the domain controller to obtain Group Policy objects, including login scripts. LDAP access is also necessary to enable logon and other domain activities. You can test SMB and LDAP using
Test‐NetConnection
.
# 3. Check Connectivity to SMB port and to LDAP port
Test-NetConnection -ComputerName DC1.Reskit.Org -CommonTCPPort SMB
Test-NetConnection -ComputerName DC1.Reskit.Org -Port 389
In Figure 4.7, you can see the expected output of these tests.
Figure 4.7: Verifying SMB/LDAP connectivity to DC1
A final test of network connectivity is to verify that the server can see the Internet. Whether or not a given server should be able to access systems on the Internet is a matter of your local policy. For many organizations, however, connectivity might be vital, and you can test using
Test‐NetConnection
and specifying an address somewhere on the Internet. Assuming you have Internet access (an external network adapter) configured, you can test a path as follows:
# 4. Examine path to a remote server on the Internet
$NCHT = @{
ComputerName = 'WWW.Wiley.Com'
TraceRoute = $true
InformationLevel = 'Detailed'
}
Test-NetConnection @ncht # Check our wonderful publisher
The results of this command may vary significantly (particularly the traceroute section) depending on where you execute it from, but the output should look like Figure 4.8.
Figure 4.8: Verifying access to an Internet server
In this figure, you can see that the site, www.wiley.com, resolves to four servers. The starting point and the path to www.wiley.com will vary depending where you are in the world. And given how often things change, it is entirely possible that the target IP addresses have changed.
The path taken from
SRV2
through the Internet shows several hops where the ICMP Echo Request was dropped, but you can see that the final hop is to one of the four servers answering to
WWW.Wiley.Com
. This is not uncommon with some of the Internet's core routers that routinely drop ICMP Echo Requests. It is not relevant if an intermediate router, like those shown in Figure 4.8, fails to respond, so long as it is routing other packets properly, as is the case here. This is another reason PowerShell's
Test‐NetConnection
cmdlet is an improvement over
ping.exe
.
It is worth noting that the
Test‐NetConnection
cmdlet has been re‐engineered in PowerShell 7. This command is now considerably quicker than in Windows PowerShell.
The Dynamic Host Configuration Protocol (DHCP) allows hosts to discover IP address details at run time. Addresses and IP configuration options are specified on a DHCP server. Setting up a DHCP service is straightforward. DHCP is a Windows Server feature that you install with the
Install‐WindowsFeature
cmdlet.
Once you install the DHCP Server service in Windows Server, you must authorize it explicitly within Active Directory. Authorization enables protection against rogue DHCP servers. The Windows DHCP Server service inside Windows Server 2019 checks to see whether it is authorized before starting up.
At the time of writing, the DHCP Server module is not supported natively in PowerShell 7. To get around this limitation, you use the Windows Compatibility feature described in Chapter 2.
You should have a Windows Server 2019 host,
DC1.Reskit.Org
, that you are going to set up to be a DHCP server. This host is also a domain controller in the
Reskit.Org
domain. You should have a second Windows 2019 host,
DC2.Reskit.Org
, that you use as part of a DHCP failover/load balancing implementation in “Configuring DHCP Failover.”
You also need to ensure PowerShell 7 and, optionally, VS Code are up and running on these hosts as in previous sections.
Also, if you have added NICs to the VM, for example to enable Internet access, to test this section consider temporarily disabling those extra NICs to enable the server to get a DHCP address.
Installing the DHCP Server service is straightforward since it is a Windows feature. You install the DHCP service on the domain controller,
DC1
, by using the
Install‐WindowsFeature
cmdlet.
# 1. Install the DHCP Feature on DC1 and add the Management tools
Import-Module -Name ServerManager -WarningAction SilentlyContinue
Install-WindowsFeature -Name DHCP -IncludeManagementTools
Once the Server Manager module is loaded, you can invoke the cmdlets, to produce the output shown in Figure 4.9.
Figure 4.9: Installing the DHCP service
In this case, you are installing the DHCP Server service on a domain controller that is also a DNS server. This is a best‐practice configuration that minimizes network traffic between DNS, AD, and DHCP.
Before your DHCP server can start the DHCP service, you must authorize the DHCP server explicitly in Active Directory. This prevents against the risk of a rogue DHCP server—one that curious users might decide to explore. A rogue DHCP could issue conflicting IP addresses or issue addresses to rogue gateways and/or DNS servers, thus compromising your network. If the DHCP service starts up (for example after you install it), the service checks whether it's been authorized in the AD and if not shuts down.
You also use the
Add‐DHCPSecurityGroup
cmdlet to add a set of security groups. This cmdlet adds two domain groups:
DHCP Users
and
DHCP Administrators
as well as the
DHCP Users
local security groups on the DHCP server. You do this as follows:
# 2. Add DC1 to Trusted DHCP Servers and add the DHCP Security Group
Import-Module -Name DHCPServer -WarningAction SilentlyContinue
Add-DhcpServerInDC
Add-DHCPServerSecurityGroup
This snippet produces no output. Once you run this snippet, you can use the cmdlet
Get‐DHCPServerInDC
to view the authorized DHCP server and the
Get‐LocalGroup
cmdlet to view the local groups on the DHCP server.
You complete the configuration of the DHCP service by updating the registry to indicate to Windows that the DHCP server is installed and ready to be used. The code to do this is as follows:
# 3. Let DHCP know it's all configured
$DHCPHT = @{
Path = 'HKLM:\SOFTWARE\Microsoft\ServerManager\Roles\12'
Name = 'ConfigurationState'
Value = 2
}
Set-ItemProperty @DHCPHT
Setting registry values in this way produces no output.
With the DHCP service now configured, you can restart the service as follows:
# 4. Restart DHCP Server
Restart-Service -Name DHCPServer -Force
Restarting the server does not produce any output, although you may see warning messages as Windows stops and then restarts the DHCP service. When you restart the service, because the DHCP server has been authorized in the DHCP, it is ready to issue IP addresses once your DHCP scopes are created.
Now that the DHCP Server service is authorized, restarting the service should show it up and running. Because you have not yet configured a DHCP scope, the service is not going to hand out addresses, so at this stage you simply check that the DHCP service is up and running and is set to start automatically. You can use the
Get‐Service
command to return this information, as follows:
# 5. Test service availability
Get-Service -Name DHCPServer |
Format-List -Property *
The output of this step looks like Figure 4.10.
Figure 4.10: Checking the DHCP service
You have installed DHCP and performed basic configuration. Your next step in deploying DHCP is to create one or more scopes.
After you have the DHCP service authorized in AD and running, you need to configure your DHCP server with the IP address ranges and options to provide to DHCP clients.
To do this, you set up one or more scopes, configure the scopes with the appropriate option and options values, and then test to ensure that client computers can obtain IP addresses from this system.
A DHCP scope is a range of IP addresses within an IP network that the DHCP server can offer to DHCP clients. Its various configuration options are values that a DHCP client can request, such as the default gateway or DNS server IP address. Once configured, your DHCP server can issue these option values to any client that requests them.
You can define scope‐specific options that apply only to IP addresses handed out with a specific DHCP scope. Alternatively, you can configure options at the server level, enabling the options to be supplied to all scopes defined on the server.
For more information about the deployment of DHCP, see docs.microsoft.com/en-us/windows-server/networking/technologies/dhcp/dhcp-deploy-wps.
This section assumes you have already installed and authorized the DHCP service on
DC1.Reskit.Org
, which is also the domain controller in the
Reskit.Org
domain.
You create an IPv4 DHCP scope by using the
Add‐DhcpServerV4Scope
command. You specify the IP block in which the DHCP server is to provide IP addresses, as well as the subnet mask for the IP addresses in the scope, as follows:
# 1. Create an IPv4 Scope
Import-Module DHCPServer -WarningAction SilentlyContinue
$SCOPEHT = @{
Name = 'ReskitOrg'
StartRange = '10.10.10.150'
EndRange = '10.10.10.199'
SubnetMask = '255.255.255.0'
ComputerName = 'DC1.Reskit.Org'
}
Add-DhcpServerV4Scope @SCOPEHT
The DHCP Server module is not supported natively in PowerShell 7. You access the commands using the Windows PowerShell compatibility mechanism described in Chapter 2.
In most cases, you configure your DHCP servers to hand out IPv4 addresses. With IPv6's autoconfiguration, if you have an IPv6‐capable router serving a subnet, Windows hosts configure themselves with global (and local) addresses, including the router's address. Should you need more control over IPV6 addresses, you can create IPv6 scopes as needed.
Once you have a scope (or scopes) defined, you can view the scope information by using the
Get‐DHCPServerv4Scope
command.
# 2. Get IPv4 Scopes from the server
Get-DhcpServerv4Scope -ComputerName DC1.Reskit.Org
In the output shown in Figure 4.11, you can see the scope you just created along with its IP address range (10.10.10.150 to 10.10.10.199) and the scope's subnet mask (255.255.255.0).
Figure 4.11: Reviewing IPv4 scopes
Options are specific configuration items whose value can be requested by a DHCP client and provided by the DHCP Server. There is a large set of potential options—and almost all of them are only infrequently used. See www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.txt for the definitive list of options that can be set.
You can set DHCP options at the server level or the scope level. This allows you to have, for example, a single set of DNS servers provided to all DHCP clients in all scopes served by the server while you might have a scope‐specific setting for the default gateway.
Two options you should specify are the IP addresses of your DNS servers and the DNS domain name for any DHCP clients. You can do this as follows:
# 3. Set Server Wide Option Values
$OPTION1HT = @{
ComputerName = 'DC1.Reskit.Org' # DHCP Server to Configure
DnsDomain = 'Reskit.Org' # Client DNS Domain
DnsServer = '10.10.10.10' # Client DNS Server
}
Set-DhcpServerV4OptionValue @OPTION1HT
You can also set options at the scope level. A good example of a scope‐specific option you might want to specify is the IP address of the default gateway (
Router
).
To set a scope‐specific option value, you use the same
Set‐DHCPServerV4OptionsValue
and specify the scope name (using the
‐ScopeId
parameter).
# 4. Set a scope specific option
$OPTION2HT = @{
ComputerName = 'DC1.Reskit.Org' # DHCP Server to Configure
Router = '10.10.10.254'
ScopeID = '10.10.10.0'
}
Set-DhcpServerV4OptionValue @OPTION2HT
Now that you have the DHCP service installed, configured, and with a scope and options defined, you can begin to use it. You can test the DHCP service using the server
SRV2.Reskit.Org
. You used this server in “Configuring IP Addressing.”
To do this you must first set the TCP/IP client on
SRV2
to get IP address information from DHCP, as you see in the following code. In production, you should also test that your Windows 10 clients and other devices are getting the correct IP configuration. Once DHCP is seen to be providing an IP address, you can use the
Resolve‐DNSName
command to ensure the new DHCP‐provided IPv4 address is being resolved by DNS. These tests look like this:
# 5. Test the DHCP Service
# Run on SRV2
$NICHT = @{
InterfaceAlias = 'Ethernet'
AddressFamily = 'IPv4'
}
$NIC = Get-NetIPInterface @NICHT
Set-NetIPInterface -InterfaceAlias $NIC.ifALias -DHCP Enabled
Get-NetIPConfiguration
Resolve-DnsName -Name SRV2.Reskit.Org -Type A
This snippet sets the NIC in
SRV2
to be DHCP‐enabled. Running these commands produces the output shown in Figure 4.12, which shows that the server has a new IP address and related values. It can take a second or two to set this new address.
Figure 4.12: Checking DHCP operation
In early deployments of the Windows DHCP service, individual DHCP servers were standalone and did not communicate with other DHCP servers. If you wanted a measure of DHCP server failover, you would have had to create two DHCP servers and configure them to each offer IP addresses in the appropriate range (making sure the two servers did not issue the same address). A typical approach would be to configure the same DHCP scope on each DHCP server and then configure each server to issue only some of the addresses in the subnet block. With this approach, even if one server was down, clients could still get an IP address. This approach worked but was all too easy to misconfigure.
Later versions of Windows Server DHCP provided a better solution: built‐in failover and load balancing. This involves installing two Windows Servers with the DHCP service running on both. Then after creating a scope on one server, you create a failover/load balancing relationship for that scope between the two servers. Once configured, the two servers share the scope and the responsibility of issuing an IP address and related configuration. You can configure the two DHCP servers to do load balancing of DHCP requests or just to provide failover support.
If you set up DHCP with just DHCP hot standby, you would need to configure how long the standby server should wait before servicing DHCP requests.
To implement DHCP failover, you first need two DHCP servers. The first one,
DC1.Reskit.Org
, was set up in “Configuring the DHCP Service.” You also should have a second server, in this case
DC2.Reskit.Org.
This server is another domain controller in the
Reskit.Org
domain but without the DHCP feature loaded or configured. You can see how to do this in “Installing a Replica DC” in Chapter 3.
In this section, you run the PowerShell commands on the
DC2.Reskit.Org
server.
To implement a DHCP load balancing relationship you need to have installed DHCP on both the first server (which you did in “Installing the DHCP Service”) and on the second server (
DC2.Reskit.Org
), which you do here. To install the DHCP feature on
DC2.Reskit.Org
, run the following code:
# 1. Install the DHCP Server feature on DC2
Import-Module -Name ServerManager -WarningAction SilentlyContinue
$FEATUREHT = @{
Name = 'DHCP'
IncludeManagementTools = $True
}
Install-WindowsFeature @FEATUREHT
This command produces the output you see in Figure 4.13.
Figure 4.13: Installing the DHCP feature
As with the DHCP service on
DC1.Reskit.Org
, you need to tell Windows Server that DHCP is fully configured on DC2, which you do as follows:
# 2. Let DHCP Know It Is Fully Configured
$IPHT = @{
Path = 'HKLM:\SOFTWARE\Microsoft\ServerManager\Roles\12'
Name = 'ConfigurationState'
Value = 2
}
Set-ItemProperty @IPHT
You also need to ensure that the
DC2
DHCP server is authorized in AD, with the following code:
# 3. Authorize the DHCP Server in AD
Import-Module -Name DHCPServer -WarningAction 'SilentlyContinue'
Add-DhcpServerInDC -DnsName DC2.Reskit.Org
Once these steps are complete, you can use
Get‐DhcpServerInDC
to test and view the DHCP servers you have authorized for the
Reskit.Org
domain:
# 4. View Authorized DHCP Servers
Get-DhcpServerInDC
In the output, shown in Figure 4.14, you can see the two authorized DHCP servers. The first,
DC1.Reskit.Org
, was created in “Installing the DHCP Service” earlier and the other here.
Figure 4.14: Viewing authorized DHCP servers
If you have two DHCP servers, you can configure a load‐balancing relationship. The idea is to have the first DHCP server (in this case
DC1.Reskit.Org
) configured with one or more scopes defined and both server and scope options set as needed. Then, on a new DHCP server (
DC2.Reskit.Org
) to which you have just added the DHCP service, you create the relationship using the
Add‐DhcpServerV4Failover
command.
With
DC2.Reskit.Org
now installed and configured as a DHCP server, you can configure DHCP failover/load balancing as follows:
# 5. Configure failover and load balancing:
$FAILOVERHT = @{
ComputerName = 'DC1.Reskit.Org'
PartnerServer = 'DC2.Reskit.Org'
Name = 'DC1-DC2'
ScopeID = '10.10.10.0'
LoadBalancePercent = 60
SharedSecret = 'j3RryIsTheB3est
Force = $true
}
Add-DhcpServerv4Failover @FAILOVERHT
After you run this command, the two DHCP servers are now in an active‐active state. Both servers listen for and respond to DHCP client requests. If either DHCP server provides a lease for any configured scope, the DHCP service synchronizes the scopes automatically.
In this example, you created an active‐active relationship, which is great for performance. To reduce the overall resource usage, you might want to set up an active standby. That allows one server to do all the work of managing leases and to synchronize with the second server. Should the first server become nonresponsive, the second can take over until the first server comes back online. You would use the
MaxClientLeadTime
,
AutoStateTransition
, and
StateSwitchInterval
parameters to configure the hot standby relationship. For more information on configuring hot standby, see docs.microsoft.com/en-gb/archive/blogs/teamdhcp/dhcp-failover-using-powershell. And as with other references to Windows Server documentation, this content is old but still accurate for the purposes of this chapter.
While all PowerShell cmdlets support the
‐Verbose
parameter, some (many?) produce little or no useful output. Others, however, do produce a lot of valuable output that can be used for troubleshooting or debugging. If you use the
‐Verbose
parameter with the
Add‐DhcpServerv4Failover
command when creating a load‐balancing relationship between the two servers, you see the verbose output as shown in Figure 4.15. This is informative and can be useful for troubleshooting.
Figure 4.15: Verbose output when creating DHCP failover
With the DHCP installed and your DHCP scope (10.10.10.0) replicated, you can now view the DHCP server statistics, as follows:
# 6. Get active leases in the scope (from both servers!)
$DHCPServers = 'DC1.Reskit.Org', 'DC2.Reskit.Org'
$DHCPServers |
ForEach-Object {
"Server $_" | Format-Table
Get-DhcpServerv4Scope -ComputerName $_ | Format-Table
}
Once your DHCP clients are set up, they can use the DHCP service to obtain leases. The output, which you can see in Figure 4.16, shows the state of DHCP leases (after failover) on both servers.
Figure 4.16: Viewing active DHCP leases
As you can see, both servers have a copy of the scope, and both scopes have already had at least one DHCP client obtain an IP address lease from one or other of the DHCP servers. In this configuration, both servers are able to issue new IP address leases; and when one server does so, it coordinates the lease with the partner DHCP server.
Finally, you can also view the scope statistics from each server, using the
Get‐DhcpServerv4ScopeStatistics
command:
# 7. View DHCP Server Statistics from both DHCP Servers
$DHCPServers |
ForEach-Object {
"Server $_" | Format-Table
Get-DhcpServerv4ScopeStatistics -ComputerName $_ | Format-Table
}
As in the previous step, if you have a few DHCP clients using the DHCP server and zone, the output would resemble Figure 4.17.
Note that in this figure, you see just the IP address lease provided to SRV2. In your testing you may find different numbers of leases in use depending on what systems you have configured to have DHCP‐based IP addressing. Note that both DHCP servers return this information, so it appears twice.
Figure 4.17: Viewing DHCP server statistics
The DNS is a globally distributed name resolution service that converts DNS domain names into IP addresses. Once a DNS client resolves an IP address, the client can then initiate IP‐related access to the remote server. An analogy is a telephone book: you look up someone's name to get a phone number and then dial that number.
DNS enables you to look up the IP address for a domain name, for example converting www.wiley.com into an IP address of 13.32.123.207. DNS also does reverse lookup, which involves resolving the IP address of 13.32.123.207 back to the server that hosts the www.wiley.com web site.
Windows included a DNS service with Windows NT and has included and improved the server with later releases of Windows Server. Microsoft also makes use of DNS to provide a domain locator service that enables clients and servers to discover domain controllers. Previously, that was done using NetBIOS.
With Windows, DNS is used for both name resolution and service location. A DNS client enables applications to communicate with remote hosts by name. The DNS client is also able to search for services such as LDAP (Active Directory), by way of SRV records.
This section assumes you have a good understanding of what DNS is and broadly how it works. For more information on the basics of DNS, see the DNS Technical Reference at docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc779926
(v=ws.10)
. For more information, see bookauthority.org/books/best-dns-books.
In Chapter 3, you installed several domain controllers to form three domains within two forests. There, all the domain controllers used a single DNS service on
DC1
, which you created in “Establishing a Forest Root Domain.” After configuring AD, you can provide better resiliency for DNS by adding the DNS service to other DCs. Best practice is to have the DNS service on each domain controller and have the zones AD‐integrated.
Like any DNS Service, Microsoft's DNS provides a number of configuration settings that allow you to deploy DNS as needed. PowerShell 7 provides the necessary cmdlets that configure DNS to meet your requirements.
In this section, you add the DNS service to a second DC,
DC2
, to ensure that zones are replicated between DCs and configure key DNS service settings.
This section adds and configures the DNS service on
DC2
, adds the
DC2
DNS server to the DHCP Options you set in “Configuring DHCP Scopes,” and sets other key DNS configuration options. You also need
DC1
online. You run the snippets in this section from
DC2
.
To set up a Windows Server host to be a DNS server, you install the DNS feature using the
Install‐WindowsFeature
command.
# 1. Install the DNS Feature
Import-Module -Name ServerManager -WarningAction SilentlyContinue
Install-WindowsFeature -Name DNS -IncludeManagementTools
You can see the results of this command in Figure 4.18.
Figure 4.18: Installing the DNS feature
Since PowerShell supports Server Manager via the compatibility mechanism described in Chapter 2, importing the module generates a warning message by default advising that the module is running in compatibility mode. You use the
‐WarningAction
parameter to suppress this warning message.
Once the DNS Server service is installed and active, you can configure some basic options. Depending on how and where you plan to deploy DNS, the DNS Server service's options you might need to configure include the following:
There are other options that you may need to configure less commonly, including these:
(v%3Dws.11)
.SRV2.Reskit.Org
to
DC1.Reskit.Org
, but only for queries for the
Reskit.Org
zone. You set up forwarders in “Configuring a Cross‐Forest Trust” in Chapter 3.(v%3Dws.11)
for more information on DNS logging and diagnostics.You can set key DNS server options as follows:
# 2. Set Key DNS Server Options
# Enable recursion on this server
Set-DnsServerRecursion -Enable $true
# Configure DNS Server cache maximum size
Set-DnsServerCache -MaxKBSize 20480 # 20 MB
# Enable EDNS
$EDNSHT = @{
EnableProbes = $true
EnableReception = $true
}
Set-DnsServerEDns @EDNSHT
# Enable Global Name Zone
Set-DnsServerGlobalNameZone -Enable $true
You would run this snippet on each DNS server in your organization, amended as appropriate for each server.
After configuring your server, it is prudent to check the server option settings. You can do this by using the
Get‐DNSServer
command. This command on its own produces a lot of output, which would fill many pages of this book. However, the object that is returned from the
Get‐DNSServer
command contains a number of expandable properties that contain details of your DNS server's overall configuration.
You use
Select‐Object
to filter out the settings you want to view; the code looks like this:
# 3. View DNS Service and note the module
# Get DNS Server Settings
$WAHT = @{WarningAction='SilentlyContinue'}
$DNSRV = Get-DNSServer -ComputerName DC2.Reskit.Org @WAHT
# View Recursion settinngs
$DNSRV |
Select-Object -ExpandProperty ServerRecursion
# View Server Cache settings
$DNSRV |
Select-Object -ExpandProperty ServerCache
# View ENDS Settings
$DNSRV |
Select-Object -ExpandProperty ServerEdns
You can see the output of this code in Figure 4.19.
Figure 4.19: Examining key DNS configuration settings
In the output produced by these commands, you can see that the maximum TTL is set to one day and the cache timeout is set to 15 minutes. For an internal DNS server, you might consider raising the maximum TTL and cache timeouts to higher values as appropriate in your environment. Increasing these values decreases DNS traffic but risks out‐of‐date records. On the internal network, this is not much of a risk as servers do not change IP addresses often. On Internet‐facing DNS servers, erring on the side of accuracy is probably a good approach.
Each DNS zone contains resource records (RRs), which the DNS service uses to return information. When a DNS client attempts to resolve a host name, such as
DC1.Reskit.Org
, the DNS server searches the zone to find the appropriate resource record or records to return them to the DNS client.
Many RRs are automatically added to your internal DNS servers using the DNS dynamic update feature whereby DNS clients update DNS with their IP address. If you have Internet‐facing DNS servers, you are unlikely to want dynamic updates turned on.
The DNS records needed to support AD are updated in DNS each time a DC starts up and once every 24 hours thereafter. Likewise, Address (A) records for each host are written each time a host comes up and every 24 hours thereafter. For the most part, DNS is self‐healing: you remove the records, and they are rewritten to DNS.
Other records, such as Mail Exchange (MX) or Sender Protected Framework (SPF) records, are not automatically added to DNS. You can add these records statically.
If you have a number of static RRs to configure, having a PowerShell script to create the zone and the RRs makes it easy to re‐create the records should accidents happen. It's also great documentation as to what should be configured.
Before you can add RRs, you need to have the necessary zones defined on the server as well. A zone (such as
Reskit.Org
) holds RRs for that domain and possibly subdomains (e.g.,
UK.Reskit.Org
). When the DNS client sends a DNS server a resolution request, the server can find the zone and relevant RRs and resolve the name.
A reverse lookup zone enables DNS to find a host name given its IP address—the reverse of forward lookup. Reverse lookup zones are generally not required but may be used by some services and applications. The older DNS lookup command,
nslookup.exe
, for example, uses the IP address configured for the DNS server and converts it to a friendly name via the server's PTR (reverse lookup) resource record when it starts up. You can see this in Figure 4.20 although you need to set up the reverse lookup zone first, which you do in “Creating a Reverse Lookup Zone.”
Figure 4.20: Starting NSLookup
If you do not create a reverse lookup zone, then
nslookup.exe
reports the default server is “UnKnown.”
This section adds DNS RRs to the DNS Server you installed on
DC1.Reskit.Org
, which you created initially in “Establishing a Forest Root Domain” in Chapter 3.
A DNS forward lookup zone, for example
Cookham.Net
, is required before your DNS server can resolve a host name such as
Home.Cookham.Net
into an IP address such as
10.42.42.42
. You create a zone on
DC1
by doing the following:
# 1. Create a new primary forward DNS zone for Cookham.Net
Import-Module DNSServer
$ZHT1 = @{
Name = 'Cookham.Net'
ResponsiblePerson = 'dnsadmin.cookham.net.'
ReplicationScope = 'Forest'
ComputerName = 'DC1.Reskit.Org'
}
Add-DnsServerPrimaryZone @ZHT1
Although this snippet produces no output, you can see the results by using the DNS MMC console or by using DNS cmdlets. By default, this zone is AD integrated, meaning the zone information is stored in the AD. And, again by default, the zone is replicated to all DCs in the forest, which includes both DC1 and DC2.
You can also create reverse lookup zones that resolve IP addresses back into their respective host names. You use the
Add‐DnsServerPrimaryZone
command to add a reverse lookup zone like this:
# 2. Create a reverse lookup zone
$ZHT2 = @{
NetworkID = '10.10.10.0/24'
ResponsiblePerson = 'dnsadmin.reskit.org.'
ReplicationScope = 'Forest'
ComputerName = 'DC1.Reskit.Org'
}
Add-DnsServerPrimaryZone @ZHT2
In most cases, DNS clients register their reverse lookup information automatically using dynamic DNS update at the same time they register their forward lookup information. If you had an Internet‐facing server offering DNS resolution for Internet‐facing line‐of‐business (LOB) applications or systems, you would usually configure reverse lookups manually and turn off dynamic update. Allowing dynamic updates of Internet‐facing DNS servers could be a security concern.
By default, Windows hosts re‐register their DNS resource records every 24 hours or when the system is rebooted. It can take time before the new zones work on all servers. To speed things up, you can force key systems to register their forward and reverse lookup records (A and PTR) using
Register‐DnsClient
, as follows:
# 3. Register DNS for DC1, DC2
Register-DnsClient
Invoke-Command -ComputerName DC2 -ScriptBlock {Register-DnsClient}
These commands cause DC1 and DC2 to re‐register their A and PRT records on their configured DNS Server, which is
DC1
.
After creating two new zones, you verify that the zones are available. In this book, you have two forward lookup zones on the
DC1
DNS server. The first holds the
Reskit.Org
information (which was created by the snippets in Chapter 3 that create the AD). The second zone is the one just added. You also have a reverse lookup zone for 10.10.10.0/24.
To view all the zones held in
DC1
, you can use
Get‐DNSServerZone
and specify DC1 explicitly.
# 4. Check The DNS zones on DC1
Get-DNSServerZone -ComputerName DC1
The output, which you see in Figure 4.21, shows details of the zones held on
DC1
.
Figure 4.21: Checking on recently created DNS zones
As you see, there are two main forward lookup zones (for
Reskit.Org
and
Cookham.Net
), a forwarder (for Kapoho.Com) and a reverse‐lookup zone for 10.10.10.0;/24. You see whether the zones were created manually, are AD‐integrated, or are reverse lookup zones.
With your zones created, you next need to add RRs for DNS to use when resolving names/addresses. There are many different RR types that you might want to add to a zone; the most important are these:
WWW.Reskit.Org
, and point that to another host, such as
SRV2.Reskit.Org
.You can add these RR types to the zone RR‐specific commands, as follows:
# 5. Add Resource Record to Cookham.Net zone
# Add an A record
$RRHT1 = @{
ZoneName = 'Cookham.Net'
A = $true
Name = 'Home'
AllowUpdateAny = $true
IPv4Address = '10.42.42.42'
TimeToLive = (30 * (24 * 60 * 60)) # 30 days in seconds
}
Add-DnsServerResourceRecord @RRHT1
# Add a Cname record
$RRHT2 = @{
ZoneName = 'Cookham.Net'
Name = 'MAIL'
HostNameAlias = 'Home.Cookham.Net'
TimeToLive = (30 * (24 * 60 * 60)) # 30 days in seconds
}
Add-DnsServerResourceRecordCName @RRHT2
# Add an MX record
$MXHT = @{
Preference = 10
Name = '.'
TimeToLive = '1:00:00'
MailExchange = 'Mail.Cookham.Net'
ZoneName = 'Cookham.Net'
}
Add-DnsServerResourceRecordMX @MXHT
The DNS Server module provides cmdlets that add specific RRs for most commonly used RR types with parameters suitable for that RR as used in this snippet. For other DNS resource records you might need to add, you can use the more generic
Add‐DnsServerResourceRecord
command. For a deeper look at the range of RRs supported by Windows Server's DNS service, see docs.microsoft.com/en-us/windows/win32/dns/managing-dns-resource-records.
The zones you have created so far were created on
DC1
and were AD‐integrated with forest‐wide replication. That means that once
DC1
has been updated, AD replicates the new zone and RR details to all DCs in the forest. If a DC runs the DNS Service, it finds the new zones automatically. With AD‐integrated zones, a DNS client can register records on any DC (that runs a DNS service). AD then replicates those. The DNS service regularly updates its record information based on the newly replicated AD contents. While the replication and updating all happens fairly quickly, they can take some time. To speed things up you can restart the DNS service on
DC1
and
DC2
, like this:
# 6. Restart DNS Service to ensure replication
Restart-Service -Name DNS
$SB = {Restart-Service -Name DNS}
Invoke-Command -ComputerName DC1 -ScriptBlock $SB
These commands have the side effect of clearing the DNS server's name cache. For busy intranet servers, that means losing cached RRs, which can lead to increased external traffic for a time. As a best practice, you should do maintenance like this during off‐peak times or if possible, during a routine maintenance outage.
After adding resource records to the
Cookham.Net
forward lookup zone, and restarting the DNS service, you can verify that the RRs are set up correctly.
# 7. Check results of RRs in Cookham.Net zone
Get-DnsServerResourceRecord -ZoneName 'Cookham.Net'
The output from these commands, in Figure 4.22, shows the RRs you just created (the MX, CNAME, and A records) plus two RRs created by the DNS server when you created the zone (the NS and SOA RRs).
Figure 4.22: Checking on DNS RRs
In this figure, the SOA record shows a version number of 5. Over time this version number increases as changes are made. This is normal.
You should always test any DNS installation and changes to that installation carefully. Little mistakes can lead to huge consequences. An often‐repeated bit of IT Pro humor suggests “The cause of your issue is DNS—now what was your issue?”
Besides the obvious checks that the DNS service is running and confirming key configuration values, such as recursion, server cache, and EDNS, you also need to test that key resource records are being resolved by all your DNS Servers (that is,
DC1
and
DC2
). You can test the resolution on both DNS servers with code like this:
# 8. Test DNS Resolution on DC1, DC2
# Test the Cname
Resolve-DnsName -Server DC1.Reskit.Org -Name 'Mail.Cookham.Net'
# Test the MX
Resolve-DnsName -Server DC2.Reskit.Org -Name 'Cookham.Net' -Type MX
The testing produces the output you see in Figure 4.23.
As you can see in the figure, resolving the
Mail.Cookham.Net
domain name retrieves the CNAME record and the A record (for
Home.Cookham.Net
), which the CNAME points to. This DNS resolution was performed on
DC1
, and you verified that the MX record for the domain
Cookham.Net
points to the server
Mail.Cookham.Net
.
Figure 4.23: Checking DNS name resolution on
DC1
In this section you used a number of the core DNS server configuration commands. There are a number of advanced DNS features this book does not cover, such as DNS security (DNSSec), root hints, DNS server virtualization instances, DNS scavenging, and more. The DNS Server module has 134 commands to enable you to configure DNS as your needs dictate.
Networking is at the heart of every organization. In this chapter, you saw how to configure IP addressing and test network connectivity. You also looked at the installation and configuration of DHCP. With DHCP, you created a simple DHCP Server with one scope and then added a second failover/load‐balancing DHCP server. In this chapter's final sections, you installed and configured your DNS server, and you configured and tested DNS zones and resource records.