Link to home
Start Free TrialLog in
Avatar of robrandon
robrandon

asked on

Command for Session Time

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.
Avatar of Longbow
Longbow

Some Experts have already done the job for you.
You will find the answer in the next thread.
https://www.experts-exchange.com/questions/20816048/Login-script-to-track-users-date-time-login-logout.html

And what when the session is locked out ?
Avatar of robrandon

ASKER

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.

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

right...I mentioned that I was not sure if psinfo would give you the uptime or the session info.  Did you try it?
Nah, didn't bother to try it.  I checked out the details on their website.  Any other ideas?

Thanks, btw.
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.
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.



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
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
ASKER CERTIFIED SOLUTION
Avatar of dlwyatt82
dlwyatt82
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think I can modify that script enough to get it to do what I want.  Thanks for all the help.
-r