stopsoftwarepatents.eu petition banner

Let's Sign the petition today.

Parent

dhcpenum.vbs is a tool that list/enumerate dhcp information, and generate a CSV file. It should be easy to extract Super-scope, reservation, options, leases... too. But since I didn't needed it, it's not there (your patches are welcome). The source is available below.

Samples

dhcp scopes enumeration

Sample invocation:

cscript //NoLogo dhcpenum.vbs 10.1.2.3

Would produce: Server;Start;End;Mask;"Name";"Comment"

10.4.192.0;255.255.255.0;"Montpellier etage 00 vlan 100 ";"Montpellier etage 00 "
10.4.214.0;255.255.255.0;"Montpellier etage 11 vlan 111 ";"Montpellier etage 11 "
10.4.216.0;255.255.255.0;"Montpellier etage 12 vlan 112 ";"Montpellier etage 12 "

With the option "/printscopeas:range", the scope would be printed as ranges (start-ip/end-ip rather than subnet/mask)

10.4.192.1;10.4.192.254;"Montpellier etage 00 vlan 100 ";"Montpellier etage 00 "
10.4.214.1;10.4.214.254;"Montpellier etage 11 vlan 111 ";"Montpellier etage 11 "
10.4.216.1;10.4.216.254;"Montpellier etage 12 vlan 112 ";"Montpellier etage 12 "

dhcp server list

The list of servers can easily be extracted with netsh:

netsh dhcp show server | find /i "cn=" > dhcp.raw

then

for /F "delims=[] tokens=2,4" %i in (dhcp.raw) do cscript //NoLogo dhcpenum.vbs /noheader /printscopeas:range %j > scopes.csv

Now, if you want to run a command for each scope

for /F "delims=; tokens=1,2" %%f in (scopes.csv) do "CmdLineNetAudit.exe" -startip %%f -endip %%g -unmanaged true -verbose

Source

The source can be downloaded: dhcpenum.vbs

' dhcpenum.vbs 0.03 - List/Enumerates dhcp information
'
' Copyright (C) 2008 Frank Lin PIAT <fpiat@klabs.be>
' latest version is available from:
'     http://www.klabs.be/~fpiat/windows/dhcpenum/
'
' This file is free software; you can redistribute it and/or modify it
' under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
''             full license text : http://www.gnu.org/copyleft/gpl.html

' Script requirements:
'	- Microsoft DHCP Objects (see below)
'
' Script changelog:
'	- at the bottom og this file


Dim dhcpmgr 
Dim dhcpsrvr

Dim i18n
'SetLocale("en") 'Force locale, like: "en" or "fr"... for testing puposes
Initialise_i18n

Sub showHelp()
	Dim o
	o = getI18n("To invoke this script, run:") & vbCrLf _
		& "   cscript //Nologo " & WScript.ScriptName & " DhcpServerIP"
	wscript.echo o

	if (InStr(WScript.FullName,"cscript") > 0 ) Then 
		gecho ""
		gecho "DhcpServerIP : The IP adress of the DHCP server(s)"
		gecho "  The list of the DHCP servers can be obtained by running :"
		gecho "  netsh dhcp show server"
		gecho ""
		gecho "  (assuming DHCPMON helper was added to netsh with the command:"
		gecho "  netsh add helper DHCPMON.DLL)"
	End If
	WScript.quit
	wscript.quit(1)
End Sub

format="csv"
header=true
printscopeas="subnet"
For Each arg in WScript.Arguments.named
	Select Case arg
		Case "help"
			showHelp
		Case "h"
			showHelp
		Case "?"
			showHelp
		Case "format"
			format=Wscript.Arguments.named(arg)		' "csv" or "vbarray"
		Case "noheader"
			header=false
		Case "printscopeas"					' "subnet" or "range"
			printscopeas=Wscript.Arguments.named(arg)
		Case Else 
			wscript.echo Replace(getI18n("Error: Option ""{option}"" is invalid."), "{option}",  arg)
			wscript.quit
	End Select
Next

' *** Verify Environement ***

If WScript.Arguments.Unnamed.Count < 1 Then
	showHelp

End If

On Error Resume Next
Err.Clear
Set dhcpmgr = CreateObject("Dhcp.Manager")
If Err.Number Then
	wscript.StdErr.WriteLine Err.Description
	wscript.StdErr.WriteLine getI18n("This script requires the DLL dhcpobjs.dll from Windows 2000 server resource kit.")  '& vbCrLf
	wscript.StdErr.WriteLine getI18n("(it is located in in the archive netmgmt.cab, the in dhcpobjs.exe).")

	wscript.quit(1)
End If
On Error Goto 0
'Set dhcpsrvr=CreateObject("DhcpObjects.Server")


For Each srvName in WScript.Arguments.Unnamed
	If header & format="csv" Then
		wscript.echo "Server;Start;End;Mask;""Name"";""Comment"""
	End If
	ListScopes srvName 
Next


Sub ListScopes(srvName)
	Dim scope, dhcpscopes
	Dim netStart, netEnd
	Set dhcpsrvr = dhcpmgr.Servers.Connect(srvName)
	j=0

	With dhcpsrvr.Scopes
		For i = 1 To .Count
			If .Item(i).Active Then
				If printscopeas = "range" Then
					netStart = CalcRangeStart(.Item(i).Address, .Item(i).Mask)
					netEnd = CalcRangeEnd(.Item(i).Address, .Item(i).Mask)
				Else ' "subnet"
					netStart = .Item(i).Address
					netEnd = .Item(i).Mask
				End If
				If format="vbarray" Then
					WScript.Echo "snet("&j&",0)="""& netStart & """:" _
						& "snet("&j&",1)="""& netEnd & """:" _
						& "snet("&j&",2)="""& .Item(i).Name & """:" _
						& "snet("&j&",3)="""& .Item(i).Comment & """:"
					j=j+1
				Else
					WScript.Echo netStart & ";" _
						& netEnd & ";""" _
						& .Item(i).Name,""";""" _
						& .Item(i).Comment, """"
				End If
			End If
		Next
	End With

	dhcpmgr.Servers(1).Disconnect	
End Sub



' Microsoft (MCS) DHCP Objects 1.0.
'
' dhcpobjs.dll in the Windows 2000 server resource kit.
' In netmgmt.cab in the archive : dhcpobjs.exe
' The helpfile is dhcpobjs.chm
' (don't know if its in 2003 RK also)
'
' ** Quick references **
'Manager
'	.MajorVersion
'	.MinorVersion
'	.BuildVersion 
'	.About							#Method: show about dialog box
'								#Suspend the script!
'	.Servers
'		.Count
'		.Connect(iphostname)
'		.Disconnect(int)
'	.Servers(int)
'		.Scopes
'			.Count
'			.CreateNew()
'			.Add(startip,endip,subnet,name,Description, isActive)
'			.Refresh				#Reload from server
'		.Scopes(int)
'			.Name
'			.Address
'			.Delete
'			.Update					#Flush piending updates
'			.Reservations
'				.Count
'				.Refresh			#Reload from server
'			.Reservations(int)
'				#??
'				.Active
'				.Update				#Flush pending updates
'			.Exclusions
'				.Count
'				.CreateNew()
'				.Add(startip, endip)
'				.Refresh			#Reload from server
'			.Exclusions(int)
'				.StartAddress			#ReadOnly
'				.EndAddress			#ReadOnly
'				.Update				#Flush pending updates
'				#?? .Delete
'			.Options				#See .Options below
'		.SuperScopes
'			.Count
'			.Refresh				#Reload from server
'			.CreateNew
'		.SuperScopes(int)
'			.Name 
'			.MemberScopes
'				.Count
'				.Add dhcpsrvr.Scopes(1)		#We add an existing scope
'				.Remove int			#Remove the scope from superscope (not deleted)
'				.Update				#Flush pending updates
'			.MemberScopes()
'				.Remove(int)
'				.Scope				#See ".Scope" above
'		.DefaultOptions
'			.Count
'			.Refresh				#Reload from server
'		.DefaultOptions(int)
'			#...
'		.Options
'			.Count
'			.Refresh				#Reload from server
'			.Add( optionnumber, Value)
'		.Options(int)					#Read/Write
'		.Options(str)					#Read/Write (where str is "51", with quotes)
'			.Update
'			


'## Dim i64 As New DhcpObjects.Int64				#Store a 64bit integer.
'Dim i64 
'Set i64 = CreateObject("DhcpObjects.Int64")			#Store a 64bit integer.
'i64.High = 305419896						#print MSB
'i64.Low = -1698898192						#Print LSB
'Print Hex(i64.High) & Hex(i64.Low)

'## IPAddress ##
'Dim ipaddr 
' Set ipaddr = CreateNew("Dhcp.IPAddress")
'Dim ipaddr As New DhcpObjects.IPAddress

' Set the IP address using the IP string notation
'ipaddr.String = "192.1.1.1"
'Print ipaddr.String

' Set the IP address using a 32-bit hex integer value
'ipaddr.DWord = &HC0010101&

' 
'ipaddr = mgr.Servers.Connect("192.1.1.1").Scopes(1)'

' Set the IP address by specifying each byte
'ipaddr.Byte(1) = 1
'ipaddr.Byte(2) = 1
'ipaddr.Byte(3) = 1
'ipaddr.Byte(4) = 192


' Print "Class = " & Choose(ipaddr.Class, "A", "B", "C")
' Print "Host ID = " & Hex(ipaddr.HostID)
' Print "Net ID = " & Hex(ipaddr.NetID)

'ipaddr = "192.1.1.1"
'Print ipaddr.Compare("157.1.1.1")  ' Displays 1




' #########################################################################################
' http://www.highorbit.co.uk/?p=270
' VbScript: IPv4 Subnet math
'

' ** Convert an IP to binary **
' This function performs a bitwise comparison (AND) with each octet in the original IP to determine if each power of two is present starting with the highest, 128 allowing us to calculate the binary version of any IP address


Function ConvertIPToBinary(strIP)
  ' Converts an IP Address into it's Binary Form
 
  Dim arrOctets
  Dim strBinOctet
  Dim intOctet, i, j
 
  arrOctets = Split(strIP, ".")
  For i = 0 to UBound(arrOctets)
    intOctet = CInt(arrOctets(i))
    strBinOctet = ""
    For j = 0 To 7
      If intOctet And (2^(7 -j)) Then
        strBinOctet = strBinOctet & "1"
      Else
        strBinOctet = strBinOctet & "0"
      End If
    Next
    arrOctets(i) = strBinOctet
  Next
  ConvertIPToBinary = Join(arrOctets, ".")
End Function

' ** Convert a binary IP to a decimal IP
' It’s quite important that we are able to get back to the familiar form of the IP address, so this calculates the decimal form of an IP address based on the binary.

Function ConvertBinIPToDecimal(strBinIP)
  ' Convert binary form of an IP back to decimal
 
  Dim arrOctets
  Dim intOctet, i, j
 
  arrOctets = Split(strBinIP, ".")
  For i = 0 to UBound(arrOctets)
    intOctet = 0
    For j = 0 to 7
      intBit = CInt(Mid(arrOctets(i), j + 1, 1))
      If intBit = 1 Then
        intOctet = intOctet + 2^(7 - j)
      End If
    Next
    arrOctets(i) = CStr(intOctet)
  Next
 
  ConvertBinIPToDecimal = Join(arrOctets, ".")
End Function

' **** Convert a subnet mask to a mask length ****
' Occasionally it is desirable to calculate the subnet mask bit length. This can be done using the following.

Function MaskLength(strMask)
  ' Converts an subnet mask into a mask length in bits
 
  Dim arrOctets
  Dim intOctet, intMaskLength, i, j
 
  arrOctets = Split(strMask, ".")
  For i = 0 to UBound(arrOctets)
    intOctet = CInt(arrOctets(i))
    For j = 0 To 7
      If intOctet And (2^(7 -j)) Then
        intMaskLength = intMaskLength + 1
      End If
    Next
  Next
  MaskLength = intMaskLength
End Function


' **** Convert a mask length to a subnet mask ****
' If we convert into the mask length format we need to be able to convert back to a decimal mask again.

Function MaskLengthToIP(intMask)
  ' Converts a mask length to the IP format mask
 
  Dim arrOctets(3)
  Dim intFullOctets, intPartialOctetLen, i, j
  Dim intOctet
 
  intFullOctets = (intMask - (intMask Mod 8)) / 8
 
  For i = 0 To (intFullOctets - 1)
    arrOctets(i) = "255"
  Next
 
  intPartialOctetLen = intMask Mod 8
  If intPartialOctetLen > 0 Then
    For j = 0 To (intPartialOctetLen - 1)
      intOctet = intOctet + 2^(7 - j)
    Next
    arrOctets(i) = intOctet : i = i + 1
  End If
 
  For j = i To 3
    arrOctets(j) = "0"
  Next
 
  MaskLengthToIP = Join(arrOctets, ".")
End Function


' **** Calculate the subnet network address ****
' The functions above can be used with along with a bitwise AND operation against an IP address and subnet mask to calculate the network address.
'
' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.

Function CalcNetworkAddress(strIP, strMask)
  ' Generates the Network Address from the IP and Mask
 
  Dim arrOctets
  Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinNetwork
  Dim intOctet, i, j
 
  ' Conversion of IP and Mask to binary
  strBinIP = ConvertIPToBinary(strIP)
  strBinMask = ConvertIPToBinary(strMask)
 
  ' Bitwise AND operation (except for the dot)
  For i = 1 to Len(strBinIP)
    strIPBit = Mid(strBinIP, i, 1)
    strMaskBit = Mid(strBinMask, i, 1)
 
    If strIPBit = "1" And strMaskBit = "1" Then
      strBinNetwork = strBinNetwork & "1"
    ElseIf strIPBit = "." Then
      strBinNetwork = strBinNetwork & strIPBit
    Else
      strBinNetwork = strBinNetwork & "0"
    End If
  Next
 
  ' Conversion of Binary IP to Decimal
  CalcNetworkAddress= ConvertBinIPToDecimal(strBinNetwork)
End Function


' **** Calculate the first usable address of a subnet ****
' 
' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.
Function CalcRangeStart(strIP, strMask)
  ' Generates the Network Address from the IP and Mask
 
  Dim arrOctets
  Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinStart
  Dim intOctet, i, j
 
  ' Conversion of IP and Mask to binary
  strBinIP = ConvertIPToBinary(strIP)
  strBinMask = ConvertIPToBinary(strMask)
 
  ' Bitwise AND operation (except for the dot)
  For i = 1 to Len(strBinIP)
    strIPBit = Mid(strBinIP, i, 1)
    strMaskBit = Mid(strBinMask, i, 1)
 
    If strIPBit = "1" And strMaskBit = "1" Then
      strBinStart = strBinStart & "1"
    ElseIf strIPBit = "." Then
      strBinStart = strBinStart & strIPBit
    Else
      If i = Len(strBinIP) Then
        strBinStart = strBinStart & "1"
      Else
        strBinStart = strBinStart & "0"
      End If
    End If
  Next
 
  ' Conversion of Binary IP to Decimal
  CalcRangeStart = ConvertBinIPToDecimal(strBinStart)
End Function


' **** Calculate the last usable address of a subnet ****
' 
' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.
Function CalcRangeEnd(strIP, strMask)
  ' Generates the Network Address from the IP and Mask
 
  Dim arrOctets
  Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinEnd
  Dim intOctet, i, j
 
  ' Conversion of IP and Mask to binary
  strBinIP = ConvertIPToBinary(strIP)
  strBinMask = ConvertIPToBinary(strMask)
 
  ' Bitwise AND operation (except for the dot)
  For i = 1 to Len(strBinIP)
    strIPBit = Mid(strBinIP, i, 1)
    strMaskBit = Mid(strBinMask, i, 1)
 
    If strMaskBit = "1" Then
      strBinEnd = strBinEnd & strIPBit
    ElseIf strIPBit = "." Then
      strBinEnd = strBinEnd & strIPBit
    Else
      If i = Len(strBinIP) Then
        strBinEnd = strBinEnd & "0"
      Else
        strBinEnd = strBinEnd & "1"
      End If
    End If
  Next
 
  ' Conversion of Binary IP to Decimal
  CalcRangeEnd = ConvertBinIPToDecimal(strBinEnd)
End Function


' **** Calculate the subnet broadcast address ****
' To calculate the broadcast address we need to modify the CalcNetworkAddress function above. This time, we want it to set anything that isn’t covered by the mask to 1.
'
' Note that this function includes calls to both ConvertIPToBinary and ConvertBinIPToDecimal.

Function CalcBroadcastAddress(strIP, strMask)
  ' Generates the Broadcast Address from the IP and Mask
 
  Dim strBinIP, strBinMask, strIPBit, strMaskBit, strBinBroadcast
  Dim intOctet, i, j
  Dim arrOctets
 
  ' Conversion of IP and Mask to binary
  strBinIP = ConvertIPToBinary(strIP)
  strBinMask = ConvertIPToBinary(strMask)
 
  ' Set each unmasked bit to 1
  For i = 1 to Len(strBinIP)
    strIPBit = Mid(strBinIP, i, 1)
    strMaskBit = Mid(strBinMask, i, 1)
 
    If strIPBit = "1" Or strMaskBit = "0" Then
      strBinBroadcast = strBinBroadcast & "1"
    ElseIf strIPBit = "." Then
      strBinBroadcast = strBinBroadcast & strIPBit
    Else
      strBinBroadcast = strBinBroadcast & "0"
    End If
  Next
 
  ' Conversion of Binary IP to Decimal
  CalcBroadcastAddress = ConvertBinIPToDecimal(strBinBroadcast)
End Function

'Examples
'  strIp = "172.31.232.3"
'  strMask = "255.255.255.0"
'  wscript.echo "Network  : " & CalcNetworkAddress(strIP, strMask)
'  wscript.echo "Start IP : " & CalcRangeStart(strIP, strMask)
'  wscript.echo "End IP   : " & CalcRangeEnd(strIP, strMask)

'########################################################################"
' vbs_Internationalisation.vbs 0.01 - Internationalisation infrastructure
'
' Copyright (C) 2008 Frank Lin PIAT <fpiat@klabs.be>
' latest version is available from:
'     http://www.klabs.be/~fpiat/windows/vbs_Internationalisation/
'
' This file is free software; you can redistribute it and/or modify it
' under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
''             full license text : http://www.gnu.org/copyleft/gpl.html


' **** Internationalisation stuffs ****

' Load a dictionnary with translated strings
Sub Initialise_i18n
	i18n = Null
	' List of Locale ID (LCID)
	' http://msdn.microsoft.com/en-us/library/0h88fahh(VS.85).aspx

	Select Case GetLocale
		Case 1036,2060,3084,5132
			load_i18n_fr			' French / Francais
		Case 1034,11274,16394,13322,9226,5130,7178,12298,4106,18442,2058,19466,6154,10250,20490,15370,17418,14346,8202 
			load_i18n_es			' Spanish
		Case 1031,3079,5127,4103,2055
			load_i18n_de			' German
		Case Else
			i18n = Null			' Fallback to English
	End Select
End Sub

Function getI18n(str)
	If IsNull(i18n) Then
		getI18n = str
	ElseIf i18n.Exists(str) Then
		getI18n = i18n(str)
	Else
		getI18n = str
	End If
End Function

Sub gecho(str)
	wscript.echo getI18n(str)
End Sub

' Internationalise strings :

Sub load_i18n_fr()
	Set i18n = CreateObject("Scripting.Dictionary")
	'Help pages
	i18n.Add "To invoke this script, run:", _
		 "La syntaxe de ce script est la suivante:"
	i18n.Add "DhcpServerIP : The IP adress of the DHCP server(s)", _
		 "DhcpServerIP : l'adresse IP du/des serveur(s) DHCP"
	i18n.Add "  The list of the DHCP servers can be obtained by running :", _
		 "  La liste des serveurs dhcp peut être obtenue avec la commande :"
	i18n.Add "  (assuming DHCPMON helper was added to netsh with the command:", _
		 "  (Une fois le helper DHCP de netsh a été chargé en executant :"

	' options parser
	i18n.Add "Error: Option ""{option}"" is invalid.", _
		 "Erreur: L'option ""{option}"" inconnue."

	'Init
	i18n.Add "This script requires the DLL dhcpobjs.dll from Windows 2000 server resource kit.", _
		 "This script nécessite la DLL dhcpobjs.dll du resource kit Windows 2000 server."
	i18n.Add "(it is located in in the archive netmgmt.cab, the in dhcpobjs.exe).", _
		 "(la DLL est contenue dans l'archive netmgmt.cab, dans dhcpobjs.exe)."


End Sub

'Dim i18n
'SetLocale("es") 'Try your locales, like: de, es, fr, 1034, 1033...
'Initialise_i18n

'gecho "Hello"
'wscript.echo Replace(getI18n("My Name is %NAME%"), "%NAME%", "Franklin")



'########################################################################"


' Changelog
' v0.03
'	* Internationalisation
'	* show some explanation if the activex dhcp.manager isn't installed
'	* Change some variables names
'
' v0.02
'	* Add option "/printscopeas=range"  ("subnet" is the default)
'	* Add option "/noheader"