'SCCM_Inventory_Monitor.vbs 'Alan dot Kaplan at VA dot Gov 'v 1.0 4/26/11 Notifies when Software and Hardware Inventory complete ' optionally allowing cycles to be started. Option Explicit ' ======================================================== ' Get Last Inventory details ' ======================================================== Dim oActiveDL Dim Message Dim oResourceMgr Dim strComputer Dim objWMIService Dim colInv, objInv, strInvType Dim DateTime, dLastHWReport, dLastSWReport Dim dtmStart:dtmStart = Now() Dim iMax, iMaxMessages Dim objIE, k, strIETitle, blnFlag iMaxMessages = 22 iMax = iMaxMessages -1 ReDim aMessages(iMax) Dim WshShell Set WshShell = WScript.CreateObject("WScript.Shell") If WScript.Arguments.Count = 1 Then strComputer = WScript.Arguments(0) Else strComputer = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") Message = "This script will allow you to watch and be notified of SCCM inventory completion. " & _ "Optionally you will be allowed to begin a new hardware and software inventory cycle." & VbCrLf & VbCrLf & _ "This requires admin rights! Run script against what computer?" strComputer = InputBox(Message,"Enter Computer Name",strComputer) End If If strcomputer = "" Then WScript.Quit strComputer = UCase(strComputer) On Error Resume Next Set objWMIService = GetObject("winmgmts:{ImpersonationLevel=impersonate}\\" & strComputer & "\root\ccm\Invagt") If Err <> 0 Then MsgBox "Fatal Error. " & Err.Description,vbCritical + vbOKOnly,"Failed" WScript.Quit End If On Error GoTo 0 FirstInventory Dim retVal Message = Message & VbCrLf & VbCrLf & "Do you want to run the inventory cycles now? (No will begin monitoring only)" retVal = MsgBox(message,vbYesNoCancel,"Inventory Now?") If retVal = vbCancel Then WScript.Quit If retVal = vbYes Then TriggerSchedule "Hardware Inventory", "{00000000-0000-0000-0000-000000000001}" TriggerSchedule "Software Inventory", "{00000000-0000-0000-0000-000000000002}" End If message = "" ' Display based on IEDisplay.vbs ' Copyright (c) 2002 Richard L. Mueller ' Hilltop Lab web site - http://www.rlmueller.net ' Set IE display box title. Dashes ("-") are to move the Microsoft title ' appended to the title we specify out of view. ' blnFlag is set to False when the user closes the IE display box. strIETitle = strComputer & " Status Messages (30 Second Refresh)" & String(20, "-") blnFlag = True ' Initialize display box with initial message InitIE "Please Wait..." MsgIE "To abort, close this window" Dim iStartTime iStartTime = Timer InvLoop 'notify user that inventory is done beep 3 beep 3 ' Display final message MsgIE "SCCM Inventory Finished" If (blnFlag = False) Then Wscript.Quit Set WshShell = Nothing '============== Functions and Subs Sub InvLoop If (blnFlag = False) Then Wscript.Quit Set colInv = objWMIService.ExecQuery("Select InventoryActionID, LastCycleStartedDate, LastReportDate from InventoryActionStatus") ScrollIE "" ScrollIE "=====================" ElapsedTime For Each objInv In colInv strInvType = MID(objInv.InventoryActionID,35,3) If cint(strInvType) < 3 Then InvMessage strInvType, WMI2LocalTime(objInv.LastCycleStartedDate),WMI2LocalTime(objInv.LastReportDate) Next If dLastHWReport > dtmStart And dLastSWReport > dtmStart Then Exit Sub Else ScrollIE Message WScript.Sleep 30000 InvLoop End If End Sub Sub FirstInventory () Set colInv = objWMIService.ExecQuery("Select InventoryActionID, LastCycleStartedDate, LastReportDate from InventoryActionStatus") Message = "" For Each objInv In colInv strInvType = MID(objInv.InventoryActionID,35,3) Select Case cint(strInvType) Case 1 Message = Message & "Hardware Inventory Last Started: "& WMI2LocalTime(objInv.LastCycleStartedDate) & VbCrLf & _ "Hardware Inventory Last Report Date: " & WMI2LocalTime(objInv.LastReportDate) & VbCrLf Case 2 Message = Message & "Software Inventory Last Started: "& WMI2LocalTime(objInv.LastCycleStartedDate) & VbCrLf & _ "Software Inventory Last Report Date: " & WMI2LocalTime(objInv.LastReportDate) & VbCrLf Case Else End Select Next End Sub Function TriggerSchedule(strDescription, strAction) On Error Resume Next 'WMIX2 helped here, http://www.pjtec.com/Products/WMIX/index.html Dim oSMSClass,objInParams,objOutParams, objWMI Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\" & "ROOT\ccm") If Err <> 0 Then MsgBox "WMI Error connecting to Root\CCM: " & Err.Description,vbCritical + vbOKOnly,"Failed" WScript.Quit End If Set oSMSClass = objWMI.Get("SMS_Client") If Err <> 0 Then MsgBox "Error connecting to SCM_Client: " & Err.Description,vbCritical + vbOKOnly,"Failed" WScript.Quit End If ' Obtain an InParameters object specific to the SMS_Client class. Set objInParams = oSMSClass.Methods_("TriggerSchedule").inParameters.SpawnInstance_() ' Add the input parameters. objInParams.Properties_.item("sScheduleID") = strAction ' Execute method and capture the return values. Set objOutParams = oSMSClass.ExecMethod_("TriggerSchedule", objInParams) ' Check return values. If Err = 0 Then WshShell.Popup "Executed " & strDescription & " on " & strComputer & ", Success",10, "Cycle Started" Else MsgBox "Failed to execute " & strDescription & " on " & strComputer, vbCritical + vbOKOnly,"Failed" WScript.Quit End If On Error GoTo 0 End Function Function InvMessage (strInvType, dLastStart, dLastReport) Dim strInvText Select Case strInvType Case "001" ScrollIE "Hardware Inventory" dLastHWReport = dLastReport Case "002" ScrollIE "Software Inventory" dLastSWReport = dLastReport End Select ScrollIE "..Last Start: " & dLastStart ScrollIE "..Last Report: " & dLastReport End Function Function WMI2LocalTime(strWMITime) Const CONVERT_TO_LOCAL_TIME = True ' Create a new datetime object. Set DateTime = CreateObject("WbemScripting.SWbemDateTime") 'Set Value dateTime.Value = strWMITime 'Return localtime VT_DATE format. WMI2LocalTime = dateTime.GetVarDate(CONVERT_TO_LOCAL_TIME) Set DateTime = Nothing End Function Sub ScrollIE(text) Dim strMessage Add2End (text) strMessage = Join(aMessages,VbCrLf) strMessage = replace(strMessage,VbCrLf & VbCrLf,"") MsgIE strMessage End Sub Sub Add2End(item) Dim z, i If IsEmpty(aMessages(iMax)) Then For z = 0 To iMax If IsEmpty(amessages(z)) Then amessages(z) = Item Exit Sub End If Next End If For i = 0 To iMax -1 AMessages(i)= aMessages (i+1) Next amessages(imax) = item End Sub Sub MsgIE(strMsg) wshShell.AppActivate strIETitle ' Subroutine to display message in IE box and detect when the ' box is closed by the program or the user. On Error Resume Next If (strMsg = "IE_Quit") Then blnFlag = False objIE.Quit Else objIE.Document.Body.InnerText = strMsg If (Err.Number <> 0) Then Err.Clear blnFlag = False Exit Sub End If On Error GoTo 0 wshShell.AppActivate strIETitle End If End Sub Sub InitIE(strMsg) ' Subroutine to initialize the IE display box. Dim intWidth, intHeight, intWidthW, intHeightW Set objIE = CreateObject("InternetExplorer.Application") objIE.ToolBar = False objIE.StatusBar = False objIE.Resizable = True objIE.Navigate("about:blank") Do Until objIE.readyState = 4 Wscript.Sleep 100 Loop intWidth = objIE.document.ParentWindow.Screen.AvailWidth intHeight = objIE.document.ParentWindow.Screen.AvailHeight intWidthW = intWidth * .40 intHeightW = intHeight * .40 Dim oWin Set oWin = objIE.document.ParentWindow oWin.resizeto intWidthW, intHeightW oWin.moveto (intWidth - intWidthW)/2, (intHeight - intHeightW)/2 objIE.document.Write " " & strMsg & " " oWin.document.body.style.backgroundcolor = "LightBlue" oWin.document.body.scroll="Yes" oWin.document.body.style.Font = "10pt 'Courier New'" oWin.document.body.style.borderStyle = "outset" oWin.document.body.style.borderWidth = "4px" objIE.document.Title = strIETitle objIE.Visible = True WScript.Sleep 200 wshShell.AppActivate "http:/// - "& strIETitle End Sub Sub beep(iTimes) dim ibeeps for ibeeps = 1 to iTimes WshShell.run "cmd /C " & chr(34) & "@echo " & chr(7) & chr(34),0,True Sleep 500 Next End Sub Sub ElapsedTime() Dim iHours, iMinutes, iSeconds, iElapsedTime, iEndTime iEndTime = Timer iElapsedTime = iEndTime - iStartTime iHours = Round((iElapsedTime /60/60),0) iMinutes = round((iElapsedTime /60),0) iSeconds = iElapsedTime Mod 60 ScrollIE "Elapsed Time: " & padNum(ihours) &":" & padnum(iminutes) & ":" & padNum(iseconds) End Sub Function PadNum(strNum) If Len(strnum) = 1 Then padnum = "0" & strnum Else PadNum = strNum End If End Function