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 <string> –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 = "<style>" $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 + "</style>" #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