Chapter 4
Managing Networking

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).

  • When you first install Windows on a computer, the setup program does a good job of detecting your network cards and setting default settings. By default, each NIC is configured to get its IP address via DHCP. This means you install Windows, plug the system into the network, and the DHCP clients configure IP addressing and DNS details automatically. But sometimes you need to set an IP address explicitly, as shown in the “Configuring IP Addressing” section.
  • An important setup step for troubleshooting is to ensure that each host has full network connectivity to other systems either inside your network or externally. You should do this before adding applications and services to a server. In “Testing Network Connectivity,” you see how to detect issues with connection to remote systems and services.
  • To simplify the connection of client computers and devices to the organization's network, you install a DHCP server. As you see in “Installing the DHCP Service,” setting up DHCP is simple and straightforward.
  • Once your DHCP server is installed, you need to configure scopes, as described in “Configuring DHCP Scopes.” A scope is a set of addresses your DHCP server can provide to the DHCP client along with a set of options and option values that you use to configure your DHCP clients. Options include a default gateway IP address and the address(es) of your DNS servers. You can configure options at the scope level (giving these option values to addresses provided within the scope) or at the server level (using the DHCP server to provide server options to any address the server provides), or a combination of both.
  • Because your clients rely on DHCP for obtaining IP network configuration details, any outage could stop those clients from networking. For larger organizations it might also be useful to have some performance load balancing to handle peak DHCP load. To support the load balancing and resiliency requirements, you use the DHCP server's failover and load balancing features, as described in “Configuring DHCP Failover.”
  • After your systems get their IP configuration (either statically or via DHCP), to communicate with other hosts, you must provide a DNS service to do your name resolution, turning host names such as 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.
  • Likewise, configuring DNS zones and resource records is simple, as shown in “Configuring DNS Server Zones and Resource Records.”

Systems Used in This Chapter

In this chapter, you use PowerShell 7 to manage various networking aspects. The scripts in this chapter make use of the following servers:

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.

image

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.

Configuring IP Addressing

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.

Before You Start

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.

Checking Adapter Details

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).

image

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.

Configuring an IP Address

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.

Verifying the New IP 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.

image

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.

Setting DNS Server Details

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

Validating the New IP Configuration

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.

image

Figure 4.4: Verifying the new IP configuration

Testing Network Connectivity

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.

Before You Start

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.

Verifying That SRV2 and Loopback Are Working

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.

image

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).

Testing Connectivity to the DC

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.

image

Figure 4.6: Verifying connectivity to DC1

Checking Connectivity to the SMB and LDAP Ports

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.

image

Figure 4.7: Verifying SMB/LDAP connectivity to DC1

Examining the Path to a Remote Server

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.

image

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.

Installing the DHCP Service

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.

Before You Start

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 Feature

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.

image

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.

Authorizing the DHCP Server in the AD

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.

Completing the DHCP Configuration

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.

Restarting the DHCP Service

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.

Checking the DHCP Service

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.

image

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.

Configuring DHCP 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.

Before You Start

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.

Creating a DHCP Scope

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.

Getting Scopes from the DHCP Server

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).

image

Figure 4.11: Reviewing IPv4 scopes

Configuring Server‐wide Options

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 

Configuring Scope‐Specific Options

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 

Testing the DHCP Service in Operation

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.

image

Figure 4.12: Checking DHCP operation

Configuring DHCP Failover

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.

Before You Start

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.

Installing the DHCP Server Feature on DC2

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.

image

Figure 4.13: Installing the DHCP feature

Letting DHCP Know It Is Fully Configured on DC2

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

Authorizing the Second DHCP Server in AD

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 

Viewing Authorized DHCP Servers

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.

image

Figure 4.14: Viewing authorized DHCP servers

Configuring DHCP Failover and Load Balancing

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.

image

Figure 4.15: Verbose output when creating DHCP failover

Viewing Active Leases from Both DHCP Servers

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.

image

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.

Viewing DHCP Server Statistics

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.

image

Figure 4.17: Viewing DHCP server statistics

Configuring the DNS Service

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.

Before You Start

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.

Installing the DNS Feature on 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.

image

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.

Configuring the DNS Service

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:

  • Disabling recursion: You may want to disable recursion to avoid clients forcing recursive queries (a potential denial‐of‐service attack vector for Internet‐facing servers). For use within your organization, you would enable recursion.
  • Configuring the DNS Server local cache: You can set the maximum amount of memory that the DNS Server service can use for its local cache. For most Internet‐ or DMZ‐based DNS servers, you can probably set this to 25MB and be OK. But monitor it carefully.
  • Configuring EDNS: Extended DNS (EDNS) is an extension mechanism that allows suitably configured DNS client systems to extend the DNS protocol while allowing older clients to work as previously. One example is to enable a larger DNS reply. This could be useful if you have larger numbers of resource records that can fit in a simple UDP datagram. EDNS is turned off by default, but there is no real downside to leaving this off.
  • Enabling the global name zone: The global name zone enables you to enable single‐label DNS queries (for HRWEB, for example). This can be useful as a way of removing any lingering dependency on NetBIOS (or WINS) in an organization.

There are other options that you may need to configure less commonly, including these:

  • Configuring round robin: Round robin, which is enabled by default, returns resource records requested by a DNS query but in a random order. For situations where several servers all have the same domain name, this provides a degree of load balancing.
  • Configuring DNSSEC: DNS Security (DNSSEC) provides cryptographic assurance that DNS replies are valid. DNSSEC is complex but automatic in operation. Where possible, Internet‐facing DNS servers, and the replies they generate, should be protected with DNSSEC. For more information about DNSSEC, see docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/jj200221 (v%3Dws.11).
  • Configuring a DNS forwarder: In some cases, you might want to have your DNS server conditionally forward requests for certain domains to a specific server. You might, for example, want to route queries received at 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.
  • Specifying a zone data loading: For a standalone DNS server, you may want to save zone information in the registry or in a file. You can save it in AD, and have it automatically replicated within the forest or domain.
  • Configuring DNS debugging and event log logging: When you install the DNS server, by default the service does not perform diagnostic logging (logging either DNS requests or replies). You can turn this logging on. See docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn800669 (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.

Viewing Key DNS Server Options

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.

image

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.

Configuring DNS Zones and Resource Records

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.”

image

Figure 4.20: Starting NSLookup

If you do not create a reverse lookup zone, then nslookup.exe reports the default server is “UnKnown.”

Before You Start

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.

Creating a DNS Forward Lookup Zone

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.

Creating a Reverse Lookup Zone

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.

Registering DNS Records for DC1, DC2

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.

Checking the DNS Zones on 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.

image

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.

Adding DNS RR to the Cookham.Net Zone

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:

  • A record: This provides the IP address for a specific host name.
  • CNAME: This RR type provides an alias mechanism, enabling you to define an alias, such as WWW.Reskit.Org, and point that to another host, such as SRV2.Reskit.Org.
  • MX record: This tells email services where to send email for a particular domain.

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.

Restarting the DNS Service

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.

Checking the DNS RRs in the Cookham.Net Zone

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).

image

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.

Testing DNS Server Resolution

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.

image

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.

Summary

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.