monitors:usb

no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


monitors:usb [2012/05/04 07:29] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== usb.vbs ======
 +
 +^ Author | [[ goldfndr@gmail.com | Richard Finegold ]] |
 +^ Compatibility | Xymon or Big Brother |
 +^ Requirements | VBScript and BBWin on client |
 +^ Download | None |
 +^ Last Update | 2012-05-03 |
 +
 +===== Description =====
 +This monitors what USB devices are plugged in, with a configuration file to alert if a USB device becomes unreachable. It does not check where (i.e. which hub/hub chain) a device is plugged in. Checked devices appear as normal text, unchecked devices are italicized small, hubs (if displayed at all) are italicized small gray struck-through.
 +
 +===== Installation =====
 +=== Client side ===
 +  * Copy usb.vbs (below) to your BBWin's ''ext'' folder.
 +  * Optionally change the DISPLAYHUB value to False if you don't want hubs displayed (normally gray strike-thru).
 +  * Edit your BBWin's ''etc/bbwin.cfg'' file:
 +    * Add a line in the ''externals'' section:<code xml>
 + <load value="cscript.exe ..\ext\usb.vbs" />
 +</code>
 +    * If the externals agent was disabled in the ''bbwin'' section (e.g. commented out or deleted), enable:<code xml>
 +        <load name="externals" value="externals.dll" />
 +</code>
 +   * If you want checking/alerting, create an ''etc/usb.cfg'' file:
 +     * The first character on each line is ''#'' for a comment or a digit for a quantity.
 +     * After a digit, add a space and the text of a Description or Information of a device, with an optional ''#'' for a comment. For example, <code text>
 +1 HASP
 +2 USB UltraPro  #Needed for Sentinel Protection Server
 +1 USB SuperPro
 +</code>
 +
 +=== Server side ===
 +(no server side changes needed)
 +
 +===== Source =====
 +==== usb.vbs ====
 +
 +<hidden onHidden="Show Code ⇲" onVisible="Hide Code ⇱">
 +<code vb>
 +Const dbg=True
 +
 +'The structure of this file is a number (quantity), a space, then the device Description or Information (match output).
 +'Use an empty file if you don't need to test anything (i.e. always green).
 +'Add a "#" to any line for comments.
 +Dim cfgfile : cfgfile = "..\etc\usb.cfg"
 +Const DISPLAYHUB = True
 +
 +Function CMEC(u)
 + 'Frequent are 0=OK, 22=disabled, 24=not present.  http://msdn.microsoft.com/en-us/library/aa394353(VS.85).aspx
 + Dim a : a = Array("Device is working properly." _
 + , "Device is not configured correctly." _
 + , "Windows cannot load the driver for this device." _
 + , "Driver for this device might be corrupted, or the system may be low on memory or other resources." _
 + , "Device is not working properly. One of its drivers or the registry might be corrupted." _
 + , "Driver for the device requires a resource that Windows cannot manage." _
 + , "Boot configuration for the device conflicts with other devices." _
 + , "Cannot filter." _
 + , "Driver loader for the device is missing." _
 + , "Device is not working properly. The controlling firmware is incorrectly reporting the resources for the device." _
 + , "Device cannot start." _
 + , "Device failed." _
 + , "Device cannot find enough free resources to use." _
 + , "Windows cannot verify the device's resources." _
 + , "Device cannot work properly until the computer is restarted." _
 + , "Device is not working properly due to a possible re-enumeration problem." _
 + , "Windows cannot identify all of the resources that the device uses." _
 + , "Device is requesting an unknown resource type." _
 + , "Device drivers must be reinstalled." _
 + , "Failure using the VxD loader." _
 + , "Registry might be corrupted." _
 + , "System failure. If changing the device driver is ineffective, see the hardware documentation. Windows is removing the device." _
 + , "Device is disabled." _
 + , "System failure. If changing the device driver is ineffective, see the hardware documentation." _
 + , "Device is not present, not working properly, or does not have all of its drivers installed." _
 + , "Windows is still setting up the device." _
 + , "Windows is still setting up the device." _
 + , "Device does not have valid log configuration." _
 + , "Device drivers are not installed." _
 + , "Device is disabled. The device firmware did not provide the required resources." _
 + , "Device is using an IRQ resource that another device is using." _
 + , "Device is not working properly. Windows cannot load the required device drivers.")
 + Dim n : n = u.ConfigManagerErrorCode 'Pass object for simplicity, but value is all we need
 + CMEC = n & "=Undefined?!"
 + if n <= UBound(a) then CMEC = n & "=" & a(n)
 +End Function
 +
 +Dim color : color = "green"
 +
 +Const wbemFlagReturnImmediately = &h10
 +Const wbemFlagForwardOnly = &h20
 +Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
 +
 +Phase "Read configuration file"
 +If not FSO.FileExists(cfgfile) then   WScript.Quit 2 'ERROR_FILE_NOT_FOUND
 +If FSO.GetFile(cfgfile).Size > 0 Then
 + With FSO.OpenTextFile(cfgfile, 1)
 + cfgfile = Split(.ReadAll, vbCRLF)
 + .Close
 + End With
 +Else
 + cfgfile = Array("") 'ReadAll gives an error for empty files. Workaround!
 +End If
 +
 +Phase "Parse configuration file"
 +Dim needed : Set needed = CreateObject("Scripting.Dictionary")
 +Dim usb : for each usb in cfgfile
 + if Instr(usb, "#") > 0 then usb = Trim(Left(usb, Instr(usb, "#") - 1))
 + if len(usb) > 3 then
 + if not IsNumeric(Left(usb, 1)) then
 + WScript.Echo """" & usb & """ is not in the correct format!"
 + WScript.Echo "First character must be a digit!"
 + WScript.Quit 13 'ERROR_INVALID_DATA
 + end if
 + needed(Trim(Mid(usb, 3))) = CInt(Trim(Left(usb, 2)))
 + end if
 +next
 +
 +Phase "Create WMI Query"
 +Dim WMI : Set WMI = GetObject("winmgmts:\\.\root\CIMV2")
 +
 +'Win32_USBDevice is short, but only seems to be available with SCCM installation.
 +'Win32_USBHub is almost as good, but it seems to exclude HID class devices, Bluetooth, etc.
 +'Both derive from Win32_PNPEntity, so go with that instead. Sorry!
 +
 +Dim WMIQuery : WMIQuery = "SELECT * FROM Win32_PNPEntity WHERE DeviceID Like 'USB%'"
 +Dim col : Set col = WMI.ExecQuery(WMIQuery, "WQL", wbemFlagReturnImmediately)
 +
 +Phase "Check " & col.Count & " devices"
 +Dim Summary, Table : Summary = "" : Table = ""
 +For Each usb In col
 + If Right(usb.Name, 4) = " Hub" then
 + Phase "Skip a WMI device: " & usb.Name
 + If DISPLAYHUB Then   Table = Table & Replace(DeviceLine(usb) _
 + , "<tr style=""", "<tr style=""text-decoration: line-through; color: gray; ")
 + Else
 + Phase "Check a WMI device: " & usb.Name
 + Table = Table & DeviceLine(usb)
 + End If
 +Next
 +
 +Function DeviceLine(usb)
 + 'Although usb.Name tends to be useful, sometimes it's generic (e.g. "USB Human Interface Device").
 + 'So try to look up the LocationInformation in the registry. Mention it.
 + 'Beware of OS; http://social.microsoft.com/Forums/en/genuinevista/thread/daad2598-028e-4763-ac9b-4546e4deec5e
 + Dim WSH : Set WSH = CreateObject("WScript.Shell")
 + On Error Resume Next 'In case the value isn't there
 + Dim s, nm : s = ""
 + Const ENM = "HKLM\System\CurrentControlSet\Enum\"
 + s = Trim(WSH.RegRead(ENM & usb.DeviceID & "\FriendlyName"))
 + if "" = s then s = Trim(WSH.RegRead(ENM & usb.DeviceID & "\LocationInformation"))
 + On Error Goto 0
 +
 + 'Shorten the DeviceDesc/LocationInformation if it has a semicolon (Vista, Server 2008, Windows 7)
 + If Instr(s, ";") > 1 then s = Trim(Mid(s, Instr(s, ";")+1))
 + nm = Trim(usb.Name) : If Instr(nm, ";") > 1 then nm = Trim(Mid(nm, Instr(nm, ";")+1))
 +
 + 'Make small and italic if configuration doesn't list as necessary
 + dim dl : dl = "<tr style=""font-style: italic; font-size: smaller;"">"
 + dim c : c = 0
 + if needed.Exists(nm) then
 + c = needed(nm) 'Needed count
 + dl = "<tr>"
 + end if
 + if needed.Exists(s) then
 + c = needed(s) 'Needed count
 + dl = "<tr>"
 + end if
 + dl = dl & "<td>" & nm & "<td>" & s & "<td>" & usb.DeviceID & "<td>&"
 + 'We could also add Service. Useful?
 + if usb.Status = "OK" then
 + dl = dl & "green"
 + elseif usb.Status = "Degraded" or usb.Status = "Pred Fail" then
 + dl = dl & "yellow"
 + if c > 0 then
 + if color = "green" then color = "yellow"
 + Summary = Summary & vbCRLF & "&yellow Needed device " & nm & " [" & s & "] is " & usb.Status
 + end if
 + else
 + dl = dl & "red"
 + if c > 0 then
 + color = "red"
 + Summary = Summary & vbCRLF & "&red Needed device " & nm & " [" & s & "] is " & usb.Status
 + end if
 + end if
 + dl = dl & " " & usb.Status & vbCRLF & "<td>" & CMEC(usb) & vbCRLF
 + if c > 0 then
 + c = c - 1
 + if 0 = c then
 + if needed.Exists(nm) then needed.Remove(nm) else needed.Remove(s)
 + else
 + if needed.Exists(nm) then needed(nm) = c else needed(s) = c
 + end if
 + end if
 + DeviceLine = dl
 +End Function
 +
 +Phase "Was anything found?"
 +'The first column is DeviceDesc/Caption/Name, the second column is LocationInformation.
 +If len(Table) > 0 then Table = "<table border=1>" & vbCRLF _
 + & "<tr><th>Description<th>Information<th>Device ID (Enumerator\Device\Instance)<th>Status<th>Error" & vbCRLF _
 + & Table & "</table>"
 +
 +Phase "Was anything missing?"
 +if needed.Count > 0 then
 + Quickie = "At least " & needed.Count & " USB devices needed but missing"
 + Summary = Table & vbCRLF & Summary
 + Summary = Summary & vbCRLF & "&red The following USB devices could not be found!"
 + for each usb in needed.keys
 + Summary = Summary & vbCRLF & " &clear Qty=" & needed(usb) & " : " & usb
 + next
 + color = "red"
 +else
 + Summary = Table & vbCRLF & Summary
 + Quickie = "All required USB devices present"
 +end if
 +
 +Phase "Write status"
 +WriteStatus "usb", color, Quickie, Summary
 +WScript.Quit 0
 +
 +'######################################################################
 +'Write out the status; depends on FSO and WSH
 +Sub WriteStatus(column, color, quickie, line)
 +'Why so long? Assume that client might collect file while writing, so make temp file and rename it.
 +'######################################################################
 + Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
 + Dim WSH : Set WSH = CreateObject("WScript.Shell")
 + Const BBWinreg = "HKLM\SOFTWARE\BBWin\tmpPath"
 + Const Questreg = "HKLM\SOFTWARE\Quest Software\BigBrother\bbnt\ExternalPath\"
 + On error resume next
 + 'Assume that, if BBWin is installed, they're using it; if not then they're using Quest BB client.
 + Dim colfile : colfile = WSH.RegRead(BBWinreg)
 + If "" = colfile then colfile = WSH.RegRead(Questreg)
 + If "" = colfile then Exit Sub 'Abort if nothing in the registry for location.
 + colfile = colfile & "\" & column 'Add the column name to make it a real colfile.
 + Dim tempfile : tempfile = colfile & ".$$$" 'Temporary file; use temporary name for safety!
 + If FSO.FileExists(tempfile) Then WScript.Quit 183'Bail out if already there (i.e. previous stuck)
 + On Error Resume Next
 + With FSO.CreateTextFile(tempfile, True)
 + if err then WScript.Quit err 'Bail out if unable to create file.
 + .WriteLine color & " " _
 + & WeekdayName(Weekday(Now),True) & " " _
 + & Mid(Now,1,InStr(Now," ")-1) & " " & TimeValue(Now) & " [" _
 + & WSH.Environment("Process")("COMPUTERNAME") _
 + & "] " & quickie
 + .Write line
 + .Close
 + End With
 + '***********************************************************
 + 'Rename file so client will see it (taking care to remove any unprocessed file first)
 + '***********************************************************
 + if FSO.FileExists(colfile) then FSO.DeleteFile(colfile)
 + FSO.MoveFile tempfile, colfile
 +End Sub
 +
 +'######################################################################
 +'If the script gets stuck, we can use Process Explorer to examine its environment
 +'######################################################################
 +Sub Phase(n)
 + if dbg then wscript.echo n
 + CreateObject("WScript.Shell").Environment("Process")("P-" & WScript.ScriptName) = n
 +End Sub
 +</code>
 +</hidden>
 +
 +===== Known  Bugs and Issues =====
 +(none)
 +
 +===== To Do =====
 +  * Perhaps also display each device's parent. But such additions would likely clutter the display.
 +  * Find better column headers than "Description" and "Information".
 +===== Credits =====
 +  * Nir Sofer's USBDeview, for making me realize that some additional device information was available that WMI didn't make obvious.
 +
 +===== Changelog =====
 +
 +  * **2012-05-03**
 +    * Initial release
  
  • monitors/usb.txt
  • Last modified: 2012/05/04 07:29
  • by 127.0.0.1