Creating RemoteApp and XenApp boot scripts

A common problem with Remote Desktop Services RemoteApp and Citrix XenApp environments is that the same user may start the same application multiple times, which is a problem when resources are limited. The solution is to create a boot script that starts the application, but only if it is not already started by the executing user.

This page explains how to make boot scripts that block multiple use of an application from the same user and shows an example of creating a custom application launch graphical menu. A Remote Desktop Services RemoteApp will be used as an example, but the principles are the same for XenApp applications.

Please refer to this page for information on how to deploy application to all servers in a farm.

RemoteApp and XenApp boot scripts

Blocking multiple application starts by same user

To create the simplest possible demonstration setup, we will start Notepad as a Remote Desktop Services RemoteApp. But we will not start Notepad.Exe directly, we will publish a script called "Notepad.fsh" that will handle the launch logic instead. This script will then be published as a RemoteApp. In this case the script is placed on the server in a directory called D:\RemoteApps, where a sub-folder called "FSH" contains a copy of FSH.Exe and FSH.Lic:

FSH Directory structure

We now need to create the RemoteApp to start the Notepad launch script. We need to start FSH.Exe and pass the Notepad.fsh script file as a parameter. Our new RemoteApp properties look like this:

Notepad as RemoteApp

The Notepad.fsh script must enforce starting Notepad.exe only once per user and for this we need the condition "UserProcessRunning", which (unlike ProcessRunning) looks only at processes of the current user. So if we wanted to let any one user start notepad only once as a RemoteApp, we could simply check if there is already a similar process running under this user account. This simple script is enough to enforce the rule:

If Not UserProcessRunning Notepad.exe Then

  Launch Notepad.exe

Else

  ShowErrorMessage Notepad can only be started once per user.

End If

The second time any one user starts the rdp file for the RemoteApp, this message is shown:

Remote Desktop Services blocking

The script could easily be expanded with more logic. For example - in the real world, not all users are equally important. If we wanted to block execution of notepad, but not for a certain group of users, we can simply add another condition. In the script below, a user may start Notepad multiple times, if he or she is member of the group "AcmeSuperUsers".

If Not UserProcessRunning Notepad.exe Or UserIsMemberOf AcmeSuperUsers Then

  Launch Notepad.exe

Else

  ShowErrorMessage Notepad can only be started once per user.

End If


Stateless version

The reason the above script works is because the TS Session Broker will direct a user to the same server, if the user already has a session. If other load balancing technologies are used and a user therefore may be served by different servers, it is of course not possible to identify existing sessions by looking at process information, as these reside in memory per server. We need to store session states somewhere else and in this case we will use a SQL Server database to host session state changes.

The schema for this example is as shown below. A new table named "AppState" is created in a database called "RemoteAppState":

Remote Desktop Services state table

Basically all we have to do is to make sure a record is written at launch and then deleted, when the process has completed. When the script is started, a check is needed to see, if a record is present in the combination of the application name and user name. Such a script could look like this:

Set SqlInstance=192.168.1.3

Set AppName=Notepad

 

Set LastLaunch=[SQLQuery "SELECT LaunchTime FROM AppState WHERE AppName='[Var AppName]' AND UserName='[UserName]'",[Var SqlInstance],RemoteAppState]

 

If VarIsEmpty LastLaunch Then

  ExecSQL "INSERT INTO AppState (AppName,UserName,LaunchTime) VALUES ('[Var AppName]','[UserName]',GetDate())",[Var SqlInstance],RemoteAppState

  Run Notepad.exe

  ExecSQL "DELETE FROM AppState WHERE AppName='[Var AppName]' AND Username='[UserName]'",[Var SqlInstance],RemoteAppState

Else

  ShowErrorMessage Notepad can only be started once per user.

End If


Creating boot menus

It is also possible to create menus with simple scripts. This voids the need for lots of different .rdp files and only one published application is then necessary. The script below is a simple example, where Office programs and the fictitious company Acme's ERP system are made available to everyone.

Remote Desktop Services menu

Set App = [Menu Select application,Document|Microsoft Word,Chart|Microsoft Excel,User|Microsoft Outlook,Process|ERP System]

 

Switch [Var App]

  Case Microsoft Word

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\WINWORD.EXE

  Case Microsoft Excel

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\Excel.EXE

  Case Microsoft Outlook

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\Outlook.EXE

  Case ERP System

    Launch [ProgramFilesDir]\Acme\Acme Corp\AcmeERP.EXE

End Switch

In the real world it is of course unlikely that all users may actually start all applications. The example below builds a menu based on user domain group memberships instead. You can insert this example in the script editor by selecting "RemoteApp Boot Menu" in the "New Script" window.

/**** CREATE AN EMPTY COLLECTION ****/

CreateCollection AvailableApps

 

/**** ADD APPLICATIONS BASED ON USER GROUPS ****/

If UserIsMemberOf OfficeUsers Then

  AddToCollection AvailableApps,Document|Microsoft Word

  AddToCollection AvailableApps,Chart|Microsoft Excel

  AddToCollection AvailableApps,User|Microsoft Outlook

End If

 

If UserIsMemberOf ERPUsers Then AddToCollection AvailableApps,Process|ERP System

 

/**** EXIT IF NOTHING IS AVAILABLE ****/

If CollectionIsEmpty AvailableApps Then Exit

 

/**** SHOW MENU ****/

Set App = [Menu Select application,[Collection AvailableApps]]

 

/**** LAUNCH SELECTED APP ****/

Switch [Var App]

  Case Microsoft Word

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\WINWORD.EXE

  Case Microsoft Excel

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\Excel.EXE

  Case Microsoft Outlook

    Launch [ProgramFilesDirx86]\Microsoft Office\Office14\Outlook.EXE

  Case ERP System

    Launch [ProgramFilesDir]\Acme\Acme Corp\AcmeERP.EXE

End Switch



Rating: 5 out of 5

"Use this as a replacement for VBScript and PowerShell"

"It's easy to include attractive GUI elements in FastTrack scripts, beyond the basic dialog boxes and text input that VBScript offers ... Another powerful feature is the ability to distribute scripts as Windows Installer (.msi) or standard .exe files. Although interesting in its own right, this ability results in a much more intriguing capability: to repackage -- or wrap -- software installers as .msi files without using snapshots. If you've ever created an .msi installer file from before-and-after system snapshots, for use with a software distribution system such as Group Policy or SCCM, then you know how hit-and-miss the results can be."

Read full review


Rating: 8 out of 10

"Faster than the rest"

"We found the FastTrack syntax to be more transparent and easier to learn than Microsoft's PowerShell – the editor in particular provided good support in this regard. the Script Editor offers a large number of options from the command set through to simple output of graphical elements, which cannot be achieved at all with PowerShell or other solutions or only with a significantly greater level of effort."

"Anyone wanting to tackle the many hurdles in everyday admin and especially anyone for whom logon scripts and client automation is a priority will benefit from the variety of functions offered by FastTrack."

Review in English      Review in German