Did you ever need to know, to wich network switch a computer is connected? When you are a system administrator in a large company with tousends of users, this can be difficult. But when you use SCCM for OS or Software deployment, you have a good inventory tool integreated. Unfortunately SCCM by default only collect datas which the client operating system knows. Your Windows computers doesn’t known to which switch or port they are connected, but if you have Cisco switches the computers would be able to collect this information. Fact is that switches from Cisco are spreading all 60 seconds a lot of information about them to the connected ports (you can disable this, but by default it’s enabled). So you need only a tool to gather this information an write it to the SCCM.
In my case i wrote a vb-script, which runs a little capture tool tcpdump.exe (http://www.microolap.com/products/network/tcpdump/) and wait for the CDP informations. As soon the CDP informations are gathered, they would be writen to a MIF-file. SCCM collect this files frequently and writes the datas to his Database, where you can use it in an Query or an Report.
This is the script, which i tested with Windows XP SP3 and Windows 7 SP1:
' ===========================================================================================
'
' Script Information
'
' Filename: getCDPinformations.vbs
' Author: Josh Burkard
' Date: 25.05.2011
' Description: get CDP informations from all enabled network adapters
' - writes the information to SCCM MIF file
'
' ===========================================================================================
' Constants
' ===========================================================================================
Const NETWORK_CONNECTIONS = &H31&
Const ForAppending = 8
strScriptPath = "\\domain.local\netlogon" ' Path where TCPdump.exe is
strMifFile = "\CDP.mif"
strComputer = "."
' ===========================================================================================
' Check Script is being run with CSCRIPT rather than WSCRIPT due to using stdout
' ===========================================================================================
If UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" Then
strPath = Wscript.ScriptFullName
' Wscript.Echo "This script must be run under CScript." & vbCrLf & vbCrLf & "Re-Starting Under CScript"
strCommand = "%comspec% /K cscript //NOLOGO " & Chr(34) & strPath & chr(34)
Set objShell = CreateObject("Wscript.Shell")
objShell.Run(strCommand)
Wscript.Quit
End If
Set objShell = CreateObject("Wscript.Shell")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objShellApp = CreateObject("Shell.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
' ===========================================================================================
' Get Temporary and MIF-file directory
' ===========================================================================================
strTempDir = objShell.ExpandEnvironmentStrings("%TEMP%")
strWinDir = objShell.ExpandEnvironmentStrings("%WINDIR%")
strComputerName = objShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
strProcessorArchitecture = objShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
If strProcessorArchitecture = "AMD64" Then
strNoIDMifRegLocation = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\SMS\Client\Configuration\Client Properties\NOIDMIF Directory"
Else
strNoIDMifRegLocation = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Client\Configuration\Client Properties\NOIDMIF Directory"
End If
strNoIDMifDir = objShell.RegRead(strNoIDMifRegLocation)
If objFSO.FileExists(strTempDir & strMifFile) Then
objFSO.DeleteFile(strTempDir & strMifFile)
End If
' ===========================================================================================
' Get Datas and write it to the MIF-file
' ===========================================================================================
Set objFolder = objShellApp.Namespace(NETWORK_CONNECTIONS)
Set oAdapters = objWMIService.ExecQuery ("Select * from Win32_NetworkAdapterConfiguration where (IPenabled = True)")
i = 0 ' Counter of detected CDP-Informations
' Enumerate the results (list of NICS). "
For Each oAdapter In oAdapters
strCommand = strScriptPath & "\tcpdump -nn -v -s 1500 -i \Device\" & oAdapter.SettingID & " -c 1 ether[20:2] == 0x2000"
Wscript.echo "Executing TCP Dump for Adapter " & chr(34) & oAdapter.SettingID & chr(34) & VbCrLF
Wscript.echo strCommand & VbCrLF
Set objExec = objShell.Exec(strCommand)
count = 0
Do Until objExec.Status
count = count +1
'Timeout to Deal with Non CDP Enabled Devices
If count = 1200 then
objExec.terminate
wscript.quit
End If
Wscript.Sleep 250
Loop
' Loop through the output of TCPDUMP stored in stdout and retrieve required fields
' Namely switch name, IP and Port
While Not objExec.StdOut.AtEndOfStream
strLine = objExec.StdOut.ReadLine
If Instr(UCASE(strLine),"DEVICE-ID") > 0 Then
strDeviceID = Mid(strLine,(Instr(strLine,chr(39))+1),(Len(StrLine) - (Instr(strLine,chr(39))+1)))
End If
If Instr(UCASE(strLine),"ADDRESS ") > 0 Then
strDeviceIP = Right(strLine,(Len(strLine) - (Instrrev(strLine,")")+1)))
End If
If Instr(UCASE(strLine),"PORT-ID") > 0 Then
strPort = Mid(strLine,(Instr(strLine,chr(39))+1),(Len(StrLine) - (Instr(strLine,chr(39))+1)))
End If
Wend
If strPort <> "" AND strDeviceIP <> "" Then
i = i + 1 ' Counter of detected CDP-Informations
if i = 1 then
Set objMifFile = objFSO.OpenTextFile(strTempDir & strMifFile, ForAppending, True)
objMifFile.Writeline "Start Component"
objMifFile.Writeline " Name = " & Chr(34) & "WORKSTATION" & Chr(34)
end if
objMifFile.Writeline " Start Group"
objMifFile.Writeline " Name = " & Chr(34) & "Cisco Discovery Protocol" & Chr(34)
objMifFile.Writeline " ID = " & i
objMifFile.Writeline " Class = " & Chr(34) & "CiscoDiscoveryProtocol" & Chr(34)
objMifFile.Writeline " Start Attribute"
objMifFile.Writeline " Name = " & Chr(34) & "SwitchName" & Chr(34)
objMifFile.Writeline " ID = 1"
objMifFile.Writeline " ACCESS = READ-ONLY"
objMifFile.Writeline " Storage = Specific"
objMifFile.Writeline " Type = String(100)"
objMifFile.Writeline " Value = " & Chr(34) & strDeviceID & Chr(34)
objMifFile.Writeline " End Attribute"
objMifFile.Writeline " Start Attribute"
objMifFile.Writeline " Name = " & Chr(34) & "SwitchIP" & Chr(34)
objMifFile.Writeline " ID = 2"
objMifFile.Writeline " ACCESS = READ-ONLY"
objMifFile.Writeline " Storage = Specific"
objMifFile.Writeline " Type = String(100)"
objMifFile.Writeline " Value = " & Chr(34) & strDeviceIP & Chr(34)
objMifFile.Writeline " End Attribute"
objMifFile.Writeline " Start Attribute"
objMifFile.Writeline " Name = " & Chr(34) & "SwitchPort" & Chr(34)
objMifFile.Writeline " ID = 3"
objMifFile.Writeline " ACCESS = READ-ONLY"
objMifFile.Writeline " Storage = Specific"
objMifFile.Writeline " Type = String(100)"
objMifFile.Writeline " Value = " & Chr(34) & strPort & Chr(34)
objMifFile.Writeline " End Attribute"
objMifFile.Writeline " End Group"
End If
Next 'oAdapter
If i > 0 Then
objMifFile.Writeline "End Component"
objMifFile.Close
If objFSO.FileExists(strNoIDMifDir & strMifFile) Then
objFSO.DeleteFile(strNoIDMifDir & strMifFile)
End If
objFSO.MoveFile strTempDir & strMifFile, strNoIDMifDir & strMifFile
End If
Cause the script need’s elevated user rights, i integrated the script in group policy to run at computer startup.