$Host = '' ; define host that returns null data
WMIUptime($Host)[4] ?
@ERROR ' / ' @SERROR ?
;;
;;======================================================================
;;
;;FUNCTION WMIUptime()
;;
;;ACTION Reads the boot and current time from a defined host and
;; calculates the length of time the system has been up.
;;
;;AUTHOR Glenn Barnas
;;
;;VERSION 1.1 / 2007/04/05 - Authentication, rename to WMIUptime
;; Adjustment for uptime across timezone changes
;;
;;SYNTAX WMIUptime([host] [,AuthPtr])
;;
;;PARAMETERS host - OPTIONAL - name of system to query
;;
;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer
;; Use WMIAuthentication() udf to create the AuthPtr value
;; AuthPtr is not needed if user has admin rights
;;
;;REMARKS Gets both the boot and local time from the remote system,
;; eliminating issues with timezone differences between target
;; and client.
;;
;;RETURNS Array containing Days, Hours, Minutes, and Seconds of uptime.
;; Also returns the cTime value in element 4
;;
;;DEPENDENCIES WMI support
;;
;;TESTED WITH W2K, WXP, W2K3
;;
;;EXAMPLES $Host = ''
;; $Up = WMIUptime($Host)
;; $Host has been up for ' $Up[0] ' days!'
;;
;; $Host = 'server'
;; $objWMI = WMIAuthenticate('computer', 'userid', 'User-P@ss!')
;; $Up = WMIUptime($Host, $objWMI)
;; 'Secure host ' $Host ' has been up for ' $Up[0] ' days!'
;
Function WMIUpTime(OPTIONAL $_Target, OPTIONAL $_pAuth)
Dim $_Bt[3], $_Ct[3], $_U[4] ; time arrays for boot, current, and uptime
Dim $_, $_O ; Index var, Offset flag
Dim $_B, $_C ; boot and current time strings
Dim $_Bo, $_Co ; boot and current time offsets
Dim $objWMIService, $colItems, $objItem ; WMI object vars
$WMIUptime = -1 ; default to invalid value
$_Target = IIf($_Target, $_Target, '.')
If InStr($_Target, '\') $_Target = Join(Split($_Target, '\'), '') EndIf
If $_pAuth
$objWMIService = $_pAuth
Else
$objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2')
If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
EndIf
$colItems = $objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For each $objItem in $colItems
$_B = $objItem.LastBootUpTime ; host-local boot time
$_C = $objItem.LocalDateTime ; host-local current time
'B: ' $_B ?
'C: ' $_C ?
; format is YYYYMMDDhhmmss.ssssss+ooo (or -ooo)
; Get the timezone offset. The offset will not play into the calculation unless
; the timezone switched between reboots, such as going from Standard to DaylightSavings
If InStr($_B, '-') Or InStr($_B, '+')
$_Bo = Val(SubStr($_B, 23)) ; boot timezone offset
$_Co = Val(SubStr($_C, 23)) ; current timezone offset
$_O = ($_Co - $_Bo) * 60 ; find the difference, usually will be zero
EndIf
; strip off the fractional seconds and time zone offset value
$_B = Split($_B, '.')[0]
$_C = Split($_C, '.')[0]
; format is now YYYYMMDDhhmmss - put into array
$_Bt[0] = Val(SubStr($_B, 1, 4)) - 2000
$_Bt[1] = Val(SubStr($_B, 5, 2))
$_Bt[2] = Val(SubStr($_B, 7, 2))
$_Bt[3] = 1.0 * SubStr($_B,13) + 60.0 * SubStr($_B,11,2) + 3600.0 * SubStr($_B,9,2)
$_Ct[0] = Val(SubStr($_C, 1, 4)) - 2000
$_Ct[1] = Val(SubStr($_C, 5, 2))
$_Ct[2] = Val(SubStr($_C, 7, 2))
$_Ct[3] = 1.0 * SubStr($_C,13) + 60.0 * SubStr($_C,11,2) + 3600.0 * SubStr($_C,9,2)
; Convert dates to Days, then convert to seconds and add the time value
If $_Bt[1] < 3
$_Bt[1] = $_Bt[1] + 12
$_Bt[0] = $_Bt[0] - 1
EndIf
$_B = $_Bt[2] + ( 153 * $_Bt[1] - 457 ) / 5 + 365 * $_Bt[0] + $_Bt[0] / 4 - $_Bt[0] / 100 + $_Bt[0] / 400 - 306
$_B = CDbl($_B) * 86400.0
$_B = $_B + $_Bt[3]
If $_Ct[1] < 3
$_Ct[1] = $_Ct[1] + 12
$_Ct[0] = $_Ct[0] - 1
EndIf
$_C = $_Ct[2] + ( 153 * $_Ct[1] - 457 ) / 5 + 365 * $_Ct[0] + $_Ct[0] / 4 - $_Ct[0] / 100 + $_Ct[0] / 400 - 306
$_C = CDbl($_C) * 86400.0
$_C = $_C + $_Ct[3]
; Calculate uptime as cTime, then convert to days / hours / minutes / seconds
$_ = $_C - $_B + $_O
$_U[4] = $_ ; return the cTime value
$_U[0] = Int($_ / 86400)
$_ = $_ Mod 86400
$_U[1] = $_ / 3600
$_ = $_ Mod 3600
$_U[2] = $_ / 60
$_U[3] = $_ Mod 60
Next
$WMIUptime = $_U
EndFunction