Blog Post Title Four
# Collect all data up front (assuming a single DHCP server):
$AllScopes = Get-DhcpServerv4Scope -ComputerName 'DC01'
$AllExclusions = Get-DhcpServerv4ExclusionRange -ComputerName 'DC01'
$AllLeases = Get-DhcpServerv4Lease -ComputerName 'DC01'
$AllReservations= Get-DhcpServerv4Reservation -ComputerName 'DC01'
# We will build a collection of objects that map directly to CSV rows
$Output = @()
foreach ($scope in $AllScopes) {
# Pull scope-based data
$scopeId = $scope.ScopeId
# Get this scope's exclusions, leases, and reservations
$theseExclusions = $AllExclusions | Where-Object { $_.ScopeId -eq $scopeId }
$theseLeases = $AllLeases | Where-Object { $_.ScopeId -eq $scopeId }
$theseReservations= $AllReservations| Where-Object { $_.ScopeId -eq $scopeId }
# 1) Add a single row for the Scope info itself.
$Output += [PSCustomObject]@{
'Section' = 'SCOPE'
'Scope Name' = $scope.Name
'Scope' = $scope.ScopeId
'Start IP' = $scope.StartRange
'End IP' = $scope.EndRange
'Lease Duration' = $scope.LeaseDuration
'Description' = $scope.Description
'Client IP' = $null
'Name' = $null
'Lease Expiration' = $null
'Type' = $null
'Unique ID' = $null
'Extra Description'= $null
}
# 2) Address Pool (in many environments it’s just the scope’s start/end)
$Output += [PSCustomObject]@{
'Section' = 'ADDRESS POOL'
'Scope Name' = $scope.Name
'Scope' = $scope.ScopeId
'Start IP' = $scope.StartRange
'End IP' = $scope.EndRange
'Lease Duration' = $null
'Description' = $null
'Client IP' = $null
'Name' = $null
'Lease Expiration' = $null
'Type' = $null
'Unique ID' = $null
'Extra Description'= $null
}
# 3) EXCLUSIONS for this scope
foreach ($ex in $theseExclusions) {
$Output += [PSCustomObject]@{
'Section' = 'EXCLUSIONS'
'Scope Name' = $scope.Name
'Scope' = $scope.ScopeId
'Start IP' = $ex.StartRange
'End IP' = $ex.EndRange
'Lease Duration' = $null
'Description' = $null
'Client IP' = $null
'Name' = $null
'Lease Expiration' = $null
'Type' = $null
'Unique ID' = $null
'Extra Description'= $null
}
}
# 4) ADDRESS LEASES for this scope
foreach ($lease in $theseLeases) {
# Optionally find matching reservation to fill in "Description" or special status
$matchedReservation = $theseReservations | Where-Object { $_.IPAddress -eq $lease.IPAddress }
if ($matchedReservation) {
# Possibly "Name" from the reservation instead of $lease.HostName
$leaseName = $matchedReservation.Name
$desc = $matchedReservation.Description
$leaseStatus = "Reservation ({0})" -f (
if ($lease.AddressState -eq 'Active') {'active'} else {'inactive'}
)
$type = $matchedReservation.ReservationType
$uniqueId = $matchedReservation.ClientId
}
else {
$leaseName = $lease.HostName
$desc = $null
$leaseStatus = $lease.LeaseExpiryTime # or your custom string
$type = $lease.ClientType
$uniqueId = $lease.ClientId
}
$Output += [PSCustomObject]@{
'Section' = 'ADDRESS LEASES'
'Scope Name' = $scope.Name
'Scope' = $scope.ScopeId
'Start IP' = $null
'End IP' = $null
'Lease Duration' = $null
'Description' = $null
'Client IP' = $lease.IPAddress
'Name' = $leaseName
'Lease Expiration' = $leaseStatus
'Type' = $type
'Unique ID' = $uniqueId
'Extra Description'= $desc
}
}
# 5) RESERVATIONS for this scope
foreach ($res in $theseReservations) {
$Output += [PSCustomObject]@{
'Section' = 'RESERVATIONS'
'Scope Name' = $scope.Name
'Scope' = $scope.ScopeId
'Start IP' = $null
'End IP' = $null
'Lease Duration' = $null
'Description' = $null
'Client IP' = $res.IPAddress
'Name' = $res.Name
'Lease Expiration' = $null
'Type' = $res.ReservationType
'Unique ID' = $res.ClientId
'Extra Description'= $res.Description
}
}
} # end foreach scope
# Finally, export the assembled data to CSV:
$Output | Export-Csv -Path "DhcpReport.csv" -NoTypeInformation