So I was in a need of having the active leases in my DHCP server exported to an web (html) page:
On the surface this would not present a problem, however as there is only one way to read the DHCP leases, netsh.exe, and the output format of this app is somewhat … I also got the chance to to play with regular expressions (love those) and –replace
Just so everyone can share the pain, this is the netsh command:
netsh dhcp server 1.1.1.1 scope 1.1.1.0 show clients 1
And this is the output:
Changed the current scope context to 1.1.1.0 scope.
Type : N - NONE, D - DHCP B - BOOTP, U - UNSPECIFIED, R - RESERVATION IP
============================================================================================
IP Address - Subnet Mask - Unique ID - Lease Expires -Type -Name
============================================================================================
1.1.1.5 - 255.255.0.0 - 00-ff-ff-ff-ff-ff -10/13/2009 12:33:16 AM -D- host01.domain.com
:::
::: Lot of lines here
:::
1.1.1.227 - 255.255.0.0 - 00-ff-ff-ff-ff-ff -10/13/2009 12:42:06 AM -D- host10.domain.com
No of Clients(version 4): 355 in the Scope : 1.1.1.0.
Command completed successfully.
So is there any logic here? Double tabs, single tabs from which I can split? No. only spaces…. and hyphens.. and useless data
As I only needed the IP and hostnames in a html table, this is what I ended up with in powershell:
$a = (netsh dhcp server 1.1.1.1 scope 1.1.1.0 show clients 1)
$lines = @()
#start by looking for lines where there is both IP and MAC present:
foreach ($i in $a){
if ($i -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"){
If ($i -match "[0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}"){
$lines += $i.Trim()
}
}
}
$csvfile = @()
#Trim the lines for uneeded stuff, leaving only IP, Subnet mask and hostname.
foreach ($l in $lines){
$Row = "" | select Hostname,IP
$l = $l -replace '[0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}', ''
$l = $l -replace ' - ',','
$l = $l -replace '\s{4,}',''
$l = $l -replace '--','-'
$l = $l -replace '-D-','-'
$l = $l -replace '[-]{1}\d{2}[/]\d{2}[/]\d{4}',''
$l = $l -replace '\d{1,2}[:]\d{2}[:]\d{2}',''
$l = $l -replace 'AM',''
$l = $l -replace 'PM',''
$l = $l -replace '\s{1}',''
$l = $l + "`n"
$l = $l -replace '[,][-]',','
$Row.IP = ($l.Split(","))[0]
#Subnet mask not used, but maybe in a later version, so let's leave it in there:
#$Row.SubNetMask = ($l.Split(","))[1]
$Row.Hostname = ($l.Split(","))[2]
$csvfile += $Row
}
#let create a csv file, in case we need i later..
$csvfile | sort-object Hostname | Export-Csv "Out_List.csv"
#Create the HTML formating
$a = ""
$a = $a + "body {margin: 10px; width: 600px; font-family:arial; font-size: 12px;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: rgb(179,179,179);align='left';}"
$a = $a + "TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: white;}"
$a = $a + ""
#And create HTML file...
Write-Host "Please contact theadmin@void.null for support" | Out-File "DHCPLeases.html"
$csvfile | sort-object Hostname | ConvertTo-HTML -head $a | Out-File -Append "DHCPLeases.html"
The resulting output, then looks like this:
HostName |
IP |
host01.domain.com |
1.1.1.5 |
host10.domain.com |
1.1.1.227 |
which is what I wanted. Another great job by powershell.
I hope that this might prove useful to someone else, and a my thanks goes out to the powershell community and all the people who might recognize some of the code, no one mentioned, no one forgotten.
Please do drop a line if you have comments or suggestions to how the script could be optimized. Life is a learning curve and I love climbing 🙂