The Citrix Self-Service Session Reset Tool is software that I write and manage in my own time on my lab equipment. It is often challenging to find the time to work on it as I have many projects on the go. And life in general often gets in the way. I get a lot of queries asking me when the next release will be available and if the feature they are looking for will be included. Rather than continually updating the main article, and responding to queries, I wanted to document where the project is at and what further work is to be completed.
Version 1.9 was the last public release back on 1st June 2022.
Why not ditch my APIs and use the Citrix Virtual Apps and Desktops REST APIs that are now included with on-prem Delivery Controllers from version 2209 or later?
I work in the Mining Industry where we have OT (Operational Technology) networks, also known as PCN (Process Control Network). This is a typical setup within the mining, oil and gas industries, as well as utilities such as water and electricity. Some have their own AD domain with no trusts. But they all typically have a separate Citrix Site due to risk mitigation and change management requirements, and what we refer to in the mining industry as “site survivability”, meaning that a mine site can keep running when all comms links are lost. At the time of writing this, many of these sites are still 2203 LTSR or lower. Until these platforms have been upgraded to 2402 LTSR or later, I cannot leverage the built in Citrix APIs, and will continue to leverage the PowerShell SDK that my APIs are built on. Apart from that, I also wanted to be inclusive and did not want to place others at a disadvantage that are still running older versions.
If you are running 2209 and above on-prem, or just using Citrix DaaS (Cloud), the APIs are there for you to leverage. So all you need to do is create a cool user interface (UI) using a Blazor Server Application.
HOWEVER, I have since found limitations with the CVAD APIs, especially for on-prem. The Citrix Product Manager has suggested that I should be continuing to use the PowerShell cmdlets for the foreseeable future, as the CVAD APIs are not expected to be “production” ready for some time.
I have also found a interesting change in the Citrix PowerShell SDK authentication, so will make the code changes to address that.
I’m working on the following before the next version can be publicly released, which I’m planning for June 2025 early to mid 2026:
- Update project from .NET 4.5.2 to 4.8 and all packages to align where possible
- Securing the Citrix Cloud API secret information in the CtxSites.xml file
- JavaScript Bug
- Language localization via browser detection
- Dark Mode
- UI accent colours
- Convert CreatePipeline() API to [PowerShell]::Create()
- Refactor Code
- Citrix PowerShell SDK authentication change
I then plan on doing another small release with the following changes:
- Add CIM/WSMan methods that can be leveraged instead of WMI/DCOM for the Get and Terminate processes methods.
- Enable/Disable Maintenance Mode API
- Citrix PowerShell SDK Bug
- Citrix PowerShell SDK Max Record Count Limits
- Refactor Code
- Using Serilog sinks for Syslog output, etc.
The following are larger changes that will take time to complete:
- Update project from .NET 4.8 to .NET 10, which is a Long-Term Support (LTS) release
- New Blazor User Interface
- Help Desk Version (may not be a free product)
- Refactor Code
Securing the Citrix Cloud API secret information in the CtxSites.xml file
From a Cyber Security requirements point of view, Customers would like the API secret information further secured. I came up with the the following by adding 4 properties to the web.config file.
- Reverse the Citrix Cloud strings. If your client secret is 12345, it would become 54321
- Then Base64 encode it. So 54321 would become NTQzMjE=
- We can further encrypt it with AES-256-CBC. One of the Web.Config properties will be the AES key used for the encryption. The same key is required for the decryption process. If your Base64 encoded string is NTQzMjE= and your AES encryption key is is QGTD7PzVHugV5dX9Nsi9POKzyoyuCgJSt8mzSvpFT5s= , the client secret would be IteE80vJuHTY/wZduQP0/zkl990NEbpfuPOKuzkVBKw=
These settings will be in a separate section of the Web.Config so that we can encrypt that by using the aspnet_regiis.exe command line tool.
In a future build I could get adventurous and leverage OpenBao, which is an open source, community-driven fork of HashiCorp Vault.
JavaScript Bug
I believe I’ve found a bug with the version of jQuery I’m using in the SSSRT. Sometimes the SSSRT doesn’t initialise correctly in Edge and Chrome (the only browsers I’ve tested). We only see the logoff option. And when a user tries to logoff a session, it doesn’t work. It would be related to the fetch with an async await section. Perhaps a timing or race condition. I’m changing the code around a bit to see if I can address it formally. As I’m unable to make it fail, it will be difficult to know if the issue has been addressed without ongoing feedback.
Convert CreatePipeline() API to [PowerShell]::Create()
The CreatePipeline() API is informally deprecated. I am changing the code over to use [PowerShell]::Create() instead with an associated runspace. The new API is cleaner, more fluent, and is the recommended approach for PowerShell usage in modern .NET applications. A runspace is created by each of the main methods; GetCurrentSessions, LogofforDisconnectSessions, RestartMachines and HideSessions. It is passed ro other methods and contains critical information such as the loaded Citrix snap-in (Citrix.Broker.Admin.V2), authentication credentials from XDAuth(), and session state information.
Refactor Code
There is also quite a bit of code clean-up I want to do. However, refactoring is a continual job, so this will be completed gradually over the next few releases.
Enable/Disable Maintenance Mode API
I had added the code in readiness for the Help Desk version.
I will probably also leverage this API functionality for a separate tool I’ve created called the Computer Restart Service. The VDA’s don’t have the smarts to place themselves into maintenance mode using the good old “drain mode” process locally, so the Computer Restart Service that will run on the VDA’s will have the smarts to use this API to do just that.
Citrix PowerShell SDK Bug
I was working on the code for the Help Desk version some time ago, when I found a bug in the Citrix PowerShell SDK.
When using the Get-BrokerDesktopGroup and/or Get-BrokerCatalog cmdlets from the SDK and connecting to a 7.15 Delivery Controller, the Scopes property is returned with no objects! However when running these locally on the Delivery Controllers the output is correct. Connecting to 1912 and 2203 Delivery Controllers do not present such an issue. When I was working on this, my customer at the time still had 18 sites on 7.15, so I wanted to allow for that backward compatibility. The reason behind this was to use the scopes to allow me to delegate remote management of the Session Hosts through my tool, without using Director. This would make it easier for supervisors/team leaders/line managers to clear sessions holding files and licenses open when people go off-shift or go on R&R (Rest and Recreation/Recovery) without clearing all their session. This is a problem in a mining company where the platform is used 24×7.
I burnt many many hours on this before realising that it was a bug and escalating to Citrix.
After an investigation Citrix found that the ScopeReference is defined in a different namespace between 7.15 and 1912. They actually moved it to a different namespace without thinking, which broke things! So when the broker service sends the response, the PowerShell client side can not deserialize properly, thus it gets a null value for Scopes for Get-BrokerDesktopGroup and Get-BrokerCatalog. As Citrix had made significant changes to the PowerShell modules, this was unable to be fixed/reversed.
Thankfully the workaround is to use the Get-BrokerScopedObject to get Scope name. It’s a bit more messing about with code, but it works.
However, given the amount of time that has passed and with 7.15 being out of support, I may just continue on with the Get-BrokerDesktopGroup cmdlet and not be concerned about backward compatibility.
Citrix PowerShell SDK Max Record Count Limits
Even though Citrix reneged on their Announcing Remote PowerShell SDK Record Limits and will no longer implement changes to impose SDK record limits, they still strongly encourage every customer to use filtering or a reasonable MaxRecordCount. They state that their data indicates that customers with the best response times have MaxRecordCount less than 5000. Citrix do not provide pagination on the returned data, so there is no way to know how to get the next page between the MaxRecordCount and the ReturnTotalRecordCount parameters. Therefore, I’ve re-written the usages of Get-BrokerSession to make them more efficient.
Language Localization
Using the i18next JavaScript framework, I was able to create the functionality so the text instructions can be pulled from a language translation files based on the Web Browser language settings. This was very challenging, but I did eventually get it working well and have French and German language translations ready to go. Adding new language translation files is simple thanks to your favourite AI tool of choice. It’s just a matter of providing the English Translation.json file to AI and asking it to create a new language file of your choice. I am only testing left to right languages at present. So the next release will bring in language localization via browser detection, but will always fall back to English.
Dark Mode
When I got this tool up and running for a new customer the first thing they asked was “How do I enable dark mode?”. I had never thought about it previously, but felt it was a good idea.
UI accent colours
Being able to change the background and text colours for certain areas will make it easier to brand with the main company colours. So I will add properties to the Web.Config for this.
New Blazor User Interface
After fighting too many unexplained JavaScript and jQuery challenges, and inspired by Dave Brett’s PROFiLiX Server project, I have decided to move the interface to Blazor, which will offer a modern rich interactive user experience. I’ve been super impressed with version 8 and above. All the work I’ve completed for the JavaScript framework will not go to waste as it was a huge learning curve for me.
The plan is to build the Blazor interface so that it leverages my own APIs as well as the Citrix Virtual Apps and Desktops REST APIs.
Help Desk Version (may not be a free product)
As mentioned under the Citrix PowerShell SDK Bug section, I’m working a Help Desk version that will use the Scopes against Delivery Groups to allow groups of people like Help Desk, Team leaders, Line Managers and Supervisors to clear sessions on behalf of others.
This should cover off all the requests I’ve had, including changes I’ve been wanting to make for some time.

