Link to home
Start Free TrialLog in
Avatar of thaller
thaller

asked on

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
__________________________________________________________________________________
ASKER CERTIFIED SOLUTION
Avatar of andrewfHMS
andrewfHMS

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
Avatar of thaller
thaller

ASKER

Thanks, Andrew...I'll try it out.
Avatar of thaller

ASKER

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

ASKER

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

Avatar of thaller

ASKER

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?
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!