;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       WMIProcessList() 
;; 
;;ACTION         Return a list of process info from a computer 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        1.1 - 2009/02/20 
;; 
;;HISTORY        1.0 - 2007/10/12 - Initial Release 
;;		 Written as a replacement for PSList(), which uses SysInternals PSList.exe 
;;		 1.1 - 2009/02/20 - Added CFlag support to return command line 
;;                                  instead of Process Name 
;; 
;;SYNTAX         WMIProcessList([Process] [, Target] [, AuthPtr] [, CFlag]) 
;; 
;;PARAMETERS     Process - OPTIONAL - String 
;;               - Specify the PID or process (group) by name to report. Returns all 
;;               process data if not specified. 
;; 
;;		 Target - OPTIONAL - String 
;;               - The name of system to query 
;; 
;;               AuthPtr - OPTIONAL - Object 
;;               - The pre-authenticated WMI object pointer. 
;;                 Use WMIAuthenticate() udf to create the AuthPtr value. 
;;                 AuthPtr is not needed if user has admin rights. 
;; 
;;		 CFlag - OPTIONAL - Integer 
;;               - Returns the complete command line instead of the process name. 
;; 
;;REMARKS        By default, returns a detailed list of all processes from the local 
;;               computer. An alternate computer can be specified, as can a specific 
;;               process. When specifying processes, you can use a name (cmd.exe) or 
;;               process ID. If you specify a name, all processeses matching that name 
;;               will be returned, while specifying a PID will return exactly one 
;;               element that matches that process (if it was found).  If no match 
;;               is found, the function exits with status 2 (file not found). 
;; 
;;RETURNS        Array of comma-delimited values, one element per process: 
;;			Process Name 
;;			Process ID (PID) 
;;			Thread Count 
;;			Handle Count 
;;			Memory Usage (Bytes) 
;;			User Time	D:HH:MM:SS.sss format 
;;			Kernel Time	D:HH:MM:SS.sss format 
;;			Elapsed Time	D:HH:MM:SS.sss format 
;; 
;;DEPENDENCIES   WMI, TimeDiff() external UDF 
;; 
;;TESTED WITH    W2K, WXP, W2K3, Vista, x64 
;; 
;;EXAMPLES        
; 
Function WMIProcessList(OPTIONAL $_Process, OPTIONAL $_Computer, OPTIONAL $_pAuth, OPTIONAL $_CFlag)
 
  Dim $_objWMIService, $_colItems, $_objItem	; WMI object vars 
  Dim $_Line					; line string 
  Dim $_aTmp[0], $_I				; return array, index 
  Dim $_					; temp var 
  Dim $_BTime, $_CTime				; boot and current times from target system 
 
  $_I = -1
 
  ; insure a properly formatted computer name, default to local computer is not specified 
  $_Computer = IIf(Not $_Computer, '.', Join(Split($_Computer,'\'),''))
 
  ; If a pre-authenticated WMI object pointer was provided, use it, otherwise create a new object pointer 
  If $_pAuth
    $_objWMIService = $_pAuth
  Else
    $_objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Computer + '\root\cimv2')
    If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
  EndIf
 
  ; Get the current and boot times from the client system 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
  For each $_objItem in $_colItems
    $_BTime = $_objItem.LastBootUpTime			; host-local boot time 
    $_CTime = $_objItem.LocalDateTime			; host-local current time 
  Next
 
  $_colItems = 0
  ; convert to a normalized time string 
  $_CTime = SubStr($_CTime, 1,4) + '/' + SubStr($_CTime, 5,2) + '/' +SubStr($_CTime, 7,2) + ' '
         + SubStr($_CTime, 9,2) + ':' + SubStr($_CTime, 11,2) + ':' + SubStr($_CTime, 13,6)
 
  ; get the collection of process objects 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Process",,48)
  If @ERROR   $_colItems = 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
 
  ; Enumerate the collection of process data 
  For Each $_objItem in $_colItems
    ; add the data to the array if no process is specified, or if a specific process name or ID is specified 
    If Not $_Process Or $_Process = $_objItem.Name Or $_Process = $_objItem.ProcessID 
      $_Line =  IIf($_CFlag, $_objItem.CommandLine, $_objItem.Name)
      $_Line = $_Line + ',' + $_objItem.ProcessID
      $_Line = $_Line + ',' + $_objItem.Priority
      $_Line = $_Line + ',' + $_objItem.ThreadCount
      $_Line = $_Line + ',' + $_objItem.HandleCount
      $_Line = $_Line + ',' + $_objItem.WorkingSetSize
      ; convert the following to d:hh:mm:ss.sss format 
      $_Line = $_Line + ',' + _WMIPLTC(CDbl($_objItem.UserModeTime) * 0.0000001)
      $_Line = $_Line + ',' + _WMIPLTC(CDbl($_objItem.KernelModeTime) * 0.0000001)
      ; Use the system boot time if creation date is not set 
      $_ = IIf($_objItem.CreationDate , $_objItem.CreationDate, $_BTime)
      ; calculate elapsed time and convert to d:hh:mm:ss.sss format 
      $_Line = $_Line + ',' +  _WMIPLTC(_WMIPLET($_, $_CTime))
      ; Update the array 
      $_I = $_I + 1
      ReDim Preserve $_aTmp[$_I]
      $_aTmp[$_I] = $_Line
    EndIf
  Next
 
  ; return the array, close the collection, and gripe if no items were found 
  $WMIProcessList = $_aTmp
  $_colItems = 0
  If $_Process and $_I < 0 Exit 1911 EndIf
  Exit 0
 
EndFunction
 
 
; support function to calculate elapsed time as Seconds 
; Dependent on TimeDiff UDF! 
Function _WMIPLET($_Time, $_CTime)
 
  ; Break into Date and Time parts, including 3 decimal points 
  $_Time = SubStr($_Time, 1,4) + '/' + SubStr($_Time, 5,2) + '/' +SubStr($_Time, 7,2) + ' '
         + SubStr($_Time, 9,2) + ':' + SubStr($_Time, 11,2) + ':' + SubStr($_Time, 13,6)
 
  ; return the value with 3 decimal places 
  $_WMIPLET = TimeDiff($_Time, $_CTime, '', 1); FormatNumber(, 3, -1, 0, 0) 
  Exit 0
 
EndFunction
 
 
; support function to conver the time value (100ns units) to D:H:M:S.s format 
Function _WMIPLTC($_Units)
 
  Dim $_D, $_H, $_M, $_S		; day, hour, minute, & second values 
 
  ; Find d/h/m and subtract result from units 
  $_D = Int($_Units / 86400)	$_Units = $_Units - $_D * 86400
  $_H = INT($_Units/3600)	$_Units = $_Units - $_H * 3600
  $_M = INT($_Units/60)
  $_S = FormatNumber($_Units - $_M * 60, 3, -1, 0, 0)
 
  ; return a time string 
  $_WMIPLTC = '' + $_D + ':' + $_H + ':' + $_M + ':' + $_S
  Exit 0
 
EndFunction