[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 10373
  • Last Modified:

VB script to kill active and disconnected terminal server sessions

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
thaller
Asked:
thaller
  • 4
  • 2
1 Solution
 
andrewfHMSCommented:
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
 
thallerAuthor Commented:
Thanks, Andrew...I'll try it out.
0
 
thallerAuthor Commented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
thallerAuthor Commented:
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
 
andrewfHMSCommented:
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
 
thallerAuthor Commented:
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
 
Toky76Commented:
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

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now