Solved

Command for Session Time

Posted on 2004-09-23
12
136 Views
Last Modified: 2010-04-14
Is there a DOS command that would show how long your session has been active, i.e. how long since you have logged on?  My intention is to use this in a logoff script on a Terminal Server to track how long people use it.

Thanks.
0
Comment
Question by:robrandon
  • 5
  • 4
  • 2
  • +1
12 Comments
 
LVL 10

Expert Comment

by:Longbow
Comment Utility
Some Experts have already done the job for you.
You will find the answer in the next thread.
http://www.experts-exchange.com/Operating_Systems/WinXP/Q_20816048.html

And what when the session is locked out ?
0
 
LVL 16

Author Comment

by:robrandon
Comment Utility
That solution seems more like a log that will have the logon and logoff times.  I'm looking for the total session time.  Unless you know how to calculate it from that info.  I tried the initial script in the post and it didn't return the information I was looking for.  It showed how long my session was for a server I was connected to.  But thanks.  I'm going to see if I can find a way to do it with WMI.

0
 
LVL 17

Expert Comment

by:Jared Luker
Comment Utility
Get PSINFO

http://www.sysinternals.com/ntw2k/freeware/psinfo.shtml

in your shutdown script, you can run:

psinfo | find "Uptime" > logfile.txt

Or something to that effect.  It will report a time.  I'm not sure if it would report the session time, or the uptime of the server your users are remoting into.

Results:
Uptime:                    0 days 2 hours 15 minutes 28 seconds

Jared
0
 
LVL 16

Author Comment

by:robrandon
Comment Utility
I'm not looking for the uptime.  I'm looking for the session time.  The time that a user has been logged on for.  So if the computer boots up on Monday, and a user logs in on Tuesday, and then they ran it on on Thursday, it would show something like 48 hours.

0
 
LVL 17

Expert Comment

by:Jared Luker
Comment Utility
right...I mentioned that I was not sure if psinfo would give you the uptime or the session info.  Did you try it?
0
 
LVL 16

Author Comment

by:robrandon
Comment Utility
Nah, didn't bother to try it.  I checked out the details on their website.  Any other ideas?

Thanks, btw.
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 14

Expert Comment

by:dlwyatt82
Comment Utility
Another of the utilities in the PSTools suite can help you accomplish this, though - psloggedon. It will display all of the logged-on user accounts, along with the time they connected. It is a fairly straightforward task to write a script which parses this output and converts it to a "total logged on tmie" report that you are after.
0
 
LVL 16

Author Comment

by:robrandon
Comment Utility
Thanks dlwyatt82,
I was hoping there was a utility that would give the time for me so I don't have to write the script.  It looks like I'll have to go back to my original plan of doing so.



0
 
LVL 14

Expert Comment

by:dlwyatt82
Comment Utility
I was bored this morning :) Copied some bits and pieces of my other vbscripts to make a scrpt that does what you want. Just copy this into a text file, name it whatever.vbs, put psloggedon in the same folder (or on your search path), and run "cscript whatever.vbs ComputerName".

***************************************************

' Script main section start
  Dim strComputerName

  ' Get parameter
  If (WScript.Arguments.Count < 1) Then
    Dim WshNetwork
    Set WshNetwork = WScript.CreateObject("WScript.Network")
    strComputerName = WshNetwork.ComputerName
    Set WshNetwork = Nothing
  Else
    strComputerName = WScript.Arguments.Item(0)
  End If

  Dim WshShell  
  Set WshShell = CreateObject("WScript.Shell")
 
  Dim objProcess  
  Set objProcess = WshShell.Exec("psloggedon.exe \\" & strComputerName)
 
  Do While (objProcess.Status = 0)
    Call WScript.Sleep(100)
  Loop
 
  Dim strLine
 
  Const cParseStart = 1 ' information prior to user list
  Const cParseLocal = 2 ' list of users logged on locally or via TS
  Const cParseShare = 3 ' list of users connected via shared drives
 
  Const cLocalStartLine = "Users logged on locally:"
  Const cShareStartLine = "Users logged on via resource shares:"
 
  Dim nParseStatus
  nParseStatus = cParseStart
   
  Do While (Not objProcess.StdOut.AtEndOfStream)
    strLine = TrimWhiteSpace(objProcess.StdOut.ReadLine)
    Select Case nParseStatus
      Case cParseStart
        If (Right(strLine, Len(cLocalStartLine)) = cLocalStartLine) Then
          Call WScript.Echo("Users logged on locally:")
          nParseStatus = cParseLocal
        End If
      Case cParseLocal
        If (Left(strLine, Len(cShareStartLine)) = cShareStartLine) Then
          Call WScript.Echo("Users logged on via resource shares:")
          nParseStatus = cParseShare
        ElseIf (strLine <> "") Then
          ProcessDataLine(strLine)
        End If
      Case cParseShare
        If (strLine <> "") Then
          ProcessDataLine(strLine)
        End If
      Case Else
        ' If you got here, put the beer down immediately.
    End Select
  Loop

' Script main execution complete

Function IntervalStr(dtStart, dtEnd)
  Dim nDays, nHours, nMinutes, nSeconds, strInterval, strSeparator
 
  nDays = DateDiff("d", dtStart, dtEnd)
  nHours = DateDiff("h", dtStart, dtEnd) Mod 24
  nMinutes = DateDiff("n", dtStart, dtEnd) Mod 60
  nSeconds = DateDiff("s", dtStart, dtEnd) Mod 60
 
  strInterval = ""
  strSeparator = ""
 
  If (nDays > 0) Then
    strInterval = strInterval & strSeparator & nDays & " " & PluralStr("Day", nDays)
    strSeparator = ", "
  End If
 
  If (nHours > 0 Or strSeparator <> "") Then
    strInterval = strInterval & strSeparator & nHours & " " & PluralStr("Hour", nHours)
    strSeparator = ", "
  End If
 
  If (nMinutes > 0 Or strSeparator <> "") Then
    strInterval = strInterval & strSeparator & nMinutes & " " & PluralStr("Minute", nMinutes)
    strSeparator = ", "
  End If
 
  If (nSeconds > 0 Or strSeparator <> "") Then
    strInterval = strInterval & strSeparator & nSeconds & " " & PluralStr("Second", nSeconds)
    strSeparator = ", "
  End If
 
  IntervalStr = strInterval
End Function

Function PluralStrEx(ByVal strName, ByVal nAmount, ByVal strFooter)
  nAmount = CInt(nAmount)
  strName = CStr(strName)
  strFooter = CStr(strFooter)
 
  If (IsEmpty(strName) Or IsNull(StrName)) Then strName = ""
  If (IsEmpty(strFooter) Or IsNull(StrFooter)) Then strFooter = ""
 
  PluralStrEx = strName
  If (nAmount <> 1) Then PluralStrEx = PluralStrEx & strFooter
End Function

Function PluralStr(ByVal strName, ByVal nAmount)
  PluralStr = PluralStrEx(strName, nAmount, "s")
End Function

Function GetDate(strDate, strTime, strAMPM)
  Dim arrTimeSplit
 
  arrTimeSplit = Split(strTime, ":")
 
  Select Case arrTimeSplit(0)
  Case "12"
    If (UCase(strAMPM) = "AM") Then arrTimeSplit(0) = "0"
  Case Else
    If (UCase(strAMPM) = "PM") Then arrTimeSplit(0) = CStr(Eval(arrTimeSplit(0) & "+ 12"))
  End Select
 
  If (UBound(arrTimeSplit) < 2) Then
    Call WScript.Echo("ERROR in GetDate. strDate = " & strDate & ", strTime = " & strTime & ", strAMPM = " & strAMPM)
    GetDate = Now
  Else
    strTime = arrTimeSplit(0) & ":" & arrTimeSplit(1) & ":" & arrTimeSplit(2)
    GetDate = CDate(strDate & " " & strTime)
  End If
 
End Function

Function RegExGetFirstMatch(strString, strPattern, bIgnoreCase)
  RegExGetFirstMatch = ""
 
  Dim objRegExp
  Set objRegExp = New RegExp
 
  objRegExp.Global = False
  objRegExp.IgnoreCase = bIgnoreCase
  objRegExp.Pattern = strPattern
 
  Dim colMatches
  Set colMatches = objRegExp.Execute(strString)
 
  For Each objMatch in colMatches
    RegExGetFirstMatch = objMatch.Value
  Next
 
  Set objRegExp = Nothing
End Function

Function TrimWhiteSpace(ByVal str)
  Dim objRegExp
 
  Set objRegExp = New RegExp
  objRegExp.Pattern = "^\s+|\s+$"
  objRegExp.IgnoreCase = True
  objRegExp.Global = True
  TrimWhiteSpace = objRegExp.Replace(str, "")
  Set objRegExp = Nothing
End Function

Function ProcessDataLine(ByVal strLine)
  Dim strDate, strTime, strAMPM, strUser
  Dim dtTime, dtNow
 
  dtNow = Now

  strDate = RegExGetFirstMatch(strLine, "^\b[0-9/]+\b", True)
  strTime = RegExGetFirstMatch(strLine, "\b[0-9:]{5,}\b", True)
  strAMPM = RegExGetFirstMatch(strLine, "\b(A|P)M\b", True)
  strUser = RegExGetFirstMatch(strLine, "\b\S+$", True)
 
  If (strDate <> "" And strTime <> "" And strAMPM <> "" And strUser <> "") Then
    dtTime = GetDate(strDate, strTime, strAMPM)
    Call WScript.Echo(PackStr("  " & strUser & " - ", 25) & IntervalStr(dtTime, dtNow))
  End If
End Function

Function PackStr(ByVal strString, ByVal nWidth)
  PackStr = PackString(strString, nWidth, True, False)
End Function

Function PackString(ByVal strString, ByVal nWidth, ByVal bAfter, ByVal bTruncate)
  On Error Resume Next

  nWidth      = CInt(nWidth)
  bAfter      = CBool(bAfter)
  bTruncate   = CBool(bTruncate)
 
  If (Err.Number) Then
    Wscript.Echo ("Argument type is incorrect!")
    Err.Clear
    WScript.Quit
  End If
 
  If (IsNull(strString)) Then
    PackString = Space(nWidth)
    Exit Function
  End If
 
  strString = CStr(strString)
  If (Err.Number) Then
    Wscript.Echo ("Argument type is incorrect!")
    Err.Clear
    WScript.Quit
  End If
 
  If (nWidth > Len(strString)) Then
    If (bAfter) Then
      PackString = strString & Space(nWidth-Len(strString))
    Else
      PackString = Space(nWidth-Len(strString)) & strString & " "
    End If
  Else
    If (bTruncate) Then
      PackString = Left(strString, nWidth-1) & " "
    Else
      PackString = strString & " "
    End If
  End If
End Function

Sub VerifyHostIsCscript()
  On Error Resume Next
 
  Dim strFullName, strCommand, i, j, bIsCScript
 
  strFullName = WScript.FullName
 
  If (Err.Number) Then
    WScript.Echo( "Error 0x" & CStr(Hex(Err.Number)) & " occurred." )
    If (Err.Description <> "") Then
      WScript.Echo( "Error description: " & Err.Description & "." )
    End If
    bIsCScript = False
  End If
 
  i = InStr(1, strFullName, ".exe", 1)
  If (i = 0) Then
      bIsCScript = False
  Else
    j = InStrRev(strFullName, "\", i, 1)
    If (j = 0) Then
      bIsCScript = False
    Else
      strCommand = Mid(strFullName, j+1, i-j-1)
      Select Case LCase(strCommand)
        Case "cscript"
          bIsCScript = True
        Case "wscript"
          bIsCScript = False
        Case Else       'should never happen
          WScript.Echo( "An unexpected program was used to " _
                        & "run this script." )
          WScript.Echo( "Only CScript.Exe or WScript.Exe can " _
                        & "be used to run this script." )
          bIsCScript = False
      End Select
    End If
  End If
 
  If (bIsCScript = False) Then
    WScript.Echo("Please run this script using CScript." & vbCRLF & _
                 "This can be achieved by" & vbCRLF & _
                 "1. Using ""CScript SystemInfo.vbs arguments"" for Windows 95/98 or" _
                 & vbCRLF & "2. Changing the default Windows Scripting Host " _
                 & "setting to CScript" & vbCRLF & "    using ""CScript " _
                 & "//H:CScript //S"" and running the script using" & vbCRLF & _
                 "    ""SystemInfo.vbs arguments"" for Windows NT/2000." )
    WScript.Quit
  End If
End Sub
0
 
LVL 14

Expert Comment

by:dlwyatt82
Comment Utility
Forgot to mention, make sure you update your Windows Script runtime to the latest version. You need 5.6 to support WshShell.Exec.

http://www.microsoft.com/downloads/details.aspx?FamilyID=c717d943-7e4b-4622-86eb-95a22b832caa&DisplayLang=en
0
 
LVL 14

Accepted Solution

by:
dlwyatt82 earned 125 total points
Comment Utility
Also, I posted this script without rereading the original post... the way it's written, it will display the session times of all users on a particular machine (local or remote), not just the user running the script. It's pretty easy to modify the script to ignore other users (use WshNetwork.UserDomain and WshNetwork.UserName to get the logon information of the current user, and compare that to the strUser variable in the ProcessDataLine function).

Can also just break out of the Do While loop when you get to the "users logged on via resource shares" line if you don't care about that information.
0
 
LVL 16

Author Comment

by:robrandon
Comment Utility
I think I can modify that script enough to get it to do what I want.  Thanks for all the help.
-r
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

NTFS file system has been developed by Microsoft that is widely used by Windows NT operating system and its advanced versions. It is the mostly used over FAT file system as it provides superior features like reliability, security, storage, efficienc…
In this article, you will read about the trends across the human resources departments for the upcoming year. Some of them include improving employee experience, adopting new technologies, using HR software to its full extent, and integrating artifi…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now