Scripting for Server Based Computing: Part 3 – Citrix Presentation Server Scripting

by Andy Jones [Published on 31 Jan. 2006 / Last Updated on 31 Jan. 2006]

VBScript and WMI are very powerful toolsets that allow server based computing administrators to perform some very complex, and sometimes mundane, tasks with consistency and speed. This article series serves as a look into leveraging this toolset to simplify the configuration of server and user settings. Part three of this article series will look at Citrix Presentation Server’s MFCOM Object. We will explore the settings and properties that may be managed via VBScript and WMI.

If you would like to read the other articles in the series please go here:

Introduction

In part one of this series, we explored how VBScript and WMI could be leveraged for the modification of Active Directory User Object terminal services specific Attributes. In part two, we looked at the various scripting capabilities available for the Terminal Services service and connections. Now we will turn our attention to a VERY large topic, that being the MFCOM Object capabilities of the Presentation Server API. Before we begin, the topic of MFCOM (and COM/Object oriented scripting) are well beyond the basis of this article series. Instead we will look at some examples of WHAT information we can gather and configure at a base level and then discuss how to find the voluminous API information.

Let us first look at what scripting in a Presentation Server environment is and what it isn’t. Scripting for Presentation Server is made possible through the MFCOM Interface. MFCOM (MetaFrame COM) is the API interface for scripting, and full coding, which allows us as administrators to automate tasks such as information gathering, configuration changes and so on. Scripting for Presentation Server is NOT a replacement for the previous topics of this article series, terminal services scripting and Active Directory Object scripting to name a few. Additionally, scripting for Presentation Server is NOT meant to be a replacement for Group Policy Objects, Citrix Policy or good ol’ fashioned use of the GUI management tools. Instead, it is for quick, consistent information gathering about Presentation Server settings or modification thereof.

So, without further ado, let’s look at the particular types of information that we are going to investigate in this article. Again, keep in mind that MFCOM is a VERY big API that allows virtually ANY aspect of a Presentation Server’s operation and configuration to be adjusted. We are going to review how to gather some basic information about the servers in our farm. To that end, the sample WSF script in this article is aptly named FARMSERVERLISTER.WSF as it will determine the number of servers in a farm and then list out several important pieces of information about the server’s configuration. For those of you that are a more “GUI-minded” administrator, the settings in question that we will be “polling” will be viewable primarily from the Presentation Server Management Console by locating a given server’s properties. Figure one below gives a window view of the types of information our script will collect for us.


Figure 1: Sample Presentation Server General Settings

For those of you that have a LARGE farm or have ever had the pleasure of managing a large farm, maintaining consistent settings, service pack and hotfix levels can be a challenge. The sample script that we will look at below will perform a basic query (no actual configuration changes, though that would be easy enough to add) of various settings and configuration information from the servers in my test farm. At the end of the scripts execution (which may take a bit of time in a larger farm) it will present a windows pop-up of the information collected and also create a text file called THE_FARM_REPORT.TXT in the same working directory from which the script is executed. (Yes, I realize that the windows pop-up is useless in a large farm, but I did if more for testing the script as I created it… in a large environment the text file will be far more helpful.)

Please keep in mind that even though this is a READ-ONLY script, never execute it on your production environments without adequate testing and a complete understanding of the work being done. Figures two and three demonstrate the kinds of information we are going to collect with the script.


Figure 2: Sample GUI Windows Pop-Up Output


Figure 3: Sample File Output

NOTE:
A REALLY good modification to the sample script I wrote below would be to change the output from a “flat” test file to a CSV or Tabbed-Value file to allow easy importation into your spreadsheet application of choice. I started to convert the script to do this prior to completing this article but stopped thinking that it would be an excellent exercise for the readers of this article to learn the functions and become more proficient at scripting in general. I will give you a hint, if the tabbed look is what you are going for think VbTab...

The MFCOM Interface or API is a rather large and all encompassing code toolset. While being vast, it is laid out fairly logically… meaning that what you can do in the GUI is roughly analogous to what can be done in coding. There are Farm level values, server level values, printers, zones and sessions to name a few. Just like you would go to certain section of the GUI Presentation Server Management Console tool to make changes to these settings or gather information, the API is laid out in the same fashion.  Table one below has an abbreviated list of the some of the more popular objects in the API that we can levering in scripting.

Farm Object

Zone Object

Server Object

Application Object

Account Authority Object

Session Object

Process Object

User Object

Group Object

Virtual Channel Object

License Object

License Set Object

License Number Object

Policy Object

Printer Object

Printer Driver Object

Printer Driver Mapping Object

Client Printer Object

Folder Object

MetaFrame Administrator Object

Table 1: Most Popular MFCOM Objects for Scripting

So… without further ado, let’s break down some of the elements we will be querying in the sample script. The first half or so of the script below is simply setting up the variables and objects we will be using to query information. The sections in particular worth noting are the pieces of code with the aWinServer, bWinServer and cWinServer, specifically pieces like aWinServer.EnableLogon where we are actually “getting” information about logon status. The first question should be: what is the a, b and c WinServer stuff… and it is basically a variable I am defining to allow me to write short-hand for the three different WinServerObject that you can note below. In a nutshell, as Citrix has continued to EXTEND the Presentation Server product, the server object has been extended to include the ability to code to the API by adding MORE Server Object Interfaces, therefore WinServerObject2, etc. At this point, PS 4 has 4 distinct WinServerObject interfaces.

Now, let’s look at the script itself. Simply copy and paste everything from and including the <package> at the beginning through the </package> at the end into a WSF file on a Presentation Server (version 4 preferably, though the code should work on PS 1/XP FR3 or newer).

<package>
<job id=" FarmServers">

<comment>
          File: FarmServerLister.wsf
          Description: List all Servers in a farm and details about the server.
          Requirements: WSH 5.5 or higher.

</comment>
<runtime>

<description>
          List Servers in the farm.
</description>

<example>
          CScript FarmServerLister.wsf //nologo
</example>

</runtime>

<reference object="MetaFrameCOM.MetaFrameFarm"/>
<script language="VBScript">

On Error Resume Next
Dim theFarm, aServer, aWinServer, bWinServer, Report

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set FinalReport = oFSO.OpenTextFile("The_Farm_Report.txt", 2, True)

'***************************************************************************
' Create MetaFrameFarm object
'***************************************************************************

Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
if Err.Number <> 0 Then
          Report = Report & vbcrlf & "Can't create MetaFrameFarm object"
          Report = Report & vbcrlf & "(" & Err.Number & ") " & Err.Description
          Report = Report & vbcrlf & ""
          Wscript.Echo Report
          FinalReport.WriteLine Report
          WScript.Quit Err.Number
End if

'***************************************************************************
' Initialize the farm object.
'***************************************************************************

theFarm.Initialize(MetaFrameWinFarmObject)
if Err.Number <> 0 Then
          Report = Report & vbcrlf & "Can't Initialize MetaFrameFarm object"
          Report = Report & vbcrlf & "(" & Err.Number & ") " & Err.Description
          Report = Report & vbcrlf & ""
          Wscript.Echo Report
          FinalReport.WriteLine Report
          WScript.Quit Err.Number
End if

'***************************************************************************
' Are you Citrix Administrator?
'***************************************************************************

if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then
          Report = Report & vbcrlf & "You must be a Citrix admin to run this script"
          Report = Report & vbcrlf & ""
          Wscript.Echo Report
          FinalReport.WriteLine Report
          WScript.Quit 0
End If

'***************************************************************************
' Begin the ACTUAL report
'***************************************************************************

Report = Report & "MetaFrame Farm Name: " & theFarm.FarmName
Report = Report & vbcrlf

'***************************************************************************
' Display all servers in the farm.
'***************************************************************************

Set Servers = theFarm.Servers
Report = Report & vbcrlf & Servers.Count & " Server(s) in the farm (" & Now & ")"
Report = Report & vbcrlf & "------------------------------------------------"

For Each aServer In theFarm.Servers

if Err.Number <> 0 Then
          Report = Report & vbcrlf & "Can't enumerate servers"
          Report = Report & vbcrlf & "(" & Err.Number & ") " & Err.Description
          Report = Report & vbcrlf & ""
          WScript.Quit Err.Number
End if

Report = Report & vbcrlf & vbcrlf & "Name : " & aServer.ServerName
Report = Report & vbcrlf & "IP Address : " & aServer.IPAddress

'***************************************************************************
' MetaFrameWinServer object.
'***************************************************************************

Set aWinServer = aServer.WinServerObject
Report = Report & vbcrlf & "Windows Version : " & aWinServer.WinNTVerMajor & "." & _
          aWinServer.WinNTVerMinor
Report = Report & vbcrlf & "PS Version : " & aWinServer.MFWinVerMajor & "." & _ 
          aWinServer.MFWinVerMinor
Report = Report & vbcrlf & "PS Service Pack : " & aWinServer.MFWinServicePack
Report = Report & vbcrlf & "Product Version (Ent, Adv or Std) : " & _ 
          aWinServer.MFWinName
Report = Report & vbcrlf & "PS Build : " & aWinServer.MFWinBuild
Report = Report & vbcrlf & "Use Farm ICA Display Settings (1=Yes) : " & _
          aWinServer.UseFarmICADisplaySettings
Report = Report & vbcrlf & "Discard Redundant Graphics (1=Yes) : " & _ 
          aWinServer.NoRedundantGraphics
Report = Report & vbcrlf & "Alternate Caching Method Enabled (1=Yes) : " & _
          aWinServer.AlternateCachingMethod
Report = Report & vbcrlf & "Use LEGACY ICA Display Compatability Mode (1=Yes) : " & _
          aWinServer.LegacyICADisplayCompatibleMode
Report = Report & vbcrlf & "ICA Video Buffer Size (bytes) : " & _
          aWinServer.ICAVideoBufferSize
Report = Report & vbcrlf & "Degradation Bias (1=Res,2=Color): " & _
          aWinServer.DegradationBias
Report = Report & vbcrlf & "Notify Degradation (1=Yes) : " & _
          aWinServer.NotifyDegradation
Report = Report & vbcrlf & "Use Farm SNMP Settings (1=Yes) : " & _
          aWinServer.UseFarmSNMPSettings
Report = Report & vbcrlf & "SNMP Agent Enabled (1=Yes) : " & _
          aWinServer.EnableSNMPAgent
Report = Report & vbcrlf & "Data Collector Responds to ICA Broadcasts (1=Yes) : " & _
          aWinServer.RespondToClientBroadcast
Report = Report & vbcrlf & "Logons Enabled (1=Yes) : " & _
          aWinServer.EnableLogon
Report = Report & vbcrlf & "Shadow Logging Enabled (1=Yes) : " & _
          aWinServer.EnableShadowLogging

Set bWinServer = aServer.WinServerObject2
Report = Report & vbcrlf & "Feature Release Level : " & _
          bWinServer.FeatureReleaseLevel
Report = Report & vbcrlf & "Console Shadowing Allowed (1=Yes) : " & _
          bWinServer.IsShadowingConsoleAllowed
Report = Report & vbcrlf & "# Installed Hotfixes : " & _
          bWinServer.HotfixCount
If bWinServer.HotfixCount <> 0 Then
'If bWinServer.HotfixCount = 0 Then
          nHotfixes = bWinServer.HotfixCount
          aHotfixes = bWinServer.Hotfixes

          HFList = vbTab & "Hotfix Name" & vbTab & "Installed on" & _
                   vbTab & "Installed by"                    
          For iCount = 0 To (nHotfixes - 1)
          Set aHotfix = aHotfixes(iCount)
          Set Datein = aHotfix.InstalledOn

                   If iCount = 0 Then
                   'WScript.Echo anServer.ServerName 
                   End If
                   HFList = HFList & vbTab & aHotfix.Name & vbTab & _
                             Datein.Month & "/" & Datein.Day & "/" & Datein.Year & _
                             vbTab & aHotfix.InstalledBy

          Next

Report = Report & vbcrlf & HFList
End If

Report = Report & vbcrlf & "Use Farm AutoReconnect Setting (1=Yes) : " & _
          bWinServer.UseFarmACRSetting
Report = Report & vbcrlf & "AutoReconnect Enabled (1=Yes) : " & _
          bWinServer.EnableACR
Report = Report & vbcrlf & "Log AutoReconnect Attempts (1=Yes) : " & _
          bWinServer.LogACRAttempts
Report = Report & vbcrlf & "XML Port (0=Sharing) : " & _
          bWinServer.XMLPortNumber
Report = Report & vbcrlf & "Printing Bandwidth (-1=Unlimited) : " & _
          bWinServer.PrintingBandwidth
Report = Report & vbcrlf & "Use Farm SmartCard Setting (1=Yes) : " & _
          bWinServer.UseFarmSmartCardSetting
Report = Report & vbcrlf & "Current Server Load : " & _
          bWinServer.ServerLoad

Set cWinServer = aServer.WinServerObject2
Report = Report & vbcrlf & "Use Farm Speed Browser Settings (1=Yes) : " & _
          cWinServer.UseFarmSpeedBrowse
Report = Report & vbcrlf & "Use Farm ICA KeepAlive Settings (1=Yes) : " & _
          cWinServer.UseFarmICAKeepAliveSetting
Report = Report & vbcrlf & "ICA KeepAlive Enabled (1=Yes) : " & _
          cWinServer.EnableICAKeepAlive
Report = Report & vbcrlf & "ICA KeepAlive Timeout (60 Sec Default) : " & _
          cWinServer.ICAKeepAliveTimeout
Report = Report & vbcrlf & "Use Farm Content Redirection Settings (1=Yes) : " & _
          cWinServer.UseFarmContentRedirectionSetting
Report = Report & vbcrlf & "Content Redirection Enabled (1=Yes) : " & _
          cWinServer.EnableContentRedirection
Report = Report & vbcrlf & "Use Farm Remote Console Connection Setting (1=Yes) : " & _
          cWinServer.UseFarmRemoteConsoleConnectionSetting
Report = Report & vbcrlf & "Remote Console Connection Enabled (1=Yes) : " & _
          cWinServer.EnableRemoteConsoleConnection

Next

Wscript.Echo Report
FinalReport.WriteLine Report

</script>
</job>
</package>

Conclusion

With this article, we close the scripting series. It is fitting that we end the series with the BIGGEST door being still open, namely that of MFCOM Scripting. The sample script above could be easily modified to create a CSV or TSV file that could EASILY be used to sort and compare server values for very large farms. For the purposes of this article, I chose to have the script display it’s findings in a popup and to write a text file to the “working directory” of wherever you execute the script. I am sure that you will have your mind filling with fantasies of scripts running virtually every aspect of your Presentation Server environment... for further information, please consult Citrix’s online knowledge base concerning Scripting and the Presentation Server SDK at http://support.citrix.com/article/CTX102095 and http://apps.citrix.com/cdn/SDK/server_sdk_v40.asp. There are MANY, MANY things we could have added to this article, but the API is rather large to include here so make sure to leverage the printed and online docs from Citrix and this sample script as an excellent starting point! In closing, please note that Citrix updates the MFCOM and the SDK with every version of Presentation Server, so be sure you are scripting to the specific API that is available with the MFCOM in question. In other words, you won’t be able to query new features from older servers?!

If you would like to read the other articles in the series please go here:

Advertisement

Featured Links