These are TS-specific VBScript procedures I have pulled from code I keep up; the page also includes any non-TS functions upon which the TS functions are dependent.
These procedures have all been tried at one time or another against a Windows 2000 Terminal Server, and against XP Professional if appropriate. They will probably all work against .NET server.
They have not been tested against NT 4 TSE nor in a Citrix environment. If run on NT4 TSE they might work if WMI and a recent (5.1+) versionof WSH have been installed. If you try it, let me know the effects.
Besides the functions, I also have some TS miniscript fragments that may be useful.
This chunk of VBScript can be used in logon scripts to record client name, username, and time of any successful TS/Remote Desktop logons.
Set Sh = CreateObject("WScript.Shell")
sys = Sh.ExpandEnvironmentStrings("%CLIENTNAME%")
User = CreateObject("WScript.Network").Username
Sh.LogEvent 4, "Logon by " & User & " from " & sys
Not sure where your TSWeb folder is? Run this to pop it open.
'Webclients.vbs
Set Sh = CreateObject("WScript.Shell")
sData = Sh.Regread( _
"HKLM\SOFTWARE\Microsoft\TS Web Clients\InstallDir")
WScript.Echo "Web Clients folder is", sData
Sh.Run "%COMSPEC% /c start " & sData & "\.", 0
The script below will kill off all active TS Sessions. Use judiciously; it will NOT impress your boss to lose 2 hours of unsaved work on a presentation because you forced everyone out with this on a Sunday night.
' 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
NOTE: For "bulk" changes on a LAN, the best approach in an XP environment is to use the Group Policy Settings available via GPEdit.msc. Remote Desktop, Remote Assistance, and a host of other features are accessible there. See Q306300 - How to Disable Remote Desktop by Using Group Policy for details.
Function ConsoleUser(sHost)
' Returns name of user logged on to console
' If no users are logged on, returns nothing
Dim WMI, Processes, Process, sUser, sDomain
Set WMI = GetObject("winmgmts://" & sHost)
Set Processes = WMI.InstancesOf("Win32_Process")
ConsoleUser = ""
For Each Process In Processes
If (Process.Caption = "explorer.exe") _
And (Process.SessionID = 0 ) Then
lRet = Process.GetOwner(sUser, sDomain)
If (Err = 0) And (lRet = 0) Then
ConsoleUser = sUser
End If
End If
Next
End Function
Function LoggedOnUsers(sHost)
' Returns array containing all users logged in to
' interactive explorer-based sessions on sHost
' This WILL NOT WORK with applications as the shell!
Dim WMI, Processes, Process, sUser, sDomain, aTmp()
Set WMI = GetObject("winmgmts://" & sHost)
Set Processes = WMI.InstancesOf("Win32_Process")
ReDim aTmp(-1)
For Each Process In Processes
If (Process.Caption = "explorer.exe") Then
lRet = Process.GetOwner(sUser, sDomain)
If (Err = 0) And (lRet = 0) Then
ReDim aTmp(UBound(aTmp)+1)
aTmp(UBound(aTmp)) = sUser
End If
End If
Next
LoggedOnUsers = aTmp
End Function
Function IsTSSession
' Returns true if this is a non-console TS/RD session
Dim Sh, x
Set Sh = WScript.CreateObject("WScript.Shell")
x = LCase(Sh.ExpandEnvironmentStrings("%Clientname%"))
If (x <> "") And (x <> "console") Then
IsTSSession = True
Else
IsTSSession = False
End If
End Function
Function IsTS
' Returns true if this system is a TS/RD host
Dim Sh, x
Set Sh = WScript.CreateObject("WScript.Shell")
x = LCase(Sh.ExpandEnvironmentStrings("%Clientname%"))
If (x <> "") Then
IsTS = True
Else
IsTS = False
End If
End Function
Sub LogoffDisconnectedSessions
' Logs off disconnected sessions on a terminal server
' DEPENDENCIES: Cmd function
sData = Cmd("query session")
Lines = Split(sData, vbCrLf)
For Each Line In Lines
'WScript.Echo InStr(Line,"Disc "), vbCrLf, Line
If CBool(InStr(Line,"Disc ")) Then
SessionId = Trim(Mid(Line,42,6))
CreateObject("WScript.Shell").Run "logoff " & SessionId
End If
Next
End Sub
Function RAssistEnabled
' True if Remote Assistance enabled
Dim Sh, sKey, sValueName, sValue
Set Sh = CreateObject("WScript.Shell")
sKey = "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\"
sValueName = "fAllowToGetHelp"
sValue = Sh.RegRead(sKey & sValueName)
RAssistEnabled = CBool(sValue)
End Function
Function RDeskEnabled
' True if Remote Desktop enabled
Dim Sh, sKey, sValueName, sValue
Set Sh = CreateObject("WScript.Shell")
sKey = "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\"
sValueName = "fDenyTSConnections"
sValue = Sh.RegRead(SKey & sValueName)
RDeskEnabled = CBool(sValue)
End Function
Function RDeskAdvertised
' True if Remote Desktop is "advertising"
Dim Sh, sKey, sValueName, sValue
Set Sh = CreateObject("WScript.Shell")
sKey = "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\"
sValueName = "TSAdvertise"
sValue = Sh.RegRead(SKey & sValueName)
RdAdvertisedStatus = CBool(sValue)
End Function
Function RdpPort
' Returns current RDP port
Dim Sh, sKey, sValueName, sValue
Set Sh = CreateObject("WScript.Shell")
sKey = "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\" _
& "WinStations\RDP-Tcp\"
sValueName = "PortNumber"
sValue = Sh.RegRead(SKey & sValueName)
RdpPort = sValue
End Function
Function Set_RdAdvertised(bStatus)
' Sets Remote Desktop advertising
' Returns a value of TRUE if status changed successfully
Dim Sh, sKey, sValueName, sValue
Set Sh = CreateObject("WScript.Shell")
sKey = "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\"
sValueName = "TSAdvertise"
Set_RdAdvertisedStatus = FALSE
On Error Resume Next
Sh.RegWrite SKey & sValueName, Abs(bStatus)
If Err.Number = 0 Then Set_RdAdvertisedStatus = TRUE
On Error Goto 0
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