[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

VB script to kill active and disconnected terminal server sessions

Posted on 2004-10-26
7
Medium Priority
?
10,214 Views
Last Modified: 2010-08-05
I found the following VB script to kill active and disconnected terminal server sessions on the web, but I'm having difficulty getting it to work.  Since it doesn't provide any output, I don't know why it isn't working.  Can anyone suggest some lines of code to add to allow for stdout to be displayed as it steps through the script?  Is their any obvious problem withthe script?  I'm trying to use it in a Win2k3 terminal services environment.  TIA.

______________________________________________________________________________________________
' KillTsSessions.vbs
' Finds all active TS sessions on server HOST defined
' below and terminates them.  Does not terminate the
' current session if being run remotely.
' If running on local host, set HOST value to ""

HOST = ""


' Get disconnected sessions and log them off
sessions = DisconnectedSessions(HOST)

For each session in sessions
 TerminateWinSession HOST, sessionId
Next

' Now get active sessions and log them off
sessions = ActiveSessions(HOST)

For each session in sessions
 TerminateWinSession HOST, sessionId
Next

Sub TerminateWinSession(Host, sessionId)
 Dim Sh, tmpHost
 Set Sh = createobject("WScript.Shell")
 if trim(Host)="" Then
  tmpHost = ""
 Else
  tmpHost = " /SERVER:" & Host
 End If
 Sh.Run "%COMSPEC% /C rwinsta " & sessionId & tmpHost, 0, False
End Sub

Function ActiveSessions(Host)
 Dim tmpHost, aTmp, aTmp1(), i
 if trim(Host)="" Then
  tmpHost = ""
 Else
  tmpHost = " /SERVER:" & Host
 End If
 aTmp = Split(cmd("qwinsta" & tmpHost & " | find ""Active"""), _
  vbCrLf)
 ReDim aTmp1(-1)
 For i = 0 to UBound(aTmp)
  If Left(aTmp(i),1) <> ">" Then
   Redim Preserve aTmp1(UBound(aTmp1) + 1)
   aTmp1(UBound(aTmp1)) = Trim(Mid(aTmp(i), 42, 6))
  End If
 Next
 ActiveSessions = aTmp1
End Function


Function DisconnectedSessions(Host)
 Dim tmpHost, aTmp, aTmp1(), i
 if trim(Host)="" Then
  tmpHost = ""
 Else
  tmpHost = " /SERVER:" & Host
 End If
 aTmp = Split(cmd("qwinsta" & tmpHost & " | find ""Disconnected"""), _
  vbCrLf)
 ReDim aTmp1(-1)
 For i = 0 to UBound(aTmp)
  If Left(aTmp(i),1) <> ">" Then
   Redim Preserve aTmp1(UBound(aTmp1) + 1)
   aTmp1(UBound(aTmp1)) = Trim(Mid(aTmp(i), 42, 6))
  End If
 Next
 DisconnectedSessions = aTmp1
End Function


Function Cmd(cmdline)
 ' Wrapper for getting StdOut from a console command
 Dim Sh, FSO, fOut, OutF, sCmd
 Set Sh = createobject("WScript.Shell")
 Set FSO = createobject("Scripting.FileSystemObject")
 fOut = FSO.GetTempName
 sCmd = "%COMSPEC% /c " & cmdline & " >" & fOut
 Sh.Run sCmd, 0, True
 If FSO.FileExists(fOut) Then
  If FSO.GetFile(fOut).Size>0 Then
   Set OutF = FSO.OpenTextFile(fOut)
   Cmd = OutF.Readall
   OutF.Close
  End If
  FSO.DeleteFile(fOut)
 End If
End Function
__________________________________________________________________________________
0
Comment
Question by:thaller
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 

Accepted Solution

by:
andrewfHMS earned 500 total points
ID: 12418229
Hi I took some time and added some error handling and which writes to errorlog.txt in the same directory.

' KillTsSessions.vbs
' Finds all active TS sessions on server HOST defined
' below and terminates them.  Does not terminate the
' current session if being run remotely.
' If running on local host, set HOST value to ""

'// Added to Create and Open a file to write to
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objOutputFile = objFSO.CreateTextFile(".\ErrorLog.txt", True)

HOST = ""
' Get disconnected sessions and log them off
sessions = DisconnectedSessions(HOST)
For each session in sessions
      TerminateWinSession HOST, sessionId
Next

' Now get active sessions and log them off
sessions = ActiveSessions(HOST)

For each session in sessions
      TerminateWinSession HOST, sessionId
Next
objOutputFile.WriteLine("Done.")
objOutputFile.Close
WScript.Quit(0)

Sub TerminateWinSession(Host, sessionId)
       Dim Sh, tmpHost
       Set Sh = createobject("WScript.Shell")
       If trim(Host)="" Then
              tmpHost = ""
       Else
              tmpHost = " /SERVER:" & Host
       End If
       objOutputFile.WriteLine("Executing... " & vbCrLf & "%COMSPEC% /C rwinsta " & sessionId & tmpHost & vbCrLf)
      Err.Clear
       Sh.Run "%COMSPEC% /C rwinsta " & sessionId & tmpHost, 0, False
       If Err <> 0 Then
             objOutputFile.WriteLine("Error: " & Err.Number & " " & Err.Description)
       End If
End Sub

Function ActiveSessions(Host)
      Dim tmpHost, aTmp, aTmp1(), i
      If trim(Host)="" Then
            tmpHost = ""
       Else
              tmpHost = " /SERVER:" & Host
      End If
      aTmp = Split(cmd("qwinsta" & tmpHost & " | find ""Active"""), vbCrLf)
      ReDim aTmp1(-1)
       For i = 0 to UBound(aTmp)
              If Left(aTmp(i),1) <> ">" Then
                     Redim Preserve aTmp1(UBound(aTmp1) + 1)
                     aTmp1(UBound(aTmp1)) = Trim(Mid(aTmp(i), 42, 6))
              End If
       Next
      ActiveSessions = aTmp1
End Function


Function DisconnectedSessions(Host)
      Dim tmpHost, aTmp, aTmp1(), i
      If trim(Host)="" Then
              tmpHost = ""
       Else
              tmpHost = " /SERVER:" & Host
       End If
       aTmp = Split(cmd("qwinsta" & tmpHost & " | find ""Disconnected"""),vbCrLf)
       ReDim aTmp1(-1)
       For i = 0 to UBound(aTmp)
              If Left(aTmp(i),1) <> ">" Then
                    Redim Preserve aTmp1(UBound(aTmp1) + 1)
                     aTmp1(UBound(aTmp1)) = Trim(Mid(aTmp(i), 42, 6))
              End If
        Next
      DisconnectedSessions = aTmp1
End Function


Function Cmd(cmdline)
 ' Wrapper for getting StdOut from a console command
      Dim Sh, FSO, fOut, OutF, sCmd
      Set Sh = createobject("WScript.Shell")
      fOut = objFSO.GetTempName
      sCmd = "%COMSPEC% /c " & cmdline & " >" & fOut
      objOutputFile.WriteLine("Executing... " & vbCrLf & sCmd & vbCrLf)
      Err.Clear
      Sh.Run sCmd, 0, True
      If Err <> 0 Then
             objOutputFile.WriteLine("Error: " & Err.Number & " " & Err.Description)
       End If
       If objFSO.FileExists(fOut) Then
            If objFSO.GetFile(fOut).Size>0 Then
                  Set OutF = objFSO.OpenTextFile(fOut)
                  Cmd = OutF.Readall
                  objOutputFile.Write(Cmd & vbCrLf)
                  OutF.Close
            End If
              objFSO.DeleteFile(fOut)
       End If
End Function
0
 
LVL 3

Author Comment

by:thaller
ID: 12420924
Thanks, Andrew...I'll try it out.
0
 
LVL 3

Author Comment

by:thaller
ID: 12421326
Thanks for the time you took....it did do exactly what you said it would.  I still need to work on why the script itself fails but you did exactly what I asked for.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 3

Author Comment

by:thaller
ID: 12421445
Andrew,
Again, thanks for the help...I think I've found the problem and I'm hoping you can help out.  The 'rwinsta' command called to kill the sessions will ask the following question upon execution:

If you reset this session, all users using this protocol will be logged off,
continue (n=no)?

How would I echo y to answer the question in the script?
0
 

Expert Comment

by:andrewfHMS
ID: 12423811
Thaller,
Unfortunatley I do not have any server running terminal services were I am currently at so I havent been able to fully test the following....
But try changing line 38 to
Sh.Run "%COMSPEC% /C rwinsta " & sessionId & tmpHost, 1, True

That would change the command to be run in a window ( 1)  and the script will not continue the next line of code till the command is finished running (True)

To automate it further you could also add code for sendkeys, to send a y to the open console.  That would look like this...

Sub TerminateWinSession(Host, sessionId)
       Dim Sh, tmpHost
       Set Sh = createobject("WScript.Shell")
       If trim(Host)="" Then
              tmpHost = ""
       Else
              tmpHost = " /SERVER:" & Host
       End If
       objOutputFile.WriteLine("Executing... " & vbCrLf & "%COMSPEC% /C rwinsta " & sessionId & tmpHost & vbCrLf)
      Err.Clear
       Sh.Run "%COMSPEC% /C rwinsta " & sessionId & tmpHost, 1, True
       If Err <> 0 Then
             objOutputFile.WriteLine("Error: " & Err.Number & " " & Err.Description)
       Else
                       Sh.AppActivate "Cmd.exe"
             Sh.Sleep 100
             Sh.SendKeys "Y"
             Sh.Sleep 500
             Sh.SendKeys "~"
       End If
End Sub

0
 
LVL 3

Author Comment

by:thaller
ID: 12424328
I really do appreciate the help.  Id like to throw some more points your way; how would I do that?

When I change line 38 to the following:

Sh.Run "%COMSPEC% /K rwinsta " & sessionId & tmpHost, 1, True

I get the following output:

Invalid parameter(s)
Reset the session subsytem hardware and software to known initial values.

RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]

  sessionname         Identifies the session with name sessionname.
  sessionid           Identifies the session with ID sessionid.
  /SERVER:servername  The server containing the session (default is current).
  /V                  Display additional information.

which leads me to believe there is a problem with how sessioId gets it's value.  The output of the "qwinsta" command from the functions ActiveSessions and DisconnectedSessions is the following:

>console           administrator             0  Active  wdcon              
  rdp-tcp#5        bethy                        1  Active  rdpwd

where the number preceeding "Active" is the sessionId.  It looks like there is a problem with how the functions ActiveSessions and DisconnectedSessions assign sessionId.  Any thoughts?
0
 

Expert Comment

by:Toky76
ID: 22250314
Greetings,
I am editing this script right now to kill all disconneted sessions except one for specific user. Can anybody help me with that? I dont know where to add a condition to skip session if the user is for example User1.
Please, help!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

650 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