Cold Starting and/or Hydrating Your Applications To Improve Their Startup Times

In the End User Computing (EUC) space we know that after the first time the application starts post reboot, the next time is faster. The first startup is referred to as a cold startup and all subsequent runs are warm startups. The first time the application starts, components of the application, such as the EXEs (executables) and DLLs (dynamic link libraries) need to be loaded from disk, which can delay the startup time. All subsequent runs will then read the data from the file system cache, which is memory managed by the Operating System.

Hydrate and Cold Start your applications

The way we prepare a system for a user is to cold start (pre-launch) the applications when the system starts. We do this by starting and then terminating each process, such as winword.exe.

Read more

ESRI ArcGIS Pro and Desktop License Type and Program Selector User Interfaces

Updated 17th July 2024

Here are two awesome User Interfaces (UI’s) I built that will compliment any ESRI ArcGIS Pro (AGP) and/or ArcGIS Desktop (AGD) deployment. More specifically from my point of view, they have been developed with a Citrix Published Application, VMware Horizon, Remote Desktop, VDI and AVD deployment in mind, giving the users the ability to easily switch licensing types and launching the different programs and tools, making life much easier for them.

ArcGIS Pro Challenges

  • Changing the licensing is not as simple as it seems, especially when launching it as a published application. This is because you have to change it from within the program once launched; and then the program needs to restart for the new licensing type to work. What that means is that the ArcGISPro.exe process will terminate and restart. Whilst that happens a published application session may log itself off, as there are no processes running to keep it open. The code in this UI will manipulate the user registry values before starting ArcGIS Pro, and therefore setting the licensing type as required. I call this Self-Service by allowing the users to switch License Levels/Types on demand!
  • Having a single interface allowed me to integrate other tools and processes as requested by users over time that could all be associated with ArcGIS Pro. For example, users wanted an easy way to start File Explorer in the same session. Let’s make it easy for the users to do their work! That’s my job!
  • Update on 17th July 2024 for Python code changes I completed in back February:
    • Due to some corporate licensing challenges with ArcGIS Pro, the ArcGIS Pro License Selector has been updated for the following reasons:
    • It defaults to a Basic license, regardless of what you last used. If you need to use a Standard or Advanced license type, please select it before launching ArcGIS Pro. This behaviour can be changed back by using the AlwaysDefaultToBasic script variable as documented below.
    • I have added a “Reset Extensions” checkbox, that is selected by default. This will remove any Extensions you may have selected in your previous session, as the licensing for some of these Extension is also limited. You have the option here of deselecting it if you wish to continue to use previously selected Extensions in your new session. This behaviour can be changed back by using the AlwaysResetExtensions script variable as documented below.
    • Unfortunately, neither of these settings are managed by ESRI at an enterprise level, so I’ve enhanced this tool to assist in reducing the usage of the more advanced licensing options.
    • I have also improved the flow of the Python code.

ArcGIS Desktop Challenges

  • In a large enterprise deployment, setting the licensing model can be a pain. This is done via a user environment variable. So you could use Group Policy Preferences to target them based on AD Security Groups. But that adds an administrative overhead, and users must then log support tickets via the Service Desk, which creates unnecessary overhead and lost time whilst they wait for it to be actioned. That’s not agile, and doesn’t allow users to change their license type to suite their needs. The code in this UI will manipulate the user environment variable before starting the ArcGIS Desktop program of choice, such as ArcMap or ArcCatalog, and therefore setting the licensing type as required. Again, I call this Self-Service by allowing the users to switch License Levels/Types on demand!
  • There are way too many Start Menu items to publish, which is not a neat and tidy way to present it, so why not just present it via a single UI?
  • Having a single interface allowed me to integrate all the common ArcGIS Desktop programs and other tools and processes as requested by users over time that could all be associated with ArcGIS Desktop. For example, users wanted an easy way to start File Explorer in the same session, and they wanted a way to install specific Python modules that are not part of the default Python install. Again, let’s make it easy for the users to do their work! That’s my job.
  • ArcGIS Administrator notes:
$acl= get-acl -path "HKLM:\SOFTWARE\Wow6432Node\ESRI"
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
$rule=new-object system.security.accesscontrol.registryaccessrule "USERS","FullControl",$inherit,$propagation,"Allow"
$acl.addaccessrule($rule)
$acl|set-acl
 
$acl= get-acl -path "HKLM:\SOFTWARE\Wow6432Node\Classes\CLSID\{E6BDAA76-4D35-11D0-98BE-00805F7CED21}"
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
$rule=new-object system.security.accesscontrol.registryaccessrule "USERS","FullControl",$inherit,$propagation,"Allow"
$acl.addaccessrule($rule)
$acl|set-acl

Read more

XDPing C# Function

I wrote this C# (csharp) function back in 2020 when developing the Self-Service Session Reset Tool. I have since enhanced it for improved error checking and logging and am happy to share it here for anyone else who wants to leverage it. I released a PowerShell version back in 2019. I like to integrate these functions into the scripts and tools I create as part of the health checks I do. I believe that by checking that the Broker’s Registrar service is reachable, listening and processing requests on its configured port, we can only then assume it is in a healthy state.

Read more

Citrix Self-Service Session Reset Tool Process Flows

***Updated for the release of v1.6.

There are eight (8) main process flows for the how the Citrix Self-Service Session Reset Tool works:

  1. User Opens Web Page Process Flow
  2. Get Sessions Process Flow
  3. Logoff Sessions Process Flow
  4. Disconnect Sessions Process Flow
  5. Restart Machines and Forcefully Restart Machines Process Flow
  6. Hide Sessions and Unhide Sessions Process Flow
  7. Get Processes Process Flow
  8. Terminate Processes Process Flow

Each flow is documented and visually represented below.

Read more

Citrix Self-Service Session Reset Tool

***Please refer to my article on Development Planning for the Citrix Self-Service Session Reset Tool to learn about what updates and new features are being worked on.

***If using a release less than v1.9, please refer to the release history below to understand the new features, enhancements and fixes now included.

This tool has been labelled as a game changer for any Citrix customer. It’s proven time and time again that it has a huge impact on reducing the burden on the Service Desk and Operations Teams by empowering users to get themselves back up and running in the shortest possible time.

No matter how stable your Citrix platform is, one of the biggest challenges for any Citrix customer is being able to reduce Service Desk calls and user downtime by empowering users with the ability to clear their own sessions, or recover them by terminating rogue processes. Several free scripts and a paid for tool are available, but none of them really achieve the best outcome. Some of them still require users to run a “Citrix session”, which they often can not do because the broker may be trying to reconnect them back to a stuck, hung, broken session or unhealthy host. When this happens they get into an endless loop of failure and get very frustrated. This can impact brand reputation and user satisfaction, leaving users with a poor felt experience. Some have even implemented a separate Citrix Environment to run these scripts from. In my opinion this is as waste of resources and an overhead for management. It still doesn’t always work due to Citrix Workspace (Receiver) reconnection issues and is often over complicating it for users.

My goals were to:

  • Create a tool that is easy to use, even for users that struggle with technology.
  • Create a tool that enables users to not only get themselves back up and running in the shortest possible time, but also reduces the reliance on Service Desk and even second level support teams.
  • Create a tool that does not rely on any ICA/HDX connectivity to a Citrix platform. This was extremely important!
  • Create a tool that would allow support for multiple Citrix Virtual Apps and Desktops (CVAD aka XenApp and XenDesktop) Sites.
  • Create a tool that works across trusted Domains.
  • Create a tool that works across the IT and OT landscape.
  • Create a tool that can easily be extended/expanded for other use cases.
  • Create a tool that’s modular so that other brokers such as VMware Horizon and Leostream can easily be added.
  • Create API’s with a Web front-end.
  • Create a tool that can be used to develop a microapp.
  • Create a tool that can easily be called by any scripting language such as PowerShell and Python.
  • Create a tool that can be enhanced, debugged and supported by others.
  • Create a tool for the community, because I love doing that!

Read more

Citrix Virtual Delivery Agent (VDA) Post Install Script

Updated 18th July 2025

Whilst some of these items can be excluded from the Virtual Delivery Agent (VDA) installation, checking and managing them in a post install script ensures we have consistency between all installations and VDA versions. All these actions need to take place in the base image, hence why they are managed in a script and not via Group Policies. This script has been built from years of lessons learnt and developing best practices. It will…

  • Disable the Telemetry Service
  • Disable the VDA Ceip Service
  • Disable the CtxAppVService (from 7.14 to 7.15 CU4/1906)
  • Disable the App-V Package Cleanup (from 7.15 CU5/1909)
  • Disable the Smart Card Services and Launcher
  • Implement the Citrix Desktop Service (BrokerAgent) Scheduled Task
  • Configure the UviProcessExcludes
  • Configure the CtxHooks
  • Configure the UPMEvent
  • Update the BrokerAgent.exe.config file
  • Enable the SaveRsopToFile registry value if it exists

Read more

Best Practice for the Windows Client Side Caching (CSC) kernel driver in VDI workloads

It’s been a best practice for a long time to disable Offline Files in both RDSH and VDI workloads. However, this has only ever been based around the Offline Files (CscService) service and some registry tweaks.

What people don’t realize is that you must properly disable Offline Files in all VDI workloads by also disabling the Windows Client Side Caching (CSC) kernel driver as outlined by Ned Pyle here.

Even with the Offline Files (CscService) service disabled, the Windows Client Side Caching (CSC) kernel driver is still loaded at Windows startup, creating unnecessary noise and potentially impeding performance when users access a network share.

The following example is a screen shot of Process Monitor monitoring a zpaq64.exe process extracting a file to a network drive. Note how it’s continually attempting to access the CSC (Client-Side Caching) area before the network share, even though Offline Files is disabled. This creates a large number of NAME NOT FOUND errors, and adds a potential delay to the execution time.

Read more

Best Practice for the Windows Time (W32TIME) Service for RDSH and VDI workloads

When using image deployment mechanisms for RDSH and VDI workloads, such as Citrix PVS, Citrix MCS and VMware View Composer, it’s extremely important to reconfigure the Windows Time (w32time) Service to ensure that the LastBootUpTime is accurate. If it’s not accurate, it effects monitoring, the correlation of log data, event triggers, etc.

The default Manual trigger of the Windows Time service is based on domain membership, which seems to cause issues as the image boots and changes name to the correct target name. Without having a deep enough understanding on the inner workings of these technologies, I can only assume that the default trigger of the Windows Time service is not compatible with the way the imaging mechanisms work on boot up to change the computer name and join to an Active Directory computer object. There may be a point during startup where Windows detects that it’s not domain joined and therefore stops the Windows Time service, which seems to throw the time out.

Read more

XDPing PowerShell Function

I wanted to write valid PowerShell function to do an XDPing the same way Citrix do with their Health Assistant tool. I was struggling a little to get the PowerShell code working as expected, so in the end I used the JetBrains dotPeek .NET decompiler to decompile the VDAAssistant.Backend.dll, which is a component of the Citrix Health Assistant Tool. This allowed me to reverse engineer and understand how Citrix does it in C# .NET, which is then easy for me to convert to PowerShell. Yeah…okay, so I cheated at little 😉 I also released a C# (csharp) function I wrote back in 2020.

I used this PowerShell function in two scripts:

To test if the Broker service is reachable, listening and processing requests on its configured port, you can issue blank HTTP POST requests at the Broker’s Registrar service, which is located at /Citrix/CdsController/IRegistrar. If the first line displayed/returned is “HTTP/1.1 100 Continue“, then the Broker service responded and is deemed to be healthy.

Read more

Controlling the Starting of the Citrix Desktop Service (BrokerAgent)

UPDATED 17th November 2025

  • Improved the check for the Personality.ini and MCSPersonality.ini files based on the history of VDA changes.
  • Replaced the Get-LastBootTime function with the Get-UpTime function. This starts to phase out the reliance on the Get-WmiObject cmdlet, with preference to use the Get-CimInstance cmdlet.
  • Added a group policy update (gpupdate) to be invoked before it reads the VDAHelper registry values. I’ve
    found this hit and miss with MCS images. So a gpupdate helps to ensures that the registry values are in
    place.
  • Added a check to see if it is a Citrix MCS Master Image. The script will check the following value:
    Key: HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\Configuration
    Type: DWORD
    Value: MasterImage
    Data: 1
    This is important so that it starts the Broker service immediately so that it does not cause any issues
    with the image preparation process.

UPDATED 21st July 2025

  • Added extra error checking and further improved the coding
  • When we set the Winlogon DefaultDomainName value we also need to set AutoAdminLogon value to 0 and clear the DefaultUserName value.
  • If the Winlogon AutoAdminLogon value is 0 (disabled), and the TriggerOnTaskEndEvent is set to 1 (enabled), we change the TriggerOnTaskEndEvent to 0 (disabled). This reduces unnecessary further delay waiting for an event that will never run.

UPDATED 14th July 2025

  • Replaced the Get-DeliveryControllers function with the Get-ListOfDDCs function. The name of the function may have been misleading given that it’s for both Delivery Controller or Cloud Connector addresses. It now allows for the C:\Personality.ini and C:\MCSPersonality.ini for MCS deployments.
  • Added the UsePersonalityini value to the VDAHelper registry values, which is used to call the updated Get-ListOfDDCs function.
  • Updated the XDPing function
  • Changed the flow of some of the code

UPDATED 31st January 2023

  • Added the DefaultDomainName value to the registry, which tells this script to set the Winlogon DefaultDomainName value in the registry once the autologon process has started. This allows us to use a local account for the Autologon process instead of a Domain service account, which won’t work if the Winlogon DefaultDomainName value has already been set to your preferred domain. This reduces the security footprint when using service accounts by allowing us to easily rotate passwords using a local account for the autologon process for each image build. Refer to my article Priming a Non-persistent Windows Image using an Autologon Process with an Auto Logoff Timer to understand how this works.
  • You can now use the policies registry key for the registry settings:
    • Policies Key: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Citrix\VDAHelper
    • Preferences Key: HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\VDAHelper
    • Values set under the Policies key have a higher priority.

UPDATED 30th April 2022

  • Improved the code so that the logon/logoff events are detected more efficiently across all Windows Operating Systems.

UPDATED 17th March 2020

  • Enhanced the checking for the ListofDDCs registry value by also checking the Policies key structure.

UPDATED 18th July 2019

  • The creation of the Scheduled Task needed for this script can be found in the Citrix Virtual Delivery Agent (VDA) Post Install Script. It’s important that the priority of the Scheduled Task is set to normal to prevent it from being queued.
  • Enhanced the Get-LogonLogoffEvent function for backward support of Windows 7/2008R2

UPDATED 16th May 2019

  • Added much more logging with timestamps to help debug issues and correlate events. You’ll see from the screen shot of the log file below that it’s now quite comprehensive.
  • Ensured that the format of the logging timestamp and LastBootUpTime were aligned so that its accuracy can be easily verified as I documented here.
  • Added an XDPing function I wrote to health check the Delivery Controllers.

This is a process I’ve been working on perfecting for a couple of years now. I’ve got it to a point where it works perfectly for my needs, and has been very reliable over the last few months, so I decided it was ready to release to the community.

The challenge has always been that as a Session Host boots up the Citrix Desktop Service (BrokerAgent) starts and registers with the Delivery Controllers before the boot process is complete. Therefore, a user can potentially launch an application/desktop during the tail end of the boot process. When this happens it may fail the session launch, which can leave the Session Host in an unhealthy state, such as a stuck prelaunch state, with the user potentially needing to involve the Service Desk to clear the issue. So managing the timing of the start of the Citrix Desktop Service (BrokerAgent) is extremely important to ensure that your Session Hosts have completed their startup process before registering with the Delivery Controllers. This can be easier said than done!

To add to this complexity, power managed Workstation OS pools can get into a reboot loop if you use an autologon process. I use an autologon process similar to what George Spiers documented in his article “Reduce Citrix logon times by up to 75%“. So if the Session Host has registered with the Delivery Controllers before the autologon process has logged off, the logoff process will trigger another reboot. This can become a real problem to manage.

Read more