Creating a custom template for Citrix Optimizer

Do you optimize your image? If not, you should! Citrix Optimizer is THE optimization tool for Citrix workers, created by Citrix for Citrix customers. The default templates included in Citrix Optimizer are pretty solid, but creating a custom template for Citrix Optimizer is an option as well. This article explains how to create these.

Change Log
22.03.2019: updated article for Citrix Optimizer version 2.0.0.109 released in December 2018.
19.03.2019: updated article for Citrix Optimizer version 2.1.1.23 released in March 2019.

Table of Contents

Introduction

This article was initially written for Citrix Optimizer version 1.2.0.67, but has been updated for version 2.1.1.23 released in March 2019. Citrix Optimizer is updated every three to five months. I do my best to keep the information in this article as up-to-date as possible.

First of all, if you are not familiar with Citrix Optimizer, please check out the following links:

You may wonder why there is a need to create custom templates. Doesn’t the Citrix Optimizer already include all necessary optimizations? The truth is that no optimization tool can ever include everything you may require in your organization. This would be an unfair expectation of any tool. What is a valid expectation though is to be able to create your own custom templates so you can add your own customizations. You can customize Citrix Optimizer by using the built-in feature Template Builder or by modifying the underlying XML files. In this article I explain in detail how you can create your own custom templates.

An overview of Citrix Optimizer

Release notes:

  • Citrix Optimizer v1.2.0.67: the first release of Citrix Optimizer.
  • Citrix Optimizer v2.0.109 (released in December 2018):
    • Added templates for Windows 10 build 1809 and Windows Server 2019 build 1809
    • Updated schema and names of all templates
    • Added support for template auto-selection
    • Added Template Builder (GUI)
    • Added Template Marketplace
    • Bug fixes
  • Citrix Optimizer v2.1.1.23 (released in March 2019):
    • Added option to remove marketplace
    • Many improvements and bug fixes for Template Builder and Marketplace
    • Added support for proxy configuration
    • Enhanced HTML reports, added ability to redirect logs

Log files are written to the subdirectory Logs. This directory is created automatically when running Citrix Optimizer.

The screenshot below shows the Citrix Optimizer directory structure, highlighting the directory where the XML templates are stored.

Creating a custom template for Citrix Optimizer - Citrix Optimizer folder structure

When the GUI of the Citrix Optimizer (CitrixOptimizer.exe) is launched, it lists all available XML files found within the Templates directory:

Creating a custom template for Citrix Optimizer - Citrix Optimizer screenshot

Any custom XML you add to the local Templates directory is listed automatically by Citrix Optimizer.

Template Marketplace

In version 2.0.109, the new feature Template Marketplace was introduced. The default market place is the Citrix internal marketplace where you can get new or updated templates.

Creating a custom template for Citrix Optimizer - Template marketplace

It is also possible to add new, external, marketplaces. I recommend that you add the Citrix Community Marketplace created by Citrix CTP Ryan Butler. To connect to this marketplace, go to Template Marketplace in the GUI, click on +Add New Marketplace and enter the following URL:

https://raw.githubusercontent.com/ryancbutler/Citrix_Optimizer_Community_Template_Marketplace/master/communitymarketplace.xml

Note: my template for optimizing Windows Server 2016 is also included in the Citrix Community Marketplace.

Creating a custom template for Citrix Optimizer - Add new template marketplace

Of course, when you create templates of your own, please share them and add them to the marketplace. Your contribution will be appreciated!

Template Builder

In version 2.0.109, the new feature Template Builder was introduced. This is a powerful feature that allows you to:

Create new templates

To create a new template, go to the section Template Builder. Select an existing category or create a new one. After that, you can either create a new template from scratch or you can open an existing template, modify it and save it under a new name.

Creating a custom template for Citrix Optimizer - Template Builder Add new template 1

In case you select Add New Template, you will have to fill out the following information:

Creating a custom template for Citrix Optimizer - Template Builder new template metadata

See the section Metadata in this article for more information.

Now you can start to create a new group.

Creating a custom template for Citrix Optimizer - Template Builder new template create new group

A group should contain at least one item.

Creating a custom template for Citrix Optimizer - Template Builder new template create new item

The item can be of various types:

Creating a custom template for Citrix Optimizer - Template Builder new template create new item type

Modify existing templates

To modify an existing template you go to Template Builder, select the category and than the template. This will open the template in edit mode. Here you can edit existing groups and existing items. You can also create new groups and items.

Creating a custom template for Citrix Optimizer - Template Builder modify an existing template

When you are ready you can either save the template (and overwrite the existing one) or save it as a new template.

Creating a custom template for Citrix Optimizer - Template Builder save template

When you save the template as a new template you have to fill out the metadata, the same as if you would create a new template from scratch.

Creating a custom template for Citrix Optimizer - Template Builder save template metadata

See the section Metadata in this article for more information.

Create new categories

The categories that are shown in the GUI depend on the templates that are included in the templates directory. The GUI simply reads the metadata section of each template and displays both the list of templates and the list of categories accordingly.

Creating a custom template for Citrix Optimizer - Categories header

Creating a custom template for Citrix Optimizer - Example multiple categories

The category in the official Citrix templates is OS Optimizations, so this is the only one you see by default.

You can create a new category in the section Template Builder.

Creating a custom template for Citrix Optimizer - Template Builder Add new category

After creating a new category you can start creating a new template.

Creating a custom template for Citrix Optimizer - Template Builder Add new template

It is also possible to change the category at a later time by directly modifying the XML file (the template file).

Under the hood: a breakdown of a Citrix Optimizer template

From version 2.0.109, Citrix Optimizer includes a GUI that allows you to create and modify templates. It is no longer necessary to manually modify the XML files. The contents in this section was originally created for version 1.x of Citrix Optimizer, where the only way how to create a custom template was to manually build it. I have updated all information in this section to version 2.x of Citrix Optimizer.

Citrix Optimizer templates are XML files. One XML file = one template.

Creating a custom template for Citrix Optimizer - Templates directory contents

These files can be opened in any text editor, for example in Notepad. The XML structure is build-up as follows.

Metadata

The metadata section, among other items, includes the display name of the template (which is visible in the GUI):

Creating a custom template for Citrix Optimizer - GUI title and info button

Other information included in this section are:

  • The description of the template (shown when hovering over the information icon)
  • The version of the template: this is the internal version of the template which the author has to keep up-to-date. This has nothing to do with the version of Citrix Optimizer.
  • The category: from version 2.0.109 you can create custom categories within the GUI (the standard category used by all official Citrix templates is OS Optimizations).
  • The author of the template. This can be the name of an organization or an individual.
  • The ID. The ID of each template has to be unique, otherwise an error is thrown in Citrix Optimizer.
  • The date the template was last modified (lastupdatedate). The date format is written in the month/day/year format using the forward slash as a separator (e.g. 11/27/2018). Make sure to always modify this field when updating your custom templates (together with the version number), especially when you want to offer them in an external market place.

Creating a custom template for Citrix Optimizer - XML template header

Groups

Groups represent the main categories in a template. The display name of a group is what you see in the left pane in the GUI.

Creating a custom template for Citrix Optimizer - GUI groups

Creating a custom template for Citrix Optimizer - XML template groups

The group ID is the short name of the group. This short name is used when running Citrix Optimizer using PowerShell (as opposed to the GUI) and you only want to optimize settings included in specific groups, for example:

The ID has to be unique within the template.

Entries (within a group)

Entries represent the individual optimizations within one group. One entry equals one optimization.

Creating a custom template for Citrix Optimizer - GUI entries

Creating a custom template for Citrix Optimizer - XML template entries

Multiple entry types exist. These are explained in detail in the section Create a custom entry in this article.

Creating your own template manually

From version 2.x it is no longer necessary to manually create custom templates. You can use the Template Builder included in Citrix Optimizer. Although it is still possible to create your own custom template manually, I strongly recommend you to use the Template Builder. 

This section is intended for anyone who wants to understand the underlying XML structure of the Citrix Optimizer templates. Also, you sometimes may find yourself in the situation where you need to manually change something, such as the category (which currently cannot be changed using the GUI).

Customize the metadata

The first thing you want to do after you copied an existing template as your baseline is to customize the metadata:

Creating a custom template for Citrix Optimizer - XML template header

It is important to understand the items in the metadata section well (see the section Metadata in this article for more information).

Create a custom group

I recommend to create one or more custom groups that will include your custom optimizations, for example:

Creating a custom template for Citrix Optimizer V1 - Custom template open in Citrix Optimizer

A group is created using the tags <group> and </group>. A group also requires additional information such as the name of the group, a description and an ID:

  • The display name is placed between the tags <displayname> and </displayname.
  • The description is placed between the tags <description> and </description>.
  • The ID is placed between the tags <id> and </id>. This has to be unique within the current template.

Creating a custom template for Citrix Optimizer - XML template header group

Create a custom entry

Each group requires at least one entry. An entry is where the action happens. This is where the optimization of one particular setting is configured. The easiest way how to create a new entry is by copying an existing one.

All entries have the following tags in common:

  • The name for the entry: <name></name>.
  • The description of the entry: <description></description>.
  • The execution mode of the entry: <execute></execute>.
  • The configuration/optimization: <action></action>.
  • The Citrix Optimizer plugin: <plugin></plugin>. There are multiple plugins available. These are described in more detail below.
  • The parameters in the section <params>. These are plugin specific parameters that are required to perform the action. You find more details concerning the various actions in the sections below.

The execution mode of an entry can either be 0 or 1. Zero means that the setting is optional: <execute>0</execute>.

Creating a custom template for Citrix Optimizer - Example of an optional setting

One means that the setting is mandatory: <execute>1</execute>.

Creating a custom template for Citrix Optimizer - Example of a mandatory setting

Multiple types of entries are available:

Custom entry for Services

The entry for services looks as follows:

The example above is the first service that is disabled in the default template for Windows Server 2016 version 1607 (Citrix_Windows_Server_2016_1607.xml).

Enter the following variables to create this entry:

  • The name of the service (between the tags <name> and </name>). This can be any name you want. I recommend to use the display name of the server (e.g. AllJoyn Router Service as opposed to the service name AJRouter). The name can contain spaces.
  • The description of the service (between the tags <description> and </description>).
  • The execution value 1 (mandatory) or 0 (optional) between the tags <execute> and </execute>.
  • The name of the plugin to use (between the tags <plugin> and </plugin>). For services the name of the plugin is Services.
  • The name of the service (in the section <params> between the tags <name> and </name>). This has to be the service name and not the display name (e.g. AJRouter as opposed to AllJoyn Router Service).
  • The value of the action (= configuration of the service) in the section <params> between the tags <value> and </value>. Since we are working on optimizing the operating system the value should be Disabled.

This entry type automatically supports rollback when executed using PowerShell (as opposed to the GUI).

Custom entry for Scheduled Tasks

The entry for scheduled tasks looks as follows:

The example above is the first scheduled task that is disabled in the default template for Windows Server 2016 version 1607 (Citrix_Windows_Server_2016_1607.xml).

Make sure to write down the name and location (= relative path in the scheduled task directory structure). You will need this later.

Creating a custom template for Citrix Optimizer - Scheduled task name and location

Enter the following variables to create this entry:

  • The name of the scheduled task (between the tags <name> and </name>). This can be any name you want. I recommend to use the actual name of the scheduled task though. The name can contain spaces.
  • The description of the scheduled task (between the tags <description> and </description>).
  • The execution value 1 (mandatory) or 0 (optional) between the tags <execute> and </execute>.
  • The name of the plugin to use (between the tags <plugin> and </plugin>). For scheduled tasks the name of the plugin is SchTasks.
  • The name of the scheduled task (in the section <params> between the tags <name> and </name>). This is the name of the scheduled task as shown in the screen shot above.
  • The relative path of the scheduled task (in the section <params> between the tags <path> and </path>). This is the location of the scheduled task as shown in the screen shot above. Any yes, the back slash at the beginning of the path should be included as well.
  • The value of the action (= configuration of the scheduled task) in the section <param> between the tags <value> and </value>. Since we are working on optimizing the operating system the value should be Disabled.

This entry type automatically supports rollback when executed using PowerShell (as opposed to the GUI).

Custom entry for Registry

The structure of a default registry entry is as follows:

In case you want to remove a registry value completely you can use the value CTXOE_NoValue, like this:

This entry type automatically supports rollback when executed using PowerShell (as opposed to the GUI).

Custom entry for PowerShell (also used to modify the registry and to run executables)

The PowerShell plugin allows you to be very flexible in your customization. Let me explain how to use this plugin using some examples.

Please be aware that for custom PowerShell functions you need to create your own rollback procedure.

You can of course create any routine using PowerShell you require. I invite you to use the examples below to create your own customizations. If possible, it would be great if you could share these with the community.

PowerShell: set a registry value (e.g. disable Cortana)

In this example, we will disable Cortana by changing the corresponding registry value using PowerShell. You can of course also use the registry plugin for this.

Add the following code to your custom Citrix Optimizer template if you want to optimize (disable) Cortana:

Most of the tags are the same as explained in the previous sections in this article, such as <name>, <description> <execute>, <action> and more. To be able to execute PowerShell code you have to use the plugin PowerShell. Add this between the tags <plugin> and </plugin>.

The section <executeparams> contains the code that will configure your optimization. Let’s take a closer look at the PowerShell code.

In the first couple of lines we define some variables such as the registry key path, the registry value name, the registry value and the value type (e.g. DWORD or STRING).

Then we check whether or not the registry key exists. If not, it is created (New-Item). In case of an error, the error level is raised ($ExitCode++) and the Optimizer internal variable $Global:CTXOE_Result is set to $False to indicate the setting has not been optimized.

In the last section using the PowerShell cmdlet New-ItemProperty, the registry value is configured. In case there is no error, the Optimizer internal variable $Global:CTXOE_Result is set to $True to indicate that the setting has been optimized. Should an error occur the Optimizer internal variable $Global:CTXOE_Result is set to $False to indicate that the setting was not optimized.

The section <params> contains the code that checks the current configuration and determines whether or not the current configuration is already optimized or not. Let’s take a closer look at the PowerShell code.

First we define the registry path, value name and required value.

Then, using a try / catch statement we retrieve the current value and store it in the variable $RegResult. In case the registry value does not exist the Optimizer internal variable $Global:CTXOE_Result is set to $False.
In case the value in $RegResult is equal to the value in the variable $RegValue, the setting is optimized ($Global:CTXOE_Result = $True). Otherwise, the setting has not yet been optimized and $Global:CTXOE_Result is set to $False).

PowerShell: rename a registry value (e.g. disable Active Setup)

Active setup runs at first user logon, but only within a published desktop. When starting a published application, Active Setup does not run. This is why it is a best-practice to disable Active Setup entirely. See Citrix CTP Helge Klein’s article Active Setup Explained for more information.

The easiest way how to disable Active Setup is to rename both the 32-bit and 64-bit registry keys. Renaming the parent registry key automatically disables all individual Active Setup entries beneath it.

Original key names:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Active Setup\Installed Components

Key names after being renamed (and thus disabled):

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\_DISABLED Installed Components_2018-11-10_10-24-11
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Active Setup\_DISABLED Installed Components_2018-11-10_10-24-11

Add the following code to your custom Citrix Optimizer template if you want to optimize (disable) Active Setup 32-bit:

Add the following code to your custom Citrix Optimizer template if you want to optimize (disable) Active Setup 64-bit:

Most of the tags are the same as explained in the previous sections in this article, such as <name>, <description> <execute>, <action> and more. To be able to execute PowerShell code you have to use the plugin PowerShell. Add this between the tags <plugin> and </plugin>.

The section <executeparams> contains the code that will configure your optimization. Let’s take a closer look at the PowerShell code.

In the first line we create a variable called $DateTime that includes the current date and time. We will use this later.

Now we define the new name for the registry key:

The fully qualified path of the registry key is set:

In the following part we test whether or not the original registry key exists. If not, this means that Active Setup has already been optimized (disabled). The Optimizer internal variable $Global:CTXOE_Result is set to $True, telling Citrix Optimizer that the setting has already been optimized.
In case the original Active Setup registry key exists, the key is renamed (Rename-Item). If this is successful, $Global:CTXOE_Result is set to $True. If for some reason renaming the key was not successful, $Global:CTXOE_Result is set to $False.
The Optimizer internal variable $Global:CTXOE_Details is used to report further details.

The section <params> contains the code that checks the current configuration and determines whether or not the current configuration is already optimized or not. Let’s take a closer look at the PowerShell code.

Here we simply check whether or not the original Active Setup key exists. If yes, than Active Setup is not optimized (not disabled) and the Optimizer internal variable $Global:CTXOE_Result is set to $False. If the registry key does not exist than Active Setup already has been optimized; the Optimizer internal variable $Global:CTXOE_Result is set to $True.

PowerShell: run an executable (e.g. disable DEP using “bcdedit.exe”)

It is a Citrix best-practice to disable Data Execution Prevention (DEP). See page 13 in the Citrix Windows 10 Optimization Guide.

You find DEP in the Control Panel under System \ Advanced \ Performance Settings \ Data Execution Prevention.

Creating a custom template for Citrix Optimizer - Data Execution Prevention

It is not possible to completely disable DEP in the GUI. This is only possible using the bcdedit.exe command.

Add the following code to your custom Citrix Optimizer template if you want to optimize (disable) DEP:

Most of the tags are the same as explained in the previous sections in this article, such as <name>, <description> <execute>, <action> and more. To be able to execute PowerShell code you have to use the plugin PowerShell. Add this between the tags <plugin> and </plugin>.

The section <executeparams> contains the code that will configure your optimization. Let’s take a closer look at the PowerShell code.

The first line executes BCDEdit with the parameters /set nx AlwaysOff to disable DEP. The dot (.) in the beginning is necessary if you want to use a combination of environment variables and literal path.

In the second and third line two custom Optimizer variables are used:

The variable $Global:CTXOE_Result returns the result back to Citrix Optimizer. A value of $True means that the optimization was successful; a value of $False means that the optimization failed. The variable $Global:CTXOE_Details returns more details to Citrix Optimizer.

The section <params> contains the code that checks the current configuration and determines whether or not the current configuration is already optimized or not. Let’s take a closer look at the PowerShell code.

First we need to enumerate the current BCDEdit configuration. The result is stored in the variable $BCDValue.

The information in the variable $BCDValue is not very readable so we need to split the result and store it in an array, removing any empty values.

Now we locate the value nx in the array and retrieve its array number. We know that the array item following nx is the actual value of nx, so we take the array number of nx and add 1 to get the array number of the value we are actually interested in.

Confused? Let me explain differently. Take a look at the screenshot below and locate the value nx. If the information below would be stored in an array and nx would be number 27 in that array, than the value OptOut would be number 28 in the array.

Creating a custom template for Citrix Optimizer - BCDEdit enumeration

The value of array number 28 (OptOut in our example) is what we are after. This value gets stored in the variable $BCDResult. The variable $BCDResult can contain one of four possible values: OptIn, OptOut, , AlwaysOff or AlwaysOff.

In the last two lines we determine whether or not DEP is optimized or not. In case the value store in the variable $BCDResult is AlwaysOff, DEP already has been optimized (disabled). In case it is any of the other three possible values than DEP is not optimized.

Conclusion

Creating your own custom template gives you more control over which settings are optimized. I invite you to share your experience with custom templates by leaving a comment below.

6 thoughts on “Creating a custom template for Citrix Optimizer

  1. Pingback: Using Citrix Optimizer with BIS-F | BLOGS

  2. Pingback: Supercharge Citrix Logins: Collection of Tips From the Field | BLOGS

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.