Login to participate
Endpoint Management & Virtualization DownloadsRSS

CMS 7 Reboot Inventory for Windows

rpoag's picture

I have been poking around in the data collected and I did not see any reboot information being gathered, which we use for keeping users in compliance with company policy, so I had to write a new one. (I did play around with the legacy inventory provided with version seven but it crashed more often than not and it did not behave as expected when it did submit data so I bailed and started over.) I never had much luck with pulling the reboot information from the registry because sometimes the registry does not update so I pull the reboot event from the system log. I thought I would share that script with anyone who might be interested.

Caveats:

  1. You will need to create a custom data class with a single string field for this to work.
  2. You will need to insert the GUID for the above data class into the script where it is marked below.
  3. You may also need to change the GUID in the "nse.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"" line if your NS GUID is different than mine. There are sample custom inventories so you can check one of those to verify the NS GUID. If it is different just cut and paste.
Option Explicit
'On Error Resume Next
Dim objWMIService
Dim propValue
Dim objItem
Dim colItems
Dim nse
Dim objDCInstance
Dim objDataClass
Dim objDataRow
Dim temp1, temp2

'Create instance of Altiris NSE component
set nse = WScript.CreateObject ("Altiris.AeXNSEvent")

' Set the header data of the NSE
' Please don't modify this GUID
nse.To = "{1592B913-72F3-4C36-91D2-D4EDA21D2F96}"
nse.Priority = 1

'Create Inventory data block. Here assumption is that the data class with below guid is already configured on server
set objDCInstance = nse.AddDataClass ("{insert custom data class guid}")

set objDataClass = nse.AddDataBlock (objDCInstance)

'Fire WMI Query
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NTLogEvent where logfile='system' and eventcode='6005'")
For Each objItem in colItems
temp2 = objItem.TimeGenerated
If temp1 = "" Then
temp1 = temp2
ElseIf temp2 > temp1 Then
temp1 = temp2
End If
Next

'Set columns
set objDataRow = objDataClass.AddRow
objDataRow.SetField 0, temp1

nse.SendQueued

Hope this saves someone some time.

KSchroeder's picture

Nice!

I was looking at doing something similar for our NS6 environment; hadn't quite gotten to the point of writing up the WMI query, but you did it for me!  Thanks!

We have another query that seems to work most of the time but again relies on WMI and the system Performance counters (which sometimes are corrupted).  It writes the data to the registry in the ADO ISO/8601 format which is then collected by custom inventory.


Option Explicit
Dim oShell, oFs ' General scripting objects
Dim s, i, o, l ' Generic string, integer and object variables
Dim oWmi, oWmiSet
Dim sRegKey
Dim lPerfTim

On Error Resume Next
sRegKey = "HKLM\Software\MyCompany\Inventory\"

' Get scripting objects needed throughout script.
Err.Clear
Set oShell = CreateObject("WScript.Shell")
If Err.Number <> 0 Then WScript.Quit

' Refresh the Last Boot Time of the machine in the registry
s = ""
oShell.RegDelete sRegKey & "LastBootTime"
Err.Clear
Set oWmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
If Err.Number = 0 Then
' ***** WMI LastBootUpTime found to be wrong on Windows 2000, code removed ******
' Get LastBootTime from WMI
' Set oWmiSet = oWmi.ExecQuery("Select * from Win32_OperatingSystem")
' For Each o in oWmiSet
' s = cDate_WmiToAdo(o.LastBootUpTime)
' Exit For
' Next
' Get time (in seconds) that system has been running
Set oWmiSet = oWmi.ExecQuery("Select * from Win32_PerfRawData_PerfOS_System")
For Each o in oWmiSet
l = (o.Timestamp_Object - o.SystemUpTime)/o.Frequency_Object
Exit For
Next

' Get Current Time minus time system has been running to determine last boot time.
If IsNumeric(l) Then
l = CLng(l) * -1
s = DateAdd("s", l, Now())
s = cDate_SysToAdo(s)
End If
End If
oShell.RegWrite sRegKey & "LastBootTime", s, "REG_SZ"

' ...
' Converts a WMI datetime value to ADO's ISO 8601 format (yyyy-mm-ddThh:mm:ss)
Function cDate_WmiToAdo(sWmiDate)
On Error Resume Next
cDate_WmiToAdo = ""
If sWmiDate = "" Then Exit Function

cDate_WmiToAdo = cStr(Left(sWmiDate, 4) & "-" & _
Mid(sWmiDate, 5, 2) & "-" & _
Mid(sWmiDate, 7, 2) & "T" & _
Mid (sWmiDate, 9, 2) & ":" & _
Mid(sWmiDate, 11, 2) & ":" & _
Mid(sWmiDate, 13, 2))
End Function

' Converts a standard datetime value to ADO's ISO 8601 format (yyyy-mm-ddThh:mm:ss)
Function cDate_SysToAdo(sDateTime)
Dim aTime(6)
Dim i
On Error Resume Next
CDate_SysToAdo = ""
If Not IsDate(sDateTime) Then Exit Function

' Get datetimestamp in iso 8601 format
aTime(0) = Year(sDateTime)
aTime(1) = Month(sDateTime)
aTime(2) = Day(sDateTime)
aTime(3) = Hour(sDateTime)
aTime(4) = Minute(sDateTime)
aTime(5) = Second(sDateTime)

' Adjust components of date and time to make sure they all have two digits.
For i = 1 To 5
If Len(aTime(i)) = 1 Then aTime(i) = "0" & aTime(i)
Next
cDate_SysToAdo = cStr(aTime(0) & "-" & aTime(1) & "-" & aTime(2) & "T" _
& aTime(3) & ":" & aTime(4) & ":" & aTime(5))
End Function

Thanks,
Kyle
Symantec Trusted Advisor
If your question has been resolved, please be sure to click "Mark as Solution"! Thank you.