Sign in to follow this  
Followers 0
thepip3r

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

7 posts in this topic

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

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

@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

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

@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.

Share this post


Link to post
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

Share this post


Link to post
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]

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

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

My Contributions _StringMultiReplace PC Builders Console - Secure PDF Creator - Cisco VPN Installer MS DNS Server Backup Script - MS DHCP Backup Script IT Admin Console - Toggle Admin Mode - MyMovies-Add Discs Script - IT Help Desk and System Information Tool - Set On Lid Close Power Option - Streaming Media Server & Website "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."

Share this post


Link to post
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
Sign in to follow this  
Followers 0