We recently had a client who wanted to audit their many DHCP subnets. To that end they wanted a list of subnets, and how many IP’s each still had remaining. This was tricky because they had many DHCP IP Reservations which were not always in use.
We created the script below to perform the calculations and generate a simple table we provided to our client:

# Function to calculate the total number of IP addresses in a range
function Get-TotalIPs {
param (
[string]$startIP,
[string]$endIP
)
$start = [System.Net.IPAddress]::Parse($startIP).GetAddressBytes()
$end = [System.Net.IPAddress]::Parse($endIP).GetAddressBytes()
[Array]::Reverse($start)
[Array]::Reverse($end)
$startInt = [BitConverter]::ToUInt32($start, 0)
$endInt = [BitConverter]::ToUInt32($end, 0)
return ($endInt - $startInt + 1)
}
# Get all DHCP scopes
$scopes = Get-DhcpServerv4Scope
# Initialize an array to store the results
$results = @()
# Loop through each scope
foreach ($scope in $scopes) {
# Get the total number of IP addresses in the scope
$totalIPs = Get-TotalIPs -startIP $scope.StartRange -endIP $scope.EndRange
# Get the number of used IP addresses (leases)
$leases = Get-DhcpServerv4Lease -ScopeId $scope.ScopeId
$usedIPs = $leases.Count
# Get the number of reserved IP addresses that are not currently leased
$reservations = Get-DhcpServerv4Reservation -ScopeId $scope.ScopeId
$reservedIPs = ($reservations | Where-Object { $_.ClientId -notin $leases.ClientId }).Count
# Calculate the number of unused IP addresses
$unusedIPs = $totalIPs - ($usedIPs + $reservedIPs)
# Add the result to the array
$results += [pscustomobject]@{
Subnet = $scope.ScopeId
StartIP = $scope.StartRange
EndIP = $scope.EndRange
UnusedIPs = $unusedIPs
}
}
# Display the results
$results | Format-Table -AutoSize
# Export the results to a CSV file
$results | Export-Csv -Path "C:\temp\dhcp-available-ips.csv" -NoTypeInformation
Write-Output "Results exported successfully to C:\temp\dhcp-available-ips.csv"
0 Comments