Converting DHCP addresses to static

While DHCP is an easy way to manage network addresses, especially, in dynamic environments, it does have its drawbacks. If something happens on your physical network or to your DHCP server, clients may not be able to receive or renew their addresses. And due to the dynamic nature of DHCP, addresses may change, causing issues with firewalls and DNS records.

This is normally fine for desktop environments, but in server environments, we want to minimize any possibility for an outage. As such, at some point you may want to convert your dynamically addressed hosts to use static addresses.

Getting ready

This recipe assumes a basic server configuration with a single interface using a single IP address via DHCP. The script works best when run locally on the target server.

How to do it...

Log on to the target server interactively and execute the following script:

# Identify all adapters that recieved an address via DHCP
$adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object {($_.IPAddress) -and $_.DHCPEnabled -eq 'True' }

# Iterate through each adapter
foreach($adapter in $adapters)
{
    # Get current adapter and IP information
    $adapIndex = $adapter.InterfaceIndex
    $ipAddress = $adapter.IPAddress[0]
    $subnetMask = $adapter.IPSubnet[0]
    $defaultGateway = $adapter.DefaultIPGateway[0]
    $prefix = (Get-NetIPAddress -InterfaceIndex $adapIndex –AddressFamily IPv4).PrefixLength
    $dnsServers = $adapter.DNSServerSearchOrder
    [ipaddress]$netAddr = ([ipaddress]$ipAddress).Address -band ([ipaddress]$subnetMask).Address

    # Identify the DHCP server
    $dhcpServer = $adapter.DHCPServer
    $dhcpName = ([System.Net.DNS]::GetHostEntry($dhcpServer)).HostName

    # Add an exclusion to DHCP for the current IP address
    Invoke-Command -ComputerName $dhcpName -ScriptBlock{
        Add-DhcpServerv4ExclusionRange –ScopeId $args[0] –StartRange $args[1] –EndRange $args[1]
    } -ArgumentList $netAddr.IPAddressToString, $ipAddress

    # Release the DHCP address lease
    Remove-NetIPAddress -InterfaceIndex $adapIndex -Confirm:$false

    # Statically assign the IP and DNS information
    New-NetIPAddress -InterfaceIndex $adapIndex -AddressFamily IPv4 -IPAddress $ipAddress -PrefixLength $prefix -DefaultGateway $defaultGateway
    Set-DnsClientServerAddress -InterfaceIndex $adapIndex -ServerAddresses $dnsServers
} 

How it works...

The first part of the script queries WMI for all network adapters that both have an active IP address, and are using DHCP. The results from the WMI query are placed into a variable named $adapters and are iterated in a for each loop, where the adapter and IP information is collected.

Tip

A network adapter can hold multiple IP addresses, but this script is only capable of handling the first IPv4 address of each adapter.

Once all of the network information is collected, Invoke-Command is used to connect to the DHCP server that issued the address and creates an exclusion. The exclusion record's start and end address is the IP address assigned to the client. This prevents the IP address from being reused by another host at a later time.

Lastly, the adapter is changed to a static address. Remove-NetIPAddress is used to release the DHCP address from the interface. Once cleared, New-NetIPAddress is used to statically configure the interface with the same IPv4 address, subnet, and gateway that was previously held. Finally, Set-DnsClientServerAddress assigns the DNS server addresses.

There's more...

This script can be run against a system remotely using a PSSession, with the exception of creating the DHCP exclusion. When using a PSSession to a remote computer, you cannot create another session to a third computer. As such, the script will run and successfully set the local interfaces to static, but it won't exclude DHCP from providing those addresses to another client.