Jump to content

Is there a way to tell how long a user has been logged in?


 Share

Recommended Posts

I've looked at Win32_Session, Win32_LogonSession, Win32_NetworkLoginProfile -- the easiest one seems to be enumerating through all of the sessions reported in Win32_LogonSession.StartTime method but it returns a bunch of different values that I'm having to create an elaborate function in order to compare the values and find the most recent session to assume it's the current user. So my question is... is there a better (easier) way to determine the time that the currently logged on user actually logged in at?

My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Link to comment
Share on other sites

@thepip3r

This might get you started.

#include <date.au3>

$strComputer = "."
$userName = @UserName

 $objWMIService = ObjGet("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")

 $colItems = $objWMIService.ExecQuery ("Select * from Win32_NetworkLoginProfile where caption = '" & StringUpper($userName) &"'")

For $objItem in $colItems
    $dtmWMIDate = $objItem.AccountExpires
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    $dtmWMIDate = $objItem.LastLogoff
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    Consolewrite ("Last Logoff: " & $strReturn & @CR)
    $dtmWMIDate = $objItem.LastLogon
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    Consolewrite ("Last Logon: " & $strReturn & @CR)
      

Next
 
Func WMIDateStringToDate($dtmWMIDate)
    Local $Return
    If Not $dtmWMIDate ="" Then
  
    Return (StringMid($dtmWMIDate, 5, 2) & "/" & _
            StringMid($dtmWMIDate, 7, 2) & "/" & StringLeft($dtmWMIDate, 4) _
            & " " & StringMid($dtmWMIDate, 9, 2) & ":" & StringMid($dtmWMIDate, 11, 2) & ":" & StringMid($dtmWMIDate,13, 2))

    Return $Return
    Endif
EndFunc

regards,

ptrex

Edited by ptrex
Link to comment
Share on other sites

  • Moderators

@thepip3r

This might get you started.

#include <date.au3>

$strComputer = "."
$userName = @UserName

 $objWMIService = ObjGet("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")

 $colItems = $objWMIService.ExecQuery ("Select * from Win32_NetworkLoginProfile where caption = '" & StringUpper($userName) &"'")

For $objItem in $colItems
    $dtmWMIDate = $objItem.AccountExpires
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    $dtmWMIDate = $objItem.LastLogoff
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    Consolewrite ("Last Logoff: " & $strReturn & @CR)
    $dtmWMIDate = $objItem.LastLogon
    $strReturn = WMIDateStringToDate($dtmWMIDate)
    Consolewrite ("Last Logon: " & $strReturn & @CR)
      

Next
 
Func WMIDateStringToDate($dtmWMIDate)
    Local $Return
    If Not $dtmWMIDate ="" Then
  
    Return (StringMid($dtmWMIDate, 5, 2) & "/" & _
            StringMid($dtmWMIDate, 7, 2) & "/" & StringLeft($dtmWMIDate, 4) _
            & " " & StringMid($dtmWMIDate, 9, 2) & ":" & StringMid($dtmWMIDate, 11, 2) & ":" & StringMid($dtmWMIDate,13, 2))

    Return $Return
    Endif
EndFuncoÝ÷ Ú· j·l¦ÚÞÇú®¢×ßÛޱ秶­XÂj׶¸§:j׬z÷«j[bë½éðéâ¶ÈhºWkzÛ«©ò¶§+]¡ë"az¼(­Û½éâ~Ø^­è¬mjö¥×Zµë-®)à äëÊØb²Þ¢ëZºÚ"µÍ[ÈÓRQ][ÕÑ]J ÌÍÙUÓRQ]JBSØØ[    ÌÍÜ×Ü]H    ][ÝÉÌLÐJ    ÌLÙÍJJ   ÌLÙÌJJ   ÌLÙÌJJ   ÌLÙÌJJ   ÌLÙÌJJ   ÌLÙÌJJÊIÌLÞ][ÝÂIÌÍÙUÓRQ]HHÝ[ÔYÑ^XÙJ ÌÍÙUÓRQ]K   ÌÍÜ×Ü] ][ÝÉÌLÌÉÌLÌËÉÌLÌH    ÌLÍÌLÍNÌLÍ][ÝÊBRY^[YH[] ][ÝÉ][ÝÂT]  ÌÍÙUÓRQ]B[[

Edit:

Fixed expression to only look at the beginning of the string.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I appreciate the code snippet ptrex but running your script, I found the same reason I didn't use the Win32_NetworkLoginProfile class; the data returned was not reflective of the current session. Like when I ran your script, it says that last login was on the 12th, but I'm logged into it now on the 13th. I'm going to try to use the "where caption=" in my WQL statement for the "Win32_LogonSession" class which does show me the current logged in session, it just seems to show me a bunch more information as well.

btw... is there a good book you could recommend on getting better with WQL and WMI?

My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Link to comment
Share on other sites

btw... is there a good book you could recommend on getting better with WQL and WMI?

Regarding getting started with WMI, you could try the following sections from Microsoft's site:

WMI Scripting Primer

Sesame Script

- MoChr(77)& Chr(97)& Chr(100)& Chr(101)& Chr(32)& Chr(121)& Chr(97)& Chr(32)& Chr(108)& Chr(111)& Chr(111)& Chr(107)-------I've told you 100,000 times not to exaggerate!-------Don't make me hit you with my cigarette hand...-------My scripts:Random Episode Selector, Keyboard MouseMover, CopyPath v2.1, SmartRename for XP,Window Tracer[sup]New![/sup]

Link to comment
Share on other sites

Just in case someone comes to this article looking for a solution, this is what worked for me:

I REALIZE THIS IS VBSCRIPT!!! ...but for scripts on our DCs, i have to write in .vbs (company policy) -- awful, i know =P

' Determine the time of the latest logged on user.
Function getCurrentLogonTime()
    strLogonTime = #1/1/1970#
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_LogonSession Where LogonType='2'")
    For Each objItem in colItems
        strDate = WMIDateStringToDate(objItem.StartTime)
        If strDate > strLogonTime Then
            strLogonTime = strDate
        End If
    Next
    
    getCurrentLogonTime = strLogonTime
    
    Set objWMIService = Nothing
    Set colItems = Nothing
End Function


' Convert WMI date to a valid date variable
Function WMIDateStringToDate(strDate)
  WMIDateStringToDate = CDate(Mid(strDate, 5, 2)  & "/" & _
    Mid(strDate, 7, 2)  & "/" & _
    Left(strDate, 4)    & " " & _
    Mid (strDate, 9, 2) & ":" & _
    Mid(strDate, 11, 2) & ":" & _
    Mid(strDate, 13, 2))
End Function

Edit: oops... forgot the dependency function.

Edited by thepip3r

My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Link to comment
Share on other sites

Since I'm too dumb to figure out StringRegExp here it is the long way lol

But this will only work for local users.

-Kenny

#Include <Date.au3>
#include <array.au3>
#include <Constants.au3>
$LocalUser = @UserName

Local $cmd = Run(@ComSpec & " /c NET USER " & $LocalUser, @SystemDir, @SW_HIDE, $STDOUT_CHILD)
Global $LogonTime
While 1
    $LogonTime = StdoutRead($cmd, True)
    If StringInStr($LogonTime, "The command completed successfully.") Then
  ExitLoop
 EndIf
Wend

$TimePos = StringInStr($LogonTime, "Last logon")
$TimePos = $TimePos + 10
$LogonTime = StringTrimLeft($LogonTime, $TimePos)

$TimePos = StringInStr($LogonTime, @CRLF)
$TimePos = StringLen($LogonTime) - $TimePos + 1
$LogonTime = StringTrimRight($LogonTime, $TimePos)

$LogonTime = StringStripWS($LogonTime, 4)
If StringLeft($LogonTime, 1) = " " Then $LogonTime = StringTrimLeft($LogonTime, 1)

$LogonTime = _DateTimeConvert($LogonTime, 1, "MM/DD/YYYY HH:MM", "YYYY/MM/DD HH:MM")
$LogonDuration = _DateDiff( 'n', $LogonTime, _NowCalc())
MsgBox(0, "Logon Time", "User logged on for: " & $LogonDuration & " Minutes")

 

;Start Custom Functions
Func _DateTimeConvert($sDateTime, $iConvertAmPm=0, $sDateTimeFormat="MM/DD/YYYY HH:MM:SS", $sRetFormat="YYYY/MM/DD HH:MM:SS")
    $sAM_PM = StringStripWS($sDateTime, 4)
 If StringRight($sAM_PM, 2) = "AM" OR StringRight($sAM_PM, 2) = "PM" AND StringMid($sAM_PM, StringLen($sAM_PM) - 2, 1) <> " " Then
  $sAM_PM = StringReplace($sAM_PM, "AM", " AM")
  $sAM_PM = StringReplace($sAM_PM, "PM", " PM")
 EndIf
 $sAM_PM = StringSplit($sAM_PM, "\d+|:|/ ")
 Local $sFormatArray = StringSplit($sDateTimeFormat, "\d+|:|/ ")
 
    $sMonPos = _ArraySearch($sFormatArray, "MM")
 $sDayPos = _ArraySearch($sFormatArray, "DD")
 $sYearPos = _ArraySearch($sFormatArray, "YYYY")
 $sHourPos = _ArraySearch($sFormatArray, "HH")
 $sMinPos = _ArraySearch($sFormatArray, "MM", -1, -1, -1, -1, 0)
 $sSecPos = _ArraySearch($sFormatArray, "SS")
 
 If StringLen($sAM_PM[$sMonPos]) = 1 Then $sAM_PM[$sMonPos] = "0" & $sAM_PM[$sMonPos]
 If StringLen($sAM_PM[$sDayPos]) = 1 Then $sAM_PM[$sDayPos] = "0" & $sAM_PM[$sDayPos]
 If StringLen($sAM_PM[$sYearPos]) = 2 Then $sAM_PM[$sYearPos] = "20" & $sAM_PM[$sYearPos]
 If StringLen($sAM_PM[$sHourPos]) = 1 Then $sAM_PM[$sHourPos] = "0" & $sAM_PM[$sHourPos]
 
 $sMonth  = $sAM_PM[$sMonPos]
 $sDay  = $sAM_PM[$sDayPos]
 $sYear   = $sAM_PM[$sYearPos]
 $sHour   = $sAM_PM[$sHourPos]
 $sMinute = $sAM_PM[$sMinPos]
 If $sSecPos <> -1 Then $sSecond = $sAM_PM[$sSecPos]
 
 If $iConvertAmPm = 1 AND $sAM_PM[$sAM_PM[0]] = "PM" Then
  If $sHour < 12 Then
   $sHour += 12
   If StringLen($sAM_PM[$sHourPos]) = 1 Then $sAM_PM[$sHourPos] = "0" & $sAM_PM[$sHourPos]
   $sRetAMPM = ""
  EndIf
 ElseIf $iConvertAmPm = 1 AND $sAM_PM[$sAM_PM[0]] = "AM" Then
  If $sHour = 12 Then $sHour = "00"
  If StringLen($sAM_PM[$sHourPos]) = 1 Then $sAM_PM[$sHourPos] = "0" & $sAM_PM[$sHourPos]
  $sRetAMPM = ""
 ElseIf $iConvertAmPm = 0 AND $sAM_PM[$sAM_PM[0]] = "AM" OR $sAM_PM[$sAM_PM[0]] = "PM" Then
  $sRetAMPM = $sAM_PM[$sAM_PM[0]]
 ElseIf $iConvertAmPm = 1 AND $sAM_PM[$sAM_PM[0]] <> "AM" AND $sAM_PM[$sAM_PM[0]] <> "PM" Then
  $sRetAMPM = ""
 EndIf
 
    If $sDayPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(D+)(^/|:|)", $sDay, 1)
    If $sMonPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(M+)(^/|:|)", $sMonth, 1)
    If $sYearPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(Y+)(^/|:|)", $sYear, 1)
    If $sHourPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(H+)[^/|:|]", $sHour, 1)
    If $sMinPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(M+)[^/|:|]", $sMinute, 1)
    If $sSecPos <> -1 Then $sRetFormat = StringRegExpReplace($sRetFormat, "(?i)(S+)[^/|:|]", $sSecond, 1)
    Return $sRetFormat & " " & $sRetAMPM
EndFunc
Edited by ken82m

 "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...