Microsoft Teams on Citrix Virtual Apps and Desktops, part #1 – installing the damned thing

Microsoft Teams has risen quite emphatically to prominence over the last six months or so. The reason for this is twofold – primarily, to do with the explosion of remote working that has occurred as a response to the COVID-19 pandemic, and also with the coincidence of the Skype for Business retirement date in August of 2020. This has resulted in many Citrix administrators having to deploy Teams into their Virtual Apps and Desktops environments – often quite rapidly.

Teams is Microsoft’s primary Office365 collaboration tool and is written in Electron, which makes it a bit of a pain to manage, like other Electron apps. An important point to make about Teams is that it cannot be run on-premises – it requires a cloud or hybrid model. This is because Teams hooks into Sharepoint Online, Exchange Online and Office365 Groups to drive the Teams experience. Exchange Online is the most important component to have so that your users can access the full features of the Teams product.

With Skype for Business running out of support and a huge percentage of the enterprise workforce now mandated to operate remotely, delivering Teams into Citrix environments suddenly became hugely important. But we didn’t just have to get it up and running – we had to get it up and running well. Video and audio (particularly video) were suddenly hugely important. For a lot of people, remote working is a huge cultural shift, and providing excellent collaboration facilities with the ability to interact directly with other humans is vitally important. The provision of realtime interaction is crucial – because drops in quality lead to disjointed contact, and for workers who are isolated from their colleagues, this can make a huge amount of difference. Indeed, the importance of top-quality video and audio isn’t just a business benefit to aid productivity any more, we’re actually potentially talking about people’s mental health and general happiness.

But what issues do we have putting Teams into a Citrix Virtual Apps and Desktops environment? I’ve had to divide this article into a very short series, unfortunately, so here’s the first instalment – dealing with installation.


Let’s start at the beginning, and arguably one of the trickiest parts of getting to grips with Teams – actually installing the damned thing.

Firstly, don’t use the Click To Run installer to install Teams, and make sure that you install the VDA prior to doing the Teams install. You can find the proper MSI installers at these links:-

32-bit Teams MSI install

64-bit Teams MSI install

The installer needs to be run with certain switches, so it should be called from msiexec (whether this is manually, or through some form of software deployment mechanism, is entirely up to yourself). The two switches you need to be concerned with are ALLUSER and ALLUSERS.

ALLUSERS simply means that an entry will be written into Programs and Features allowing the program to be uninstalled directly.

ALLUSER means that the automatic updater will be turned off, and this is crucially important for non-persistent and RDSH environments. Without this you will receive updates into multi-user or non-persistent environments and you will see a lot of problems.

If you are fully persistent – so for instance, using Teams on one-to-one machines where the user’s profile is stored locally – then you can get by with simply using the ALLUSERS switch on the installer, as below

msiexec /i <path_to_msi> /l*v <install_logfile_name> ALLUSERS=1

If you are on any other form of environment other than fully persistent, then use both switches to ensure you don’t lose control of updates to your images

msiexec /i <path_to_msi> /l*v <install_logfile_name> ALLUSER=1 ALLUSERS=1

Now, onto the nitty-gritty. The Teams installation doesn’t really go into Program Files or Program Files (x86), no matter what you do. Teams is an installation that lives in the user profile, period. Microsoft’s “Machine-Wide Installer” allows you to control on which devices the user-based install is initiated, but that’s it. However, the executable that controls Teams initiation is part of this install, so in order for a user to launch Teams, you have to have run the Machine-Wide Installer. So essentially, when you “install” Teams you are simply allowing the user to launch the app – the rest of the gubbins is buried in the user profile. The files that the Machine-Wide Installer drops are simply a “stub” that allows the app to be launched and the user-based install to commence.

Let’s run through this process just for posterity (we have assumed an x64 target system – if you’re on x86 the filesystem and Registry paths will be slightly different).

Teams installer is run with switches

Files are written to c:\Program Files (x86)\Microsoft\Teams

Registry value written at HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run that points to c:\Program Files (x86)\Microsoft\Teams\current\Teams.exe

Shortcut written to c:\Users\Public\Desktop that also points to c:\Program Files (x86)\Microsoft\Teams\current\Teams.exe

Shortcut written to C:\ProgramData\Microsoft\Windows\Start Menu\Programs

Uninstall entry written into Programs and Features or Apps and Features

Once this has completed, the next stage of “installation”, as it is, is triggered when the user logs onto a device that has the Machine-Wide Installer on it.

  • User logs on
  • Registry value in HKLM starts Teams.exe from the Program Files folder
  • Approximately 10MB of files are created in %APPDATA%\Microsoft\Teams
  • User is prompted for sign-in (or sign-in happens via pass-through)
  • Teams UI launches and begins initial setup
  • A further 5GB (approximately) of files are created within the user profile (most of which are deleted as part of this stage), session resource consumption spikes

Once initial setup and sync is completed (dependent on user setup), Teams is now fully “installed” into the user’s profile and this process will not need to be run again, as long as other devices the user accesses have Teams available and are using the same profile. Approximately 700-900MB of space in the profile is consumed by Teams data once this is completed (dependent on environment – this may be higher).

If you uninstall Teams, this simply removes the Machine-Wide Installer from the device – but what it also does is remove the executable that the users use to launch Teams (as well as the shortcut in %ALLUSERSPROFILE% that points to it). So despite having it still in their user profile, there’s no way for them to actually run the Teams client. However, it does mean that if they log onto a machine that does have the Machine-Wide Installer on it, they will not need to go through the first-run setup for a second time.

Teams does leave some remnants behind – mainly some device-specific filesystem entries

and a few logs and other folders in the profiles of users who may have launched Teams. As mentioned earlier, it is up to you whether to keep the profile-based entries (so that a user does not need to run the initial setup again), or to remove them entirely (usually would be done if you are trying to fix a Teams-related error that is tied to the user).

You can clear all this stuff up manually, or you can use some of the cleanup scripts that are out there (CTA Manuel Winkel has a good one here).

One final note to make about installation is that when you upgrade to a new Teams version, you must uninstall the old version fully before installing the new one. If you start every new build with a brand new image, then this isn’t an issue, but if you are simply making changes to an existing golden image (like you often would with MCS or PVS), then you need to be aware of it. Make sure in this situation you fully remove the old Machine-Wide Installer and do all necessary cleanup before installing the updated version.

Auto-setup and auto-launch

I’m going to refer to the automatic “first run” of Teams that triggers the initial setup as “auto-setup”. Auto-setup is a pain, for reasons you can probably guess. If you install the Machine-Wide Installer widely onto an estate, and then have thousands of users logging in the next day and launching Teams for the first time – that initial “burst” of resource utilization can cause a big problem.

Of course, as Citrix or RDSH admins, our first instinct is to disable the auto-setup from running so we can get a handle on it. If the users can launch Teams from the desktop or Start Menu shortcuts, then surely it is better to allow them to choose “when to launch Teams for the first time”?

If you go a-Googling, then there are immediately two methods of disabling the auto-setup that spring out:-

Use a switch with the command-line installer that blocks the auto-setup

msiexec /i Teams_windows_x64.msi OPTIONS="noAutoStart=true" ALLUSER=1 ALLUSERS=1

Or, edit the setup.json file that sits in the Program Files (x86) folder, so that it no longer has the auto-start flag set (the PowerShell below changes this setting)

(Get-Content ${ENV:ProgramFiles(x86)}’\Teams Installer\setup.json’).replace(‘false’,’true’) | Set-Content ${ENV:PROGRAMFILES(x86)}’\Teams Installer\setup.json’

There’s one small problem with both these methods, though – neither of them works. When you log into an instance that has been configured with either of the above methods, Teams still launches the auto-setup routine.

The auto-setup is driven by the entry pointing to Teams.exe which sits in HKLM. When this program runs, auto-setup is started (if the user hasn’t used Teams before), or the Teams client starts (if the user has already done the auto-setup step).

So can we just delete the HKLM entry and have done with it that way?

Well, yes, but with a significant caveat. The problem is that once auto-setup has been run, on subsequent logons, the auto-launch (so not the first-time setup, but the automatic launch of Teams for a user who has already done the auto-setup step, which we will refer to as auto-launch from hereon in) is also driven by the HKLM Registry value. So if you delete the HKLM Registry value so that users trigger the auto-setup step themselves, then the users will have to remember to manually launch Teams every time they log in. This isn’t ideal – apps like Teams are good to get auto-launched, because otherwise users may miss important conversations and messages. And don’t forget – there is no option in the user interface to auto-start Teams with the Machine-Wide Installer. The “user” version of Teams (the one that auto-updates, which we don’t want to use) has the option to auto-start in the GUI…

…but the Machine-Wide Installer has that option removed, as you can see below

Now, our requirements appear to be thus – we want to disable the auto-setup, so that new users don’t all launch Teams at once and hammer the system resources, but once they have launched Teams for the first time, we want the program to auto-launch so they don’t have to run it manually. There is a way to do this – but first, I’m going to go off on a bit of a tangent, because it ties together with what we are going to do, so bear with me.

Open minimized to notification area

Teams does, both in the user and Machine-Wide Installers, have the option to “open application in background”. This means that it will launch minimized to the notification area rather than opening up full-screen. I think this is an important feature. You don’t want users logging on to shared meeting-room devices, for instance, and a confidential or embarrassing Teams conversation flashes up on the screen for all to see.

Obviously, there is the option in the user interface to enable this functionality…

This setting correlates to an entry in a user-based configuration file, %APPDATA%\Microsoft\Teams\desktop-config.json. There is a property in this file called openAsHidden which will be set to true or false dependent on the option you have selected in the GUI.

Of course, like all things Teams, there’s a problem with this. In that, it literally just ignores the setting in the UI and just opens up full-screen anyway. Way to go, Microsoft! Arbitrarily ignoring user-selected settings that could have potential security risks attached – priceless.

So as well as getting rid of the auto-setup but keeping the auto-launch, we also want to force Teams to actually honour the setting for openAsHidden from the GUI.


“Isn’t there a GPO for handling this?” Well, there is. There is one solitary GPO for Teams, and it looks really promising – just read the description

In my testing, however, this GPO doesn’t do anything. I made sure I applied the GPO before Teams was installed (as per the description), but it still launches automatically at first logon. Talk about a disappointment!

Solving it

We need to do three things, as we’ve already laid out – disable auto-setup, enable auto-start once the setup is triggered manually by the user, and also make sure that the openAsHidden flag is actually respected. How can we do this?

You need to do a bit of conditional Registry editing, so I’d use Group Policy Preferences, Workspace Environment Management, Ivanti User Workspace Manager, or any one of the myriad tools out there that can manipulate the user Registry based on certain parameters. For this example we’ve used GPP as everyone has access to that – tweak as required for your own solution.

I set up a Group Policy Preference Registry item that writes an HKCU Run entry pointing to Teams rather than HKLM (make sure you do not use Wow6432Node in the path – HKCU does not execute the Wow6432Node Run entry, if it exists)

  • Action – Replace
  • Key path – Software\Microsoft\Windows\CurrentVersion\Run
  • Value name – Teams Auto Start
  • Value type – REG_EXPAND_SZ
  • Value data – (below so can be copied better)
"%ProgramFiles(x86)%\Microsoft\Teams\current\Teams.exe" --process-start-args "--system-initiated"

Also, use “Run in logged-on user’s security context” in the Common tab, and an Item-Level Targeting scoped as below

Also, alongside this configure a second GPP Registry item, this time as below

  • Action – Delete
  • Key path – Software\Microsoft\Windows\CurrentVersion\Run
  • Value name – Teams Auto Start

Again, use “Run in logged-on user’s security context” in the Common tab, and an Item-Level Targeting scoped as below

Hopefully you see what we are doing here. The HKCU entry is only created when the desktop-config.json file exists (which means auto-setup has been run manually by the user). If the json file does not exist, the HKCU entry is cleared. The additional arguments on the executable – –process-start-args “–system-initiated” – ensure that the openAsHidden property is properly respected. If you’re not bothered about it opening minimized, then just set the HKCU Run entry to simply “%ProgramFiles(x86)%\Microsoft\Teams\current\Teams.exe”

What a palaver! Let’s summarize this Teams installation and config process:-

  • Always use the Machine-Wide Installer
  • Always install with the ALLUSER and ALLUSERS switches
  • Delete the HKLM Run entry that Teams drops into the Registry
  • Apply the Registry entries mentioned above through GPP, WEM, UWM, etc.

Now, if all this seems like a great big pain in the proverbials my fellow CTP and Teams wrangler Rene Bigler pointed out something that may be of interest. Over at Master Packager ( there is a custom installer file where they have modified it so it can be installed everywhere, it removes the desktop shortcut, disables auto-setup and removes the Modify option. You can find it at the following link –

Another point to mention is that the Teams Machine-Wide Installer is meant only to be used on “VDI” platforms (VDI being used in the loosest possible terms). This is why at the start I said that the VDA must be installed before installing Teams. The Machine-Wide Installer is supposed to run only on Citrix, VMware Horizon and Windows Virtual Desktop and performs some checks to make sure it is in one of these environments otherwise it will fail with the error below

Of course, this makes it problematic if you’re using one of the other virtualization technologies out there (Parallels maybe), or if you want to package or layer your Teams install using some kind of application installer technology (App-V, AppVolumes, App Layering, Cloudpaging, etc.) I can’t speak for VMware Horizon or WVD, but if you need to trick your Teams Machine-Wide Installer into running on a non-VDI platform, simply create the following Registry key prior to running the installer so that you make it think it is running on Citrix


With this in place, you should be free to do what you want with the installer (or you could just avoid this and use the Master Packager version where they’ve already fooled it for you).

If you’re using the 1906 or 1909 version of the Citrix VDA, you may get issues with Teams crashing. Create a DWORD value in the following path – HKLM\SOFTWARE\Citrix\CtxHook\AppInit_Dlls\SfrHook\Teams.exe – and set it to 204 to resolve.

Finally, make sure you update Teams as often as possible. New versions come, even to the Machine-Wide Installer, a couple of times a month. If you want to keep on top of new features for your users you will need to keep an eye out for new updates to the binaries, and remember what I said – unless you are starting with a fresh base image every time you update, fully uninstall the old Teams version before installing the new one.


So there you have it – what a finickety application to have to try and deliver!

Bear in mind that Teams changes regularly, so that anything in this article could become out-of-date at any time – certainly my previous Teams article is now redundant. At time of writing, though, this all tested and worked as described.

The next part of this, where we will talk about session performance and the mysteries of the json files that drive Teams, will probably drop in a couple of weeks as I have part #3 of my logons series to publish first (contain your excitement!) Stay tuned!

 2,986 total views,  54 views today


  1. This is a really really good article Thank you very much! I’m especially glad, that I finally have proves for stuff I discovered weeks ago, but always thought I’m stupid.

    Both the AutoStart Switch and the AutoStart JSON never worked for me, now I know they just don’t.

    Checkbox “Auto-start” application was not available on Citrix, I was quite sure it’s not part of the MSI.

    “Open application in background” also never worked for me, I will try –process-start-args “–system-initiated”

    And finally the stupid none working GPO.

    Thank you very much, for proving all my findings.

    1. No problem Marco, don’t think that you’re being stupid, write it up and let everyone know! Nothing in Teams surprises me 🙂

  2. Thanks for the excellent write-up. Has anyone actually been able to make the damn app start minimized by default?

    I’d rather it start minimized for our users and let them have the ability to uncheck that option by default. I guess I could create default desktop-config.json that has that set, store it on a common share, and use a WEM file system operation to copy it down once…not ideal but might work.

    1. Minimized is in the json file as well. But you can simply write the openAsHidden=true to the json file at the first launch and it should do the same?

  3. What about performance capping of Teams? on large environment with thousands of users, this is likely to consume a huge amount of resource and impact the total density. Have you looked at tailoring performance for Teams?

  4. Hi James, An excellent article for Dummies. In any of your upcoming article, can you also share pros and cons of x86 vs x64 version of Teams and on what circumstance should we choose one among them?

Leave a Reply

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