Citrix Receiver Per-User Install Cleanup

For years Citrix has created the Receiver installer with per-user installation functionality where if the installer is launched in the context of a regular user it will install/register the components to the local user’s profile rather than just failing with a permission error. This creates a huge headache when trying to mass deploy Receiver (now Citrix Workspace) to the environment. You wind up with machines that have both installed. When this happens the user that had the per-user installation cannot launch applications. Even worse the machine/profile usually winds up being in a state where the per-user installation cannot be removed. Even if you get it removed the uninstaller and Citrix’s own cleanup utilities do an awful job at cleaning up the registered classes/components in the per-user installation. Their tools only clean up a fraction of what is actually there. My last two work environments (and current) have been plagued with these installations. I spent time a while back figuring out how to clean it up manually, but it is a major headache to do so. I tried logging a case (and an enhancement request) with Citrix about two years ago stating their Receiver Clean-up Utility utility does not properly clean up these installations. They later came back saying they no longer are supporting the utility. It seems that since then they’ve updated the utility to clean installs up to version 4.3.

Let’s take a look what Citrix is missing in their utility… To do this I take a clean profile, install Citrix Receiver 4.3.100 (not elevated/per-user install), and uninstall it using the Receiver Clean-up Utility (running as an administrator/elevated) while the regular user is still logged in and has their profile loaded. Here is a high-level list of what was left behind in the registry:

  • HKCU\Software\Classes\* – File Associations and COM object registrations
  • HKCU\Software\Classes\AppID\* – AppID registrations
  • HKCU\Software\Classes\Applications\* – More app registrations
  • HKCU\Software\Classes\CLSID\* – MANY COM class object GUIDs
  • HKCU\Software\Classes\WOW6432Node\CLSID\* – MANY COM class object GUIDs (32-bit)
  • HKCU\Software\Classes\Interface\* – MANY interface name to interface ID mappings
  • HKCU\Software\Classes\WOW6432Node\Interface\* – MANY interface name to interface ID mappings (32-bit)
  • HKCU\Software\Classes\MIME\Database\Content Type\* – x-ica MIME types
  • HKCU\Software\Classes\PROTOCOLS\Filter\* – Protocol filter handlers
  • HKCU\Software\Classes\Record\*
  • HKCU\Software\Classes\TypeLib\*
  • HKCU\SOFTWARE\MozillaPlugins\* – Firefox plugin registrations
  • HKCU\Software\Microsoft\Installer\Products – MSI installer product codes

In addition to this there are other issues:

  • When it is run against a machine it doesn’t properly load other existing (unloaded) profiles. This caused it not to fully process other user profiles on the machine
  • It doesn’t always kill processes correctly leaving file/directories behind

I decided to build a wrapper script around the Citrix Receiver Clean-up Utility to fill in the gaps. To do so I had to create a full list of everything I had to target. I decided to extract the MSIs from the installer I was testing with and dissect them. I used SuperOrca to pull the ‘Registry’ table from each MSI. I imported those into Excel and used filtering/VLOOKUPs to extract what I needed.

After chopping up the data I am left with the following groups of items to target:

  • A static list of unique registry keys under the user’s profile (this is a good start, but I noticed that some of the IDs in CLSID and Interface are different between versions)
  • A list of values to search for under ‘HKCU\Software\Classes\CLSID’ in order to determine of the root key should be deleted. Also need to target the WOW6432Node path
  • A list of values to search for under ‘HKCU\Software\Classes\Interface’ in order to determine of the root key should be deleted. Also need to target the WOW6432Node path
  • A list of values to search for under ‘HKCU\Software\Microsoft\Installer\Products’ in order to determine of the root key should be deleted. The clean-up utility cleaned up most of this, but one was left over for me

Now that I have the targets it’s time to write the script. In addition to targeting the various registry locations I want to:

  • Identify and load all profile registry hives. This will allow me to run my clean-up process against all profiles, but it will also allow the clean-up utility to process them without the having to be logged in
  • Kill processes that reside in certain paths using wildcards
  • Execute the Citrix Receiver Clean-up Utility silently
  • Clean up a static list of registry keys in all user profiles
  • Search for a list of value strings under in the ‘CLSID’ keys and delete the parent key if a match is found
  • Search for a list of value strings under in the ‘Interface’ keys and delete the parent key if a match is found
  • Search for a list of ‘ProductName‘ value strings under in the ‘Installer\Products’ keys and delete the product key if a match is found
  • Unload all registry hives that were manually loaded in the first step
  • I also wanted the script to work with older versions of PowerShell. I did my best to make it compatible with PS V2

I have tested the script with multiple versions and so far it is working well. It does require that you download the Receiver Clean-up Utility and place the executable in the same directory as the script. Feel free to submit any issues here or in the GitHub repository.

GitHub link: https://github.com/markdepalma/CleanPerUserReceiverInstall

34 thoughts on “Citrix Receiver Per-User Install Cleanup

  1. Pingback: EUC Weekly Digest – February 16, 2019 – Carl Stalhood

  2. Kenneth Castelein

    Hi!

    Thanks for the script, very usefull.
    However in some situations we still have issues to reinstall the citrix receiver afterwards.
    Following citrix posts explains the issue :
    https://support.citrix.com/article/CTX212773

    It seems that there are still some keys in the HKLM.
    I don’t know if you have had this issue before, but is it something that perhaps could be included in this script too, you think?
    If I install for example the citrix receiver 4.9.5000 instead of the 4.9.4000 it installs without problems (because the GUIDS for those citrix components are different). If I try to reinstall the 4.9.4000 after running the script, it says that the receiver is already installed.

    Thanks in advance for your help.
    Would be very appreciated.

    Kenneth

    1. Mark DePalma Post author

      Thank you for this. I have run into the 1612 issue with various components before myself. The script uses the Receiver clean-up utility (in addition to its own clean-up logic) which usually cleans up the HKLM MSI product keys fairly well. I did add cleanup logic in the script for the Products key under HKCU since I saw one or two of those products keys getting left behind.

      Please test this use case with the script and let me know if you still come across this issue. I can definitely add this to the script if needed!

  3. Pingback: Citrix Workspace app 1812 – Carl Stalhood

  4. Pingback: Detailed Change Log – Carl Stalhood

  5. pkoziura

    Mark,
    I reported the same issue with user profiles not getting cleanup properly and got my case assigned to a good Escalation Engineer.

    There was a feature enhancement request submitted to the Development team and I provided the method to load the Classes user hives to clean up the user profile section. Citrix added this code to the Receiver Cleanup utility released in September 2018 version 2.3.0.42 .

    The tool now removes installs for all the users profiles.

    I’m curious now in the additional cleanup that your script does compared to the new released Citrix Receiver Cleanup Utility.

    Thanks

    Peter

    1. Mark DePalma Post author

      Peter,

      Thanks for commenting on this…

      First, I would like to say that this script actually works in conjunction WITH (and requires) the Citrix Receiver Cleanup Utility. The version of RCU that I was using at the time of development was actually 2.3.0.42. What I found with RCU was that it does make some attempt to clean other profiles, but it doesn’t always load them and it still misses a bulk of what I’m targeting in the script. This is also why my script actually loads all the profiles before kicking off RCU. This gives RCU the best chance of doing the most clean-up that it can possibly do. You could easily test RCU’s deficiencies by doing the following: install Receiver in per-user mode on a user’s profile, reboot (to clear any profile loads), log in as another user (who is an administrator), run RCU (elevated), install Citrix Receiver in per-machine mode, test Receiver under the original user’s profile. You will have issues with things like component registrations and will not be able to successfully launch an application. I was happy that they decided to update RCU (as they told me a while back they were no longer doing development on it when I tried submitting my own case/enhancement request), but it is still not sufficient for the per-user install use case.

      If you find something different or find any issues with the script please come to me with those items. I’d be happy to work with you on it.

      1. pkoziura

        Mark,

        The use case that you provided is what triggered contacting Citrix Support.
        The issue we experienced was a system level install of CR was already done via SCCM, Storefront is configured by default to install CR if its not installed on the client, well most users were running Chrome and Storefront was not able to properly search for the Receiver install because Google disabled the NPAPI plugin feature, therefore thousands of machines with both user and system level installs of wfica32.exe.

        So now we have set the Storefront server to never install the Citrix Receiver from Citrix.com.

        I have also seen cases with both user and system level installs of CR crashing on the wifa32.exe process.
        In addition to the RCU enhancement request, I have also requested that the Citrix Receiver installer never attempt to install in user-mode if a system level install is already present. Citrix Development team has changed this install check beginning with CR 4.12, 4.9.6000 LTSR (maybe even CU5) and CWA 18.12 to resolve this chaos.

        I would be interested in the delta changes of your script to see if maybe I can get those additional changes added into the RCU tool for the sake of all Citrix customers running into these issues.

        Nice Work on the script!!!

        Pete

        1. Mark DePalma Post author

          That is an interesting reason that per-user installs were happening in your environment. Yes, Receiver should NEVER install per-user if per-machine is present and I find it absurd that it doesn’t already operate that way. Another fix would be having the ability to disable per-user installs completely on managed machines. There is a GPO for it, but I believe it doesn’t really work. I attempted to set this a while back, but didn’t have success.

          Please, feel free to reference this post and the script to Citrix with you enhancement requests. I tried going that route years ago and had less success than you have had. I needed to create this script or the issue was going to haunt me forever.

          Thank you!

          1. pkoziura

            I also experienced that the GPO did not work to prevent user-based installs of CR and reported the issue to Citrix. Citrix tested it and confirmed it did not work.

            I like the new feature of a CR system level install has higher priority than a user-level install better than applying a GPO anyway.
            There is still the risk of a user-level occurs first, but with our Storefront servers modified to no longer install Receiver, the user would need to goto Citrix.com and install as a non-admin for this to happen.

            Here is some more details from a forum post last year that I responded to another user experiencing the same issue with user-level installs of CR.
            https://discussions.citrix.com/topic/392010-disable-non-admin-user-from-installing-citrix-receiver-410/#comment-2007429

            I’m almost positive that this issue of both system-level and user-level installs of Citrix Receiver is impacting most Citrix customers since Storefront defaults are set to install the Citrix Receiver if not present.

            Steps for your blog visitors: (Curious on their responses: System-level Only, User-level Only or both System-level and User-level installs)
            The best way to check is logon to a workstation as admin and open a command prompt, make sure your at the root c:\ drive and type: C:\dir /s wfica32.exe

            Check if you have both installs in C:\Program Files directory (System level install) and in users profile C:\user\*.* folders (User-level install)

            I’ll test out your script and take some registry snapshots before and after and review the delta info.

            Thanks,
            Peter

  6. pkoziura

    Mark,
    I reviewed you script and have some suggestions on some updates to the script.

    I’m assuming the script address’ the HKCR section of the registry, looks like your searching the global registry structure correct?

    Above Kenneth post a link to https://support.citrix.com/article/CTX212773
    The article mentions to delete Key Name: HKEY_CLASSES_ROOT\Installer\Products\[GUID]

    I have found some items related to Citrix Receiver buried in HKCR section.

    Also, in your script I see the following static registry entries:
    Software\Classes\Citrix.ICAClient
    Software\Classes\Citrix.ICAClient.2
    Software\Classes\Citrix.ICAClient.2.1
    Software\Classes\Citrix.ICAClient.2.2
    Software\Classes\Citrix.ICAClient.2.3
    Software\Classes\Citrix.ICAClient.2.4
    Software\Classes\Citrix.ICAClient.2.5
    Software\Classes\Citrix.ICAClient.2.6
    Software\Classes\Citrix.ICAClient.2.7
    Software\Classes\Citrix.ICAClient.2.8
    Software\Classes\Citrix.ICAClient.2.9
    Software\Classes\Citrix.ICAClientProp.2
    Software\Classes\Citrix.ICAClientProp.2.1
    Software\Classes\Citrix.ICAClientProp.2.2
    Software\Classes\Citrix.ICAClientProp.2.3

    I have seen new entries 2.10 & 2.11 created in more recent builds of CR.
    Based on CTX325140, I would recommend using a wildcard to tag new entries in newer builds.

    I.e Delete Citrix.ICAClient* and Citrix.ICAClientProp* to cover the newer value being created.

    Using Registry Editor, navigate to the HKEY_CLASSES_ROOT key and delete the following keys if they exist:

    Citrix.ICAClient* (delete all instances that exist – such as Citrix.ICAClient.2 or Citrix.ICAClient.2.1)
    Citrix.ICAClientProp* (delete all instances – such as Citrix.ICAClientProp.2 or Citrix.ICAClientProp.2.1 might exist)
    ica
    In the CLSID key, delete any keys whose names begin with 238F

    Pete

    1. Mark DePalma Post author

      Yes, I see this. Other items in there are hard coded in that array, but then later have more intelligent detection later in the code. This one needs some tweaking to catch variations. I will add this soon.

  7. PeterK

    I was needing just that GPO setting to disable per-user installs but it appears to have been removed in Workspace App 1904.1. I see it in Citrix Receiver v4.12 GPO settings under Client Engine->Allow Per-User install but wouldn’t you know it’s gone now. Can someone please confirm this? Anyone come up with any other ideas to prohibit per-user installs? This is getting to be a real problem in our environment. Thanks.

  8. fcray

    Mark,
    Not being a powershell whiz, unable to get the script to run on Windows 10.
    Getting this error:
    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks (“&”) to pass it as part of a string.
    I run as admin and even tried running under PSV2 with same result.
    I need a solution to the install-per-user issue as right now only option I can get to work is deleting the users local profile.
    Thanks,
    Fred

    1. Mark DePalma Post author

      How are you launching the script? It sounds like there is an ‘&’ in your commandline. There are no ampersands in the script itself.

        1. Mark DePalma Post author

          There is nothing that would do that on line 145. There is nothing that says “Sign up” in the entire script. How are you trying to execute this?

          1. ctxjuan

            We are opening the POSH window as admin, navigating to the dir, and running the PS1. Second time Im seeing it –
            C:\Temp\CleanPerUserReceiverInstall.ps1:151 char:21
            + Sign up
            + ~
            The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
            quotation marks (“&”) to pass it as part of a string.

          2. ctxjuan

            omg, it keeps deleting the actual line that I keep trying to place in here.. there’s some strange stuff around tha “&” if you open up the PS1… it in there, for sure.. 100%

  9. Chris Shearin

    Thanks for this. We continue to struggle with profiles being corrupted after several weeks of Citrix working. Our users consistently get the “not supported selected encryption” error after timing out launching ica file. I tried running this clenaup script through PDQ and local.

    Here is the error log (PDQ)
    Loading profile registry hives for username: xxxx
    Loading profile registry hives for username: xxxx
    Loading profile registry hives for username: xxx
    Loading profile registry hives for username: xxxx
    Loading profile registry hives for username: xxxx

    Running Citrix Reciever Cleanup Utility…
    ScriptHalted
    At C:\windows\AdminArsenal\PDQDeployRunner\service-1\exec\Error Handling Wrapper.ps1:58 char:2
    + Throw $_.Exception.ErrorRecord
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], RuntimeException
    + FullyQualifiedErrorId : ScriptHalted

    1. Mark DePalma Post author

      The wrapper that PDQ users is catching some error and failing. The fact that it is getting the error when trying to load the cleanup utility leads me to think that that is related. Did you download that utility and deploy it along with the script in the script location? If PDQ does not copy the utility along with the script it will fail. The cleanup utility EXE needs to be present wherever PDQ is launching the script from.

      1. Chris Shearin

        thanks Mark – I have the RCU in the same directory but I’m going to try to copy it along with the script.

        Also running into another issue while trying to run locally manually as domain admin:

        Execution Policy Change
        The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
        you to the security risks described in the about_Execution_Policies help topic at
        https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
        [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “N”): y
        Get-ChildItem : Requested registry access is not allowed.
        At C:\temp\CleanPerUserReceiverInstall.ps1:263 char:16
        + $LoadedHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {$_. …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : PermissionDenied: (HKEY_USERS\S-1-5-19:String) [Get-ChildItem], SecurityException
        + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.GetChildItemCommand

        Get-ChildItem : Requested registry access is not allowed.
        At C:\temp\CleanPerUserReceiverInstall.ps1:263 char:16
        + $LoadedHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {$_. …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : PermissionDenied: (HKEY_USERS\S-1-5-20:String) [Get-ChildItem], SecurityException
        + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.GetChildItemCommand

        Get-ChildItem : Requested registry access is not allowed.
        At C:\temp\CleanPerUserReceiverInstall.ps1:263 char:16
        + $LoadedHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {$_. …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : PermissionDenied: (HKEY_USERS\S-1-…2911268741-7756:String) [Get-ChildItem], SecurityEx
        ception
        + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.GetChildItemCommand

        1. Chris Shearin

          nevermind – I needed to brush up on my PS skills —
          I think I’m getting what I need now bust just FYI – I am getting this error only now:

          Running post-RCU registry cleanup for username: bradleyw-a
          Unloading profile registry hives for username: bradleyw-a
          reg : ERROR: The parameter is incorrect.
          At C:\temp\CleanPerUserReceiverInstall.ps1:349 char:3
          + reg unload HKU\$($Profile.SID) | Out-Null
          + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo : NotSpecified: (ERROR: The parameter is incorrect.:String) [], RemoteException
          + FullyQualifiedErrorId : NativeCommandError

          1. Mark DePalma Post author

            Ah, so this is error is fine. The script just couldn’t unload your ‘bradleyw-a’ account in the registry at the end. It is ok to ignore that error. I have the script try to clean up all the registry hives it manually loaded for the per-user clean up.

  10. thefinder808

    Really appreciate the script, I really don’t understand why Citrix themselves can’t get this right. For some reason when I run the script it is getting stuck at
    “Running Post-RCU registry cleanup for username: myusername”.
    It seems as though something changed recently, I’ve been using and testing the script for several weeks and this just started happening. It still works, and deploying via SCCM the timeout is set to 15 minutes, but wanted to see if you knew why it seems to be stalling out on that step.

  11. thefinder808

    No, it just stops there until I terminate the process. At the very end of the script I have it run the install for Workspace 2006. What’s odd is that the installation actually happens and completes fine, but the script is still sitting at that Running Post-RCU step in PowerShell. Can’t figure it out.

    1. Mark DePalma Post author

      Does it stop on a certain user? This happens on multiple machines?

      There are already a number of commented “Write-Host” lines below that line. To help narrow it down you could UNcomment all of them and see where the script hangs.

      1. thefinder808

        Good idea, it seems to quit on this line:
        Microsoft.PowerShell.Core\Registry::HKEY_USERS\\Software\Classes\WOW6432Node\CLSID\{e3dfd9c3-d58e-4c55-9083-083d97eb8144}

        It is happening on my admin account (which is the same account I’m running the script from), but then again I only have two accounts to test with so it’s hard to say if that’s a coincidence or not. I checked the registry after the script got stuck there and that regkey doesn’t exist, so it seems to have gotten deleted already or never existed.

Leave a Reply