NetScaler – Rename multiple password boxes to meaningful names

On a Citrix NetScaler, when you enable Two Factor Authentcation (2FA) for a VPN/CAG vServer, two password boxes are presented to the user with the somewhat meaningless names of “Password 1” and “Password 2”. This configuration is defined in a JavaScript file called “login.js” which defines some of the JavaScript functions for the logon page and process.

NetScaler Password Prompt (Original)

Some sources advocate manually amending login.js on the NetScaler to rename them, but there are several issues with this approach:

  • The login.js can be overwritten during firmware upgrades
  • The change is masked from the console, making it very easy to overlook during migrations or troubleshooting
  • The changes are not synchronised across HA pairs
  • Instead, I recommend creating a set of Rewrite rules to accomplish the same task. There are three items to change:

  • Remove the automatic numbering of the password boxes
  • Rename “Password 1” to “AD Password”
  • Rename “Password 2” to “2FA Password”
  • And for those not familiar with NetScaler Rewrite rules, each change will consist of three parts:

  • Action: This defines exactly what content we’re changing and to what
  • Policy: When to perform the action (I.e., only when returning login.js)
  • Binding: When to evaluate the Policy (E.g., all the time or only a specific vServer etc)
  • And here they are:
    NB: If you remove the AD Password rename, remember to remove the other corresponding actions

    #Enable Rewrite Feature

    enable ns feature REWRITE

    #Rewrite Actions#

    #Prevent automatic numbering
    add rewrite action LoginPasswordNumber_delete_rewrite_action delete_all "http.RES.BODY(120000).SET_TEXT_MODE(ignorecase)" -pattern "document.write(\' 1\');" -bypassSafetyCheck YES

    #Rename AD Password (Optional)
    add rewrite action LoginPassword1_replace_rewrite_action replace_all "http.RES.BODY(120000).SET_TEXT_MODE(ignorecase)" q/"\"AD Password\""/ -pattern "_(\"Password\")" -bypassSafetyCheck YES

    #Rename Password 2 (Recommended)
    add rewrite action LoginPassword2_replace_rewrite_action replace_all "http.RES.BODY(120000).SET_TEXT_MODE(ignorecase)" q/"\"2FA Passcode:\""/ -pattern "_(\"Password2\")" -bypassSafetyCheck YES

    #Rewrite Policies#

    add rewrite policy LoginPassword1_rewrite_pol "http.req.url.path.endswith(\"vpn/login.js\")" LoginPassword1_replace_rewrite_action
    add rewrite policy LoginPassword2_rewrite_pol "http.req.url.path.endswith(\"vpn/login.js\")" LoginPassword2_replace_rewrite_action
    add rewrite policy LoginPasswordNumber_delete_pol "http.req.url.path.endswith(\"vpn/login.js\")" LoginPasswordNumber_delete_rewrite_action

    #Rewrite Binding (Global)#

    bind rewrite global LoginPassword1_rewrite_pol 80 NEXT -type RES_OVERRIDE
    bind rewrite global LoginPassword2_rewrite_pol 90 NEXT -type RES_OVERRIDE
    bind rewrite global LoginPasswordNumber_delete_pol 100 NEXT -type RES_OVERRIDE

    #Flush the content cache, before testing
    flush cache contentgroup all

    The end result should look something like this:

    NetScaler Password Prompt (Modified)

    Please note: I’m far from the first to do this (I.e., However, I struggled to get other peoples code to work properly and really didn’t want to change the files on the NetScaler – the above “just works” on 10.5 🙂


    StoreFront Groups in a Group Policy Restricted Groups Environment


    I was recently in a position where I had to investigate why a Citrix StoreFront 2.1 (And subsequently 2.5) implementation wasn’t working properly. They had a variety of synchronisation/propagation issues and I also discovered other strange behaviour. It transpired that the environment used Restricted Groups to reconfigure the Local Administrators group on all infrastructure servers. This is a documented problem ( as StoreFront requires the following users to be present in the Local Administrators Group:

    NT SERVICE\CitrixClusterService
    NT SERVICE\CitrixConfigurationReplication

    Unfortunately the simple solution of adding the users wouldn’t work, as they would be removed on each refresh of Group Policy. Removing this policy wasn’t an option, though we were able to modify it.

    The obvious resolution is to add the above users into your Restricted Groups Policy, but unfortunately the Group Policy GUI doesn’t allow the adding of  “NT SERVICE” users.

    Work Around

    Browse to the File System path of your Group Policy (e.g., \\domain\sysvol\domain.tld\Policies\{GPO-GUID})  and then browse to Machine\Microsoft\Windows NT\SecEdit\GPTTMPL.INF

    \\domain\sysvol\domain.tld\Policies\{GROUP-POLICY-GUID}\Machine\Microsoft\Windows NT\SecEdit\GPTMPL.INF

    Where Restricted Groups are configured, this INF file contains the raw configuration, where you should see something along the lines of:

    [Group Membership] *S-1-5-32-544__Members = *S-1-5-21-12345678-123456789-123456789-513

    Where S-1-5-32-544 denotes the “Administrators” group and the SID to the right denotes a user or group that is a member of the administrators group. The configuration can understand both SIDs and full text names and is comma separated. So, to add our Citrix users simply modify the file as follows:

    [Group Membership] *S-1-5-32-544__Members = *S-1-5-21-12345678-123456789-123456789-513,NT SERVICE\CitrixClusterService,NT SERVICE\CitrixConfigurationReplication

    And then, if you go back to the GUI, you’ll see the following:

    Restricted Groups GUI

    Restricted Groups GUI

    And, if those groups exist on a machine where the policy is applied, they’ll be included in the Administrators group.


    Google Earth Tweaks For A Remote Environment

    Background Information

    By default, Google Earth is configured with some fairly graphics intensive options. It might look great on a desktop, but it means performance can often be poor on a Citrix XenDesktop, XenApp or other Remote Desktop / virtualised environment.

    In addition, there are a few options that can improve start-up performance and user experience. Please test these settings before deploying to your own environment and note that none of these are enforced settings, users may change them if they wish.

    These were tested on version (Current as of April 2014) and I recommend applying with Group Policy Preferences

    Registry Settings

    HKCU\Software\Google\Google Earth Plus
    REG_SZ : AlwaysUseExternalBrowser : true
    REG_SZ : enableTips : false
    REG_DWORD : kmlErrorHandling : 0
    REG_SZ : useHttpsForGoogle2 : false
    Software\Google\Google Earth Plus\Render
    REG_DWORD : TextureColors : 0
    REG_DWORD : AnisotropicFiltering_6_2 : 0
    REG_SZ : HighQualityTerrain : false
    REG_SZ : 3DImageryEnabled : false
    REG_DWORD : RenderingApi : 0
    REG_SZ : DisableAdvancedFeatures : true
    REG_DWORD : Antialiasing : 0
    REG_SZ : Atmosphere : false
    REG_SZ : WaterSurface : false
    Software\Google\Google Earth Plus\TourGuide\Filmstrip
    REG_SZ : Enabled : false

    Settings Description

    AlwaysUseExternalBrowser – Force any web results to open in the corporate web browser
    enableTips – Disable Start-Up Tips. Improves loading performance
    kmlErrorHandling – Ignore KML errors and continue
    useHttpsForGoogle2 – Disable HTTPS for Google Earth. Can improve performance, especially in environment where access to CRL’s etc is restricted
    TextureColors – Set texture color depth to 16-bit
    AnisotropicFiltering_6_2 – Disable anisotropic filtering
    HighQualityTerrain – Disable high quality terrain textures
    3dImageryEnabled – Use legacy 3D Buildings, instead of new textured ones
    RenderingApi – Use DirectX Rendering
    DisableAdvancedFeatures – Run in “Safe Mode” and disable advanced graphics features such as midmap texturing
    Antialisasing – Disable antialisasing
    Atmosphere – Disable atmosphere rendering
    WaterSurface – Disable water surface rendering
    Enabled – Disable the Tour Guide window to improve start up performance



    Desktop Director – Pre-populating, disabling and hiding the Domain Textbox

    Background Information

    By default, the Desktop Director logon page displays three fields: User name, Password and Domain.

    Default Logon Page

    Default Logon Page

    In some use cases, it may be beneficial to pre-populate the Domain Textbox, disable changes or even hide it altogether. Please note that the following modifications are for usability only, none of these constitute a security feature. You must use the Citrix Studio to secure Director.


    All modifications are made within the “LogOn.aspx” file, which is located in the “Director”directory of the IIS server where Desktop Director is installed. By default, this location is:


    Make a copy of “LogOn.aspx” and rename it to “LogOn.aspx.bak”

    If the server is using UAC, launch Notepad by right clicking and selecting “Run as Administrator” and then open the file (NB: Drag and drop won’t work, you must browse to the file).

    If the sever isn’t running UAC, open the file as normal using Notepad.

    Pre-Populating the Domain Textbox

    Locate the line beginning with:

    <asp:TextxBox ID="Domain"


    Insert your domain name as shown:

    <asp:Textbox ID=”Domain” ... >MYDOMAIN.COM</asp:TextBox>
    Added Domain

    Added Domain

    Save the file and reload your Director logon page. If you did everything correctly, the page should now contain a pre-populated Domain Textbox

    Pre-populated Domain

    Pre-populated Domain

    Making the Domain Textbox Read-Only

    You may want to prevent users from altering the text in the Domain textbox. If you do this, then you must pre-populate it first as explained previously.

    Locate the tag which starts with:

    <asp:TextxBox ID="Domain"

    And change it, by adding ReadOnly=”True”

    <asp:TextBox ID=”Domain” ReadOnly="True"
    Read-only Domain

    Read-only Domain

    The logon page will look identical, but the Domain box will be Read-Only.

    Hiding The Domain Textbox

    As above, if you wish to hide the Domain textbox completely, ensure you have pre-populated it.

    Locate the tag which starts with:

    <asp:Label ID="DomainLabel"

    Immediately prior to that label, locate the following tag:

    <div class='label eight'>

    Locate the <Div> Tag

    Add the following before <div class=’label eight’>:

    <div style=’display:none’>

    Inbetween “</asp:Textbox> <br />” add the following:

    Hide Code

    Hide Code

    And the resulting logon page should look like this:

    Hidden Domain Textbox

    Hidden Domain Textbox


    XenDesktop – Assigning Private Desktops by Client IP or Hostname

    Background Information

    By default XenDesktop provides desktops on a First Come First Serve basis and, with regards to Private Desktops on an “Assignment on First Use” basis. In some scenarios, it’s preferable to pre assign these private desktops based on a client device. This document is only applicable to Delivery Groups with private desktops – the following will not work with shared delivery groups.

    Assigning Private Desktops

    The “Get-BrokerPrivateDesktop” and “Set-BrokerPrivateDesktop” cmdlets are used to allocate particular desktops to a client.


    Use the command as follows:

    Set-BrokerPrivateDesktop DOMAIN\DESKTOPNAME –Option1 Option –Option2 Option

    The following options are recommended:

    -AssignedIPAddress <string>

    This is the local IP of the connecting client.

    -AssignedClientName <string>

    This is the NETBIOS (NB: Not the FQDN) name of the connecting client. NB: Does NOT work if an IP Address is assigned. Clear the IP first.

    -PublishedName <string>

    This is a custom published name to differentiate the pre-assigned private desktop from the rest of the Delivery Group (NB: As of XenDesktop 7.1, it appears that you are unable to remove a PublishedName attribute once it has been assigned!) e.g:

    Set-BrokerPrivateDesktop CONTOSO\VDI001 –AssignedIPAddress –PublishedName “Front Office”

    The following can be used to get a quick overview of what has been assigned:

    Get-BrokerPrivateDesktop | ft MachineName,AssignedIPAddress,AssignedClientName,PublishedName

    Removing the Non-Assigned Desktop

    After assigning a client device to a specific VDI Desktop, users will be presented with two desktops – the pre-assigned client-based desktop and their own user-based desktop, from the same delivery group. If all desktops have been pre-allocated, the user will still see a launch icon, though an error will be displayed when attempting to connect.

    The “Get-BrokerAssignmentPolicyRule” and “Set-BrokerAssignmentPolicyRule” cmdlets are used to control this.


    Use the commands as follows:

    Run “Get-BrokerAssignmentPolicyRule” to return a list of rules. Note the “Name” of the assignment policy rule you want to modify (It will almost certainly match your Delivery Group name)

    The following command will now disable the ‘default’ user-based desktop:

    Set-BrokerAssignmentPolicyRule –Name “Desktop Name” –Enable $false

    Where a client has a private desktop assigned by IP or Hostname, only that desktop is displayed. If the user logs on elsewhere, no desktop will be displayed.

    Alternatively, the “ExcludedUsers” option may be used to only hide this desktop from particular users.

    Delivery Group Authentication

    By default, XenDesktop only uses Users and Groups to authenticate against a Delivery Group. If a user is not in the Delivery Group they won’t see any desktop associated with it, even if the desktop has been specifically assigned to their client device.

    “Get-BrokerAccessPolicyRule” and “Set-BrokerAccessPolicyRule” can be used to modify Delivery Group authentication beyond what is possible from within the console.


    Specific configuration is out of the scope of this document, but it’s possible to base authentication on IP Address or to simply open up the Delivery Group to all users.


    Enabling PNAgent Single Sign On (SSO) with Storefront 2.1

    Background Information

    StoreFront 2.1 provides compatibility for the Online Plug-In and legacy clients by enabling the exposure of a Web Interface “Services Site” style config.xml page. This is used by the PNAgent to discover the site (i.e. store) configuration options and is configured

    More information:

    By default, StoreFront is configured to only allow “Prompt” authentication from a PNAgent connection and an application launch.

    Enabling PNAgent SSON to StoreFront

    In order to allow PNAgent to use Single Sign-On to connect to the StoreFront server and enumerate the applications, do the following:

    1. Browse to C:\inetpub\wwwroot\Citrix\[StoreName]\Views\PnaConfig
    2. Make a backup of “Config.aspx”
    3. On the production copy of “Config.aspx”, make the following changes:
    4. Find the line starting with “<LogonMethod>” and ending with “</LogonMethod>”
    5. Change this line to “<LogonMethod>sson</LogonMethod>”
    6. Save the file and restart PNAgent. It should now automatically login and return the published applications.

    Enabling PNAgent SSON to the Published Applications

    In order to allow a user to correctly launch a published application delivered by SSON PNAgent, do the following:

    1. Browse to C:\inetpub\wwwroot\Citrix\[StoreName]
    2. Make a backup of “web.config”
    3. On the production copy of “web.config”, make the following changes:
    4. Find the line starting with “<pnaProtocolResources”
    5. Within that line, locate the “logonMethod” setting and change the method to “sson”. i.e. logonMethod=”sson”
    6. Your applications should now authenticate correctly.