View TS/RDS Configuration Remotely

Here is a VBScript which can be used to get the following information from a W2K, W2K3, W2K8 or W2K8R2 server via WMI:
- is Remote Desktop enabled?
- is Terminal Services / Remote Desktop Services configured for Application Server or Remote Administration?
- what TS/RDS license servers have been defined?
- what TS license servers have been discovered? (no longer applies after W2K8)

Please forgive the appearance if the blog layout wraps the lines, and hopefully HTML encoding won’t make a mess of the code – the script has only had basic testing so let me know if there’s any mistakes in it.

The reasons for the complexity of the script:
- the registry location of the information changes between versions of Windows
- settings can be defined locally or via group policy, the latter taking precedence
- LS checks are done only if the server is in Application Server mode
- “discovered” LS servers are only sought if the NT version is 5.0, 5.2 or 6.0

It has been designed to query just one server at a time and output a readable summary of what it finds – it would be trivial to call the script repeatedly with a different server name to build an inventory and pipe the information where you desire.

'-------------------------------------------------------------------------------
' THIS SCRIPT IS PROVIDED "AS-IS" AND DOES NOT COME WITH SUPPORT FROM MICROSOFT
'
' CheckTS.vbs
'
' Syntax:
' CSCRIPT /NoLogo CheckTS.vbs [/S:servername]
'
' Example:
' CSCRIPT /NoLogo CheckTS.vbs /S:FOO > FOO.TXT
' (Reports on remote server "FOO" and pipe the output to FOO.TXT)
'
' If no server name is specified, localhost is used
'-------------------------------------------------------------------------------
Option Explicit

Const HKEY_LOCAL_MACHINE = &H80000002

Dim strComputer, strKey, strValue, strOutput
Dim objReg

If WScript.Arguments.Named.Exists("S") Then
strComputer=UCase(WScript.Arguments.Named.Item("S"))
Else
strComputer = "localhost"
End If

On Error Resume Next
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
If Err.Number <> 0 Then
' Gracefully handle a failure to connect to the remote machine
WScript.Echo "There was a problem connecting to " & strComputer & vbCrLf &_
"Error " & Err.Number & " " & Err.Description
WScript.Quit
End If
On Error Goto 0

strOutput = "Checking server: " & strComputer & vbCrLf

'-------------------------------------------------------------------------------
' Retrieve the Windows version from the remote machine,
' as we need to know which registry keys we are to check
'-------------------------------------------------------
Dim strWindowsVersion

strValue = "CurrentVersion"
strKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
objReg.GetSTRINGValue HKEY_LOCAL_MACHINE,strKey,strValue,strWindowsVersion

strOutput = strOutput & "OS Version: " & strWindowsVersion
If strWindowsVersion = "5.0" Then
strOutput = strOutput & " (Windows 2000)"
End If
If strWindowsVersion = "5.2" Then
strOutput = strOutput & " (Windows Server 2003)"
End If
If strWindowsVersion = "6.0" Then
strOutput = strOutput & " (Windows Server 2008)"
End If
If strWindowsVersion = "6.1" Then
strOutput = strOutput & " (Windows Server 2008R2)"
End If
strOutput = strOutput & vbCrLf

'-------------------------------------------------------------------------------
' Is the server accepting Remote Desktop Connections?
' (fDenyTSConnections = 0)
'----------------------------------------------------
Dim iRDDisabledLOCAL, iRDDisabledPOLICY

strValue = "fDenyTSConnections"
strKey = "SYSTEM\CurrentControlSet\Control\Terminal Server"
iRDDisabledLOCAL = 1
If ExistsDWORD Then
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKey,strValue,iRDDisabledLOCAL
End If

strKey = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
iRdDisabledPOLICY = -1
If ExistsDWORD Then
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKey,strValue,iRDDisabledPOLICY
End If

If iRDDisabledPOLICY <> -1 Then
' Setting is defined in a policy
If iRDDisabledPOLICY = 1 Then
strOutput = strOutput & "Remote Desktop is DISABLED (via policy)" & vbCrLf
Else
strOutput = strOutput & "Remote Desktop is ENABLED (via policy)" & vbCrLf
End If
Else
' Setting is not defined in a policy (so local or default setting applies)
If iRDDisabledLOCAL = 1 Then
strOutput = strOutput & "Remote Desktop is DISABLED (locally)" & vbCrLf
Else
strOutput = strOutput & "Remote Desktop is ENABLED (locally)" & vbCrLf
End If
End If

'-------------------------------------------------------------------------------
' Is the server running in Application Server mode?
' (TSAppCompat = 1)
'--------------------------------------------------
Dim iTSAppCompat

strValue = "TSAppCompat"
strKey = "SYSTEM\CurrentControlSet\Control\Terminal Server"
iTSAppCompat = -1
If ExistsDWORD Then
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKey,strValue,iTSAppCompat
End If

If iTSAppCompat = 1 Then
strOutput = strOutput & "Terminal Services is in APPLICATION SERVER mode" & vbCrLf
Else
strOutput = strOutput & "Terminal Services is in REMOTE ADMINISTRATION mode" & vbCrLf
End If

'-------------------------------------------------------------------------------
' If the server is running in Application Server mode, check the licensing mode
' (LicensingMode = 2 for per-device, 4 for per-user)
'------------------------------------------------------------------------------
Dim iLicensingModeLOCAL, iLicensingModePOLICY

If iTSAppCompat = 1 Then
strValue = "LicensingMode"
strKey = "SYSTEM\CurrentControlSet\Control\Terminal Server"
If (strWindowsVersion = "6.0" Or strWindowsVersion = "6.1") Then
strKey = "SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\Licensing Core"
End If
If ExistsDWORD Then
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKey,strValue,iLicensingModeLOCAL
End If

  strKey = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
iLicensingModePOLICY = -1
If ExistsDWORD Then
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKey,strValue,iLicensingModePOLICY
End If

  If iLicensingModePOLICY <> -1 Then
' Setting is defined in a policy
If iLicensingModePOLICY = 2 Then
strOutput = strOutput & "Licensing Mode is configured as PER DEVICE (via policy)" & vbCrLf
ElseIf iLicensingModePOLICY = 4 Then
strOutput = strOutput & "Licensing Mode is configured as PER USER (via policy)" & vbCrLf
Else
strOutput = strOutput & "Licensing Mode is NOT RECOGNIZED (via policy) : " & iLicensingModePOLICY & vbCrLf
End If
Else
' Setting is not defined in a policy (so local or default setting applies)
If iLicensingModeLOCAL = 2 Then
strOutput = strOutput & "Licensing Mode is configured as PER DEVICE (locally)" & vbCrLf
ElseIf iLicensingModeLOCAL = 4 Then
strOutput = strOutput & "Licensing Mode is configured as PER USER (locally)" & vbCrLf
Else
strOutput = strOutput & "Licensing Mode is NOT RECOGNIZED (locally) : " & iLicensingModeLOCAL & vbCrLf
End If
End If
End If

'-------------------------------------------------------------------------------
' If the server is running in Application Server mode, check the LS list
' (LicenseServers = a comma-separated list of license servers)
'-----------------------------------------------------------------------
Dim strLicenseServers

If iTSAppCompat = 1 Then
strValue = "LicenseServers"
strKey = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"

  If ExistsSTRING Then
objReg.GetSTRINGValue HKEY_LOCAL_MACHINE,strKey,strValue,strLicenseServers
strOutput = strOutput & "License servers defined by policy: " & strLicenseServers & vbCrLf
End If

  Dim arrLSKeys

  strKey = "SYSTEM\CurrentControlSet\Services\TermService\Parameters\LicenseServers"
If objReg.EnumKey(HKEY_LOCAL_MACHINE,strKey,arrLSKeys) = 0 Then
' Key does not exist by default, so if we failed to open it then we skip this
If IsArray(arrLSKeys) Then
Dim i, strName

      strOutput = strOutput & "License servers defined locally: "
i = 0
For Each strName In arrLSKeys
If i > 0 Then
strOutput = strOutput & ","
End If
strOutput = strOutput & strName
i = i + 1
Next
strOutput = strOutput & " (" & i & ")" & vbCrLf
End If
End If

  If strWindowsVersion = "5.0" Or strWindowsVersion = "5.2" Or strWindowsVersion = "6.0" Then
' Discovery of License Servers is only available before W2K8R2
strKey = "SOFTWARE\Microsoft\MSLicensing\Parameters"
If strWindowsVersion = "6.0" Then
strKey = "SYSTEM\CurrentControlSet\Control\Terminal Server\RCM"
End If

    strValue = "DomainLicenseServerMulti"
If ExistsMULTISTRING Then
Dim arrLSNames, strList

      objReg.GetMULTISTRINGValue HKEY_LOCAL_MACHINE,strKey,strValue,arrLSNames
i = 0
For Each strName In arrLSNames
' Build the list of names separated with commas, ignoring null strings
If strName <> "" Then
If i > 0 Then
strList = strList & ","
End If
strList = strList & strName
i = i + 1
End If
Next
If i > 0 Then
strOutput = strOutput & "License servers discovered in DOMAIN/WORKGROUP role: " &_
strList & " (" & i & ")" & vbCrLf
End If
End If

    strValue = "EnterpriseServerMulti"
If ExistsMULTISTRING Then
objReg.GetMULTISTRINGValue HKEY_LOCAL_MACHINE,strKey,strValue,arrLSNames
i = 0
strList = ""
For Each strName In arrLSNames
' Build the list of names separated with commas, ignoring null strings
If strName <> "" Then
If i > 0 Then
strList = strList & ","
End If
strList = strList & strName
i = i + 1
End If
Next
If i > 0 Then
strOutput = strOutput & "License servers discovered in ENTERPRISE role: " &_
strList & " (" & i & ")" & vbCrLf
End If
End If
End If
End If

'-------------------------------------------------------------------------------
' Output the results to STDOUT (can be piped to a file)
'------------------------------------------------------

WScript.Echo strOutput
WScript.Quit

'===============================================================================
' FUNCTIONS
' As some registry values/keys are optional, these functions allow us to only
' bother trying to read their contents if we have verified they exist...
'===============================================================================

Function ExistsDWORD
Dim DUMMY
If objReg.GetDWORDValue(HKEY_LOCAL_MACHINE,strKey,strValue,DUMMY) <> 0 Then
ExistsDWORD = FALSE
Else
ExistsDWORD = TRUE
End If
End Function

Function ExistsSTRING
Dim DUMMY
If objReg.GetSTRINGValue(HKEY_LOCAL_MACHINE,strKey,strValue,DUMMY) <> 0 Then
ExistsSTRING = FALSE
Else
ExistsSTRING = TRUE
End If
End Function

Function ExistsMULTISTRING
Dim DUMMY
If objReg.GetMULTISTRINGValue(HKEY_LOCAL_MACHINE,strKey,strValue,DUMMY) <> 0 Then
ExistsMULTISTRING = FALSE
Else
ExistsMULTISTRING = TRUE
End If
End Function