Tuesday, December 21, 2010

Configuring ICA / RDP session timeout values using WMI VB script

Many times you may want to use a script to configure a Windows Server RDP or the Citrix ICA timeout values.  Although these can be achieved using a Group Policy Object (GPO) if your computers are in an Active Directory domain, you may choose to use a script such as this to set the timeout values in certain situations.  For example, before the computers are joined to a domain, or on computers running Terminal Services or Citrix that are not managed by a GPO.


Here I share the VBS codes to achieve this.  There are 3 timeout values you can set:


  1. Active Session Timeout
  2. Idle Session Timeout
  3. Disconnected Session Timeout




Active Session Timeout - this value determines when to disconnect the session from the user, while the session is still alive on a server, even if the user is actively working on the session


Idle Session Timeout - this value determines when to disconnect the session from the user if the user does not perform any activities (via keyboard and mouse) on the session


Disconnected Session Timeout - this value determines when a disconnected session - a session that is running on a server but are not presented to a user - will be terminated on a server




The lines of code below are not optimized.  I just did a quick-and-dirty approach to achieve what I want to do.  You will need to modify it to make it do what you want to set.


The functions will also check if the GPO has enforced the values.  This means it will not be able to set the value if so.  There are no detail comments on what the functions are.


If you have suggestions to make this better please feel free to leave comments.


This script can be run using cscript.exe.



'This script supports Windows XP/Server2003/Vista/Server 2008 only.  Windows 2000 is not supported
'
'Your should run this script with the //b parameter for running in auto-admin script to suppress console output
'
'This script can be duplicated for step-outs if required and just change the values of the timeout
'


Option Explicit
Dim ICAActiveSessionTimeout,ICAIdleSessionTimeout,ICADisconnectedSessionTimeout
Dim RDPActiveSessionTimeout,RDPIdleSessionTimeout,RDPDisconnectedSessionTimeout
Dim strOSversion,iResult
Dim objWMI_TS,strComputer




'==========================================================
' MAIN BODY STARTS
'==========================================================
ICAActiveSessionTimeout = 0                                     ' A 0 means never timeout
ICAIdleSessionTimeout = 1800000                                            ' 30 mins in milliseconds
ICADisconnectedSessionTimeout = 28800000      ' 8 hours in milliseconds


RDPActiveSessionTimeout = 0                                    ' Never
RDPIdleSessionTimeout = 600000                                             ' 10 mins in milliseconds
RDPDisconnectedSessionTimeout = 900000                         ' 15 mins in milliseconds


strComputer = "."    ' if a computer name can be specified here if you have remote administrative rights to it




strOSVersion = OSVersion()
WScript.echo "OS Version is: " & strOSVersion


If strComp(strOSVersion,"6.0",1) > 0 Then
' If this is Windows Server Vista/Server 2008


  WScript.Echo "This is a Vista/WS2K8 or newer"
  Set objWMI_TS = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2\TerminalServices")
  iResult = ConfigureTSSessionWS2K8("ICA-tcp",ICAActiveSessionTimeout,ICAIdleSessionTimeout,ICADisconnectedSessionTimeout)
  iResult = ConfigureTSSessionWS2K8("RDP-Tcp",RDPActiveSessionTimeout,RDPIdleSessionTimeout,RDPDisconnectedSessionTimeout)
  iResult = ConfigureTSClientSettingWS2K8("RDP-Tcp")


Elseif strComp(strOSVersion,"5.2",1) >0 Then
' If this is XP/Server 2003


  WScript.Echo "This is an XP/Server 2003"
  Set objWMI_TS = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  iResult = ConfigureTSSession("ICA-tcp",ICAActiveSessionTimeout,ICAIdleSessionTimeout,ICADisconnectedSessionTimeout)
  iResult = ConfigureTSSession("RDP-Tcp",RDPActiveSessionTimeout,RDPIdleSessionTimeout,RDPDisconnectedSessionTimeout)


Else


  WScript.Echo "This operating system is not supported."
  WScript.Quit(0)


End If


WScript.Echo ""
WScript.Echo "Result of the action: "
DisplayTSSessionSetting


WScript.Quit(0)


'==========================================================
' MAIN BODY ENDS
'==========================================================






'-----------------------------------------------------
' FUNCTIONS AND SUBROUTINES
'-----------------------------------------------------


Function ConfigureTSClientSettingWS2K8(strTerminalName)
'
' This configures the Printer Mapping property
'
Dim colItems,objItem,errResult,objInstances,objInstance,iResult


  Set colItems = objWMI_TS.ExecQuery("Select * from Win32_TSClientSetting WHERE TerminalName='" & strTerminalName & "'")


  If NOT IsNull(colItems) Then
    For each objItem in colItems
      WScript.Echo ">Configuring Client Settings for " & objItem.TerminalName
      WScript.echo " Configuring Windows Printer Mapping"
      Wscript.Echo "  Current setting: " & objItem.WindowsPrinterMapping
      if objItem.PolicySourceWindowsPrinterMapping = 1 Then
        WScript.Echo "  Cannot change WindowsPrinterMapping because of enforced GPO"
      else
        iResult = objItem.SetClientProperty("WindowsPrinterMapping",1)
      End If
      objItem.Put_
      Wscript.Echo "  New setting: " & objItem.WindowsPrinterMapping
    Next
  End If


End Function






'-----------------------------------------------------
'
'This works on Windows Server 2008/Vista only
'
Function ConfigureTSSessionWS2K8(strTerminalName,ActiveSessionTimeout,IdleSessionTimeout,DisconnectedSessionTimeout)


Dim colItems,objItem,errResult


  Set colItems = objWMI_TS.ExecQuery("Select * from Win32_TSSessionSetting WHERE TerminalName='" & strTerminalName & "'")


  if NOT IsNull(colItems) Then
    For Each objItem in colItems
        WScript.echo ">Setting " & objItem.TerminalName


        If UCase(objItem.TerminalName) = UCase(strTerminalName) Then
           objItem.TimeLimitPolicy = 0
           objItem.put_


                   If objItem.PolicySourceActiveSessionLimit <> 1 Then
              errResult = objItem.TimeLimit("ActiveSessionLimit",ActiveSessionTimeout)
           Else
              WScript.Echo "Policy enforced.  Cannot set ActiveSessionLimit"
           End If


           If objItem.PolicySourceIdleSessionLimit <> 1 Then
              errResult = objItem.TimeLimit("IdleSessionLimit",IdleSessionTimeout)
           Else
              WScript.Echo "Policy enforced.  Cannot set IdleSessionLimit"
           End If


           If objItem.PolicySourceDisconnectedSessionLimit <> 1 Then
              errResult = objItem.TimeLimit("DisconnectedSessionLimit",DisconnectedSessionTimeout)
           Else
              WScript.Echo "Policy enforced.  Cannot set DisconnectedSessionLimit"
           End If


           objItem.refresh_
        End if
    Next
  End If


  ConfigureTSSessionWS2K8 = 0


End Function
'-----------------------------------------------------




'-----------------------------------------------------
'
'This function is for Windows XP/Server 2003 only
'
Function ConfigureTSSession(strTerminalName,ActiveSessionTimeout,IdleSessionTimeout,DisconnectedSessionTimeout)


Dim colItems,objItem,errResult


  On Error Resume Next


  Set colItems = objWMI_TS.ExecQuery("Select * from Win32_TSSessionSetting WHERE TerminalName='" & strTerminalName & "'")


  if NOT IsNull(colItems) Then
    For Each objItem in colItems
        WScript.echo ">Setting " & objItem.TerminalName


        If UCase(objItem.TerminalName) = UCase(strTerminalName) Then
           objItem.TimeLimitPolicy = 0
           objItem.put_


           errResult = objItem.TimeLimit("ActiveSessionLimit",ActiveSessionTimeout)
           errResult = objItem.TimeLimit("IdleSessionLimit",IdleSessionTimeout)
           errResult = objItem.TimeLimit("DisconnectedSessionLimit",DisconnectedSessionTimeout)
           objItem.refresh_
        End if
    Next
  End If


  ConfigureTSSession = 0


End Function


'-----------------------------------------------------


'-----------------------------------------------------
'
'Displays the session values
'
Sub DisplayTSSessionSetting


Dim objInstances,objInstance


  Set objInstances = objWMI_TS.InstancesOf("Win32_TSSessionSetting",48)


  For Each objInstance in objInstances
     WScript.Echo objInstance.getObjectText_
  Next
End Sub
'-----------------------------------------------------




'-----------------------------------------------------
'
'Query the OS version number
'
Function OSVersion()
Dim objOS
  OSVersion = 0
  On Error Resume Next


' Connect to WMI and obtain instances of Win32_OperatingSystem
  For Each objOS in GetObject("winmgmts:").InstancesOf ("Win32_OperatingSystem")


    OSVersion = objOS.Version


  Next


  if Err <> 0 Then
      WScript.Echo "ERROR in function OSVersion(): " & Err.Description
      Err.Clear
  End if
End Function
'-----------------------------------------------------

5 comments:

Unknown said...

thanks for this script.
Virus Stuxnet Code

Surya said...

Dear Bendera,

This is really a great script. Can i please get Powershell script for the same? I'm very much trying for this. can u pls help me?

thanks,
Surya

Mr. Bendera said...

Hi Surya, I'm happy that you find this useful. Unfortunately I do not any PowerShell experience yet. I will post some PS scripts when I do.

Praveen said...

Very useful one ..

DO we have script to pull out the value of idle timeout setting for all citrix servers in a farm ?

if yes coul you please leave ur comments to praveen2sas@gmail.com

Remeni said...

The script is good, thank you.