Large organizations typically have lots of devices that require IP addresses. Client desktops, tablets, mobile and desk phones, servers and more all consume IPs. The only way to manage IPs at this level is to use Microsoft Dynamic Host Configuration Protocol (DHCP), which will also manage which devices obtain which IPs through DHCP leases. Even though the DHCP server in Microsoft Windows handles the majority of the work for you, you'll occasionally need to run reports and query the current status of a device's DHCP lease across multiple DHCP servers and scopes.

In this article, I'll show you how to create a script in PowerShell that will allow you to discover all Microsoft DHCP servers in an Active Directory (AD) domain, all scopes on all of those servers and all leases inside those scopes. This will provide you with a simple way to run point-in-time DHCP lease reports and to easily query all DHCP leases in your organization for leases matching specific criteria.

Getting Started

Before we get started, I'm going to assume a few things:

  • You have PowerShell v4+ installed on the computer on which you're running the script
  • Your computer is in an Active Directory domain
  • You have the Remote Server Administration tools package installed with the DHCP server module enabled
  • You have all the appropriate rights to enumerate DHCP leases in your environment

Enumerating All DHCP Servers, Scopes and Leases

To find all the DHCP leases in an environment, you'll first need to enumerate all the DHCP servers in your domain. To do this, use the Get-DhcpServerInDc cmdlet. This will retrieve all the allowed DHCP servers that have been registered in AD.

$DhcpServer = Get-DhcpServerInDC

Next, we'll need to enumerate all the scopes on each of these DHCP servers. To do that, we'll use the Get-DhcpServeV4Scope cmdlet.

@($DhcpServer).foreach({
    Get-DhcpServerv4Scope -ComputerName $_.DnsName
})

Next, we'll take the final step and retrieve each of the active leases within each of those scopes.

@($DhcpServer).foreach({
    @(Get-DhcpServerv4Scope -ComputerName $_.DnsName).foreach({
        Get-DhcpServerv4Lease -ComputerName $_.DnsName -ScopeId $_.ScopeId
    })
})

This script alone will attempt to enumerate all leases in all scopes on all DHCP servers that are registered in the current domain. This is a good way to generate an all-or-nothing report, but what if you want to limit the lease output to those with certain attributes, such as certain IP addresses or MAC addresses?

Applying Filters

To do this, you'll have to scale down the output and pass a different parameter to the Get-DhcpServerV4Lease cmdlet. Let's demonstrate this by only retrieving leases with an IP address of 1.1.1.1. The majority of our code will look exactly the same, but the parameters passed to Get-DhcpServerV4Lease will be a little different.

$DhcpServer = Get-DhcpServerInDC
@($DhcpServer).foreach({
    @(Get-DhcpServerv4Scope -ComputerName $_.DnsName).foreach({
        Get-DhcpServerv4Lease -ComputerName $_.DnsName -IpAddress '1.1.1.1'
    })
})

Notice that when narrowing down lease output by IP address, you can't use the ScopeId. This is a limitation of the Get-DhcpServerV4Lease cmdlet. If you try, you'll see an error indicating that the parameter set cannot be resolved.

If you need to narrow down the lease output by MAC address, you can change up the parameters and use the ScopeId and ClientId parameters this time.

Get-DhcpServerv4Lease -ComputerName 'SRV1' -ScopeId '10.10.10.0' -ClientId $MacAddress

You'll find that, depending on the various parameters passed, you can limit the output in a number of ways. To get a list of the parameters you can use for the Get-DhcpServerV4Lease use Get-Help.

Get-Help Get-DHCPServerv4Lease -Detailed

You may also want to filter the output by host name. But, unfortunately, there's no parameter for this on Get-DHCPServerv4Lease. To do this, you'll have to use the Where-Object cmdlet or the Where() method in PowerShell v4 or later.

$HostName = 'COMPUTER1','COMPUTER2'
$leases = @(Get-DhcpServerv4Lease -ComputerName 'SRV1' -ScopeId
'10.10.10.0').where({$_.Hostname -in $HostName})

For a full demonstration of this technique, I've created a script called Get-DhcpLease. This script demonstrates everything we've discussed here, and goes into more depth on the different filtering capabilities, including the option to query specific DHCP servers.

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!