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.