CVAD Guide to Microsoft Teams

by Ray Davis, CTA

This CVAD Guide to Microsoft Teams was built from Slack posts, Citrix URLs, and Citrix consultants from the field who shared how they successfully got Teams working 90 – 95% within Citrix Virtual Apps and Desktop Environment. But the information is shared among many people and shows promising results. I keep it updated around new blogs and actual experience installing teams in a CVAD environment. If you disagree and find something different, then reach out and let’s update it. Please understand that all these tips/tricks may not apply to your environment. I encourage you to know what you are using from this blog.

Suppose you are unfamiliar with running Microsoft Teams in a Citrix Virtual Apps or Desktop. I see it all the time, and it will bite you. I recommend you start here. Reading and understanding these links will ensure you know the VDI aspect and don’t apply the typical desktop assumption as there are many transitions from a desktop space into a VDI space.

For those who need Microsoft Teams help in CVAD, I recommend bookmarking the links below. Many may be aware, like me. For those who are not, these will help you tremendously.

Teams deep dive around performance by go-EUC:

Teams around Citrix-related fixes:

Updates Microsoft Teams versioning:

Overall documentation:

eG, Key Considerations for Teams on Citrix:
Microsoft Teams on Citrix: Best Practices (

  1. Different installers for Teams
    • If you install Team.exe, this is the user installer. It will either install in the user profile or program data—mostly user profiles like the traditional desktop rollout I have seen at companies.
    • If you install the MSI version of Teams, this is the Machine Wide installer. Citrix states they need the machine-wide installer.
  1. Uninstall Teams per user -clean up and redeployment procedure
    • Uninstall the user per Team’s installer before proceeding with the Team machine installer.
    • You can have Citrix WEM run this for the user inside their profile.
    • Location: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
  1. Option 1: 
    • %LOCALAPPDATA%\Microsoft\Teams\Update.exe –uninstall –msiUninstall –source=default
    • %Programdata%\Microsoft\Teams\Update.exe –uninstall –msiUninstall –source=default
  2. Option 2:
    • Source Scripts
    •  (Read this)
    • C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -command set-execution policy bypass -Scope CurrentUser
    • C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -File “\\domain\NETLOGON\CitrixScripts\WemExternalTask\TeamsUninstall-Users\TeamsUser-Uninstall.ps1” -NoProfile -Noninteractive
    • The PS1 Script is from here
    • But I changed the part in the Script to do it while the user is logged in.
    • $TeamsStartMenuShortcut = “c:\users\$env:USERNAME.$env:USERDOMAIN\Start Menu\Programs\Microsoft Corporation”
      $TeamsDesktopShortcut = “c:\users\$env:USERNAME.$env:USERDOMAIN\Desktop\MicrosoftTeams.lnk”
    • Originally it was:
      $TeamsStartMenuShortcut = “\\domain\share\$env:USERNAME.$env:USERDOMAIN\Start Menu\Programs\Microsoft Corporation”
      $TeamsDesktopShortcut = “\\domain\share\$env:USERNAME.$env:USERDOMAIN\Desktop\Microsoft Teams.lnk”
    • Then I used a WEM external Task to run it. Put the Script in a location that users can read. It will execute and do the cleanup inside the user profile for you.
Teams installer
  1. Block user installs
    • Deny access to C:\Users\*\AppData\Local\Microsoft\Teams
    • Use FSLogix AppMasking
    • Quick Rule
FSLogix RuleEditor
  • If, by chance, a user tried to install it. They would get this:
install failed message
  • Logs point out what AppMasking is doing:
  • Note: if you have a machine installed already installed and a user tries to click a link in Outlook, it will open with the installed machine version on the VDI.
  1. Citrix Requirements: (Highly advise using more updated versions)
  1. Microsoft VDI guidance
    • These examples also use the ALLUSERS=1 parameter. When you set this parameter, Teams Machine-Wide Installer appears in Programs and Features in Control Panel and in Apps & features in Windows Settings for all computer users. All users can then uninstall Teams if they have admin credentials. It’s essential to understand the difference between ALLUSERS=1 and ALLUSER=1. The ALLUSERS=1 parameter can be used in non-VDI and VDI environments, and the ALLUSER=1 parameter is used only in VDI environments to specify a per-machine installation.
  1. Dedicated VDI (updated)
    • You have Windows 10 dedicated, persistent VDI environments. You want the Teams application to auto-update and would prefer Teams to install per-user under Appdata/Local. (I don’t know if they will be optimized for Citrix, though?) Use the .exe installer or the MSI without ALLUSER=1.
    • Update 8/18/2020, 2/6/2023
      I confirmed that it’s still optimized as well on the user install. I was wondering about this, and now I know.
    • Non-Persistent VDI or RDSH (XenApp)
      • ALLUSERS=1:  Teams Machine-Wide Installer appears in Programs and Features in Control Panel and in Apps
      • ALLUSER=1: used only in VDI environments to specify a per-machine installation and turns off auto-updater in non-persistent machines.
      • noAutoStart=true: tells it when installing set it not to autostart.
  1. Per-machine installation for VDI
    • /l*v  ALLUSER=1 ALLUSERS=1
    • msiexec /i <path_to_msi> /l*v <install_logfile_name> ALLUSER=1 ALLUSERS=1
    • msiexec /i Teams_windows_x64.msi ALLUSER=1 ALLUSERS=1
    • msiexec /i Teams_windows_x64.msi OPTIONS=”noAutoStart=true” ALLUSER=1 ALLUSERS=1
    • msiexec /i “%temp%\Teams_windows_x64.msi” /QN OPTIONS=”noAutoStart=true” ALLUSER=1 ALLUSERS=1
  1. Container Profile exclusions
    • <Exclude Copy=”0″>AppData\Local\Microsoft\Teams\Current\Locales</Exclude>
    • <Exclude Copy=”0″>AppData\Local\Microsoft\Teams\Packages\SquirrelTemp</Exclude>
    • <Exclude Copy=”0″>AppData\Local\Microsoft\Teams\current\resources\Locales</Exclude>
    • <Exclude Copy=”0″>AppData\Roaming\Microsoft\Teams\Service Worker\CacheStorage</Exclude>
    • <Exclude Copy=”0″>AppData\Roaming\Microsoft\Teams\Application Cache</Exclude>
    • <Exclude Copy=”0″>AppData\Roaming\Microsoft\Teams\Cache</Exclude>          
    • <Exclude Copy=”0″>AppData\Roaming\Microsoft Teams\Logs</Exclude>
    • <Exclude Copy=”0″>AppData\Roaming\Microsoft\Teams\media-stack</Exclude>
  1. UPM File based
  1. Warnings and issues (JSON Files are a pain and don’t seem to get honored very well.)
    • Running the MSI in VDI mode by using the switch Alluser=1 makes teams completely ignore  JSON files.  It ignores the setup.json, and it ignores the desktop-config.json file. Redirecting it to any other json file anywhere else won’t help as it doesn’t respect JSON files. It must be a bug. Still trying to work through this.
  1. Disable Teams auto-launch.
    • I see this in many environments, Teams auto-launch starts when the user logs in. Teams is heavy on CPU, and I recommend not doing this. However, some places seem to ignore this and take the desktop approach.
      • Disable Teams auto-launch after installation.
      • Delete Teams reg keys following locations
      • HKEY_LOCAL_MACHINE \SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run 
      • HKEY_LOCAL_MACHINE \SOFTWARE\Microsoft\Windows\CurrentVersion\Run
      • HKEY_CURRENT_USER \SOFTWARE\Microsoft\Windows\CurrentVersion\Run
      • Then apply GPO, not to auto Launch Teams. 
    • It is not currently possible to disable Auto-start even if using the command line flag OPTIONS=”noAutoStart=true” with the machine-wide MSI and the ALLUSER=1 property. Deleting the reg key described in bullet#2 (bullet#2 is on the citrix doc) should fix this.
    • Group Policy setting, make sure you first set the Group Policy setting to the value you want before you run this Script. If you have profiles that have already set auto-launch, you will have to run this Script to clear out the settings. Suppose you want to use the “Prevent Microsoft Teams from starting automatically after installation. 
    • Doing Auto Launch with Teams is CPU intensive. Control it with WEM on auto-launch, and It will allow the Shell to load first.
  1. James Rankin method of disabling auto-setup, enabling auto-start once the setup is triggered manually by the user, and also making sure that the openAsHidden flag is actually respected. Scroll down to “Solving It”
  1. Disable GPU offload because teams will have HIGH CPU usage (no video card)

$ErrorActionPreference = ‘SilentlyContinue’
$JsonFile = [System.IO.Path]::Combine($Env:AppData, ‘Microsoft’, ‘Teams, ‘desktop-config.json’)
$ConfigFile = Get-Content -Path $JsonFile -Raw | ConvertFrom-Json
Try {
    $ConfigFile.appPreferenceSettings.openAtLogin = $False
   $ConfigFile.appPreferenceSettings.disableGpu = $True
} Catch {
    Write-Host  “JSON element doesn’t exist”
$ConfigFile | ConvertTo-Json -Compress | Set-Content -Path $JsonFile -Force 

  • Update as of November 4, 2021
  • if (!(Test-Path $env:AppData\Microsoft\Teams\desktop-config.json)) {Exit} $JSONFile = $env:AppData+”\Microsoft\Teams\desktop-config.json” $User = $env:USERDOMAIN+’\’+$env:USERNAME $JSON = Get-Content $JSONFile | ConvertFrom-Json if ($JSON.appPreferenceSettings.disableGpu -eq $False) { Get-Process -Name ‘Teams’ -IncludeUserName -ErrorAction SilentlyContinue | Where-Object UserName -eq $User | Stop-Process -Force $JSON.appPreferenceSettings.disableGpu = $True $JSON | ConvertTo-Json | Out-File $JSONFile -Encoding ASCII & “C:\Program Files (x86)\Microsoft\Teams\current\Teams.exe” }
  • Other Sources:
  • Microsoft Teams Optimization on Citrix –
    • For this, I did a WEM external Task that does the following:
    • C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -command set-executionpolicy bypass -Scope CurrentUser
    • C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -File “\\\NETLOGON\CitrixScripts\WemExternalTask\DisableGPUTeams_VDI\disableGPUTeams.ps1” -NoProfile -Noninteractive
    1. Monitoring Teams with HDX Monitor

      On 1912 VDAs (or higher), you can monitor an optimized active call using HDX Monitor (3.5.2 or higher).To turn this on, create the following WebrtcDirectorIntegration reg key on the VDA:

      – reg key value:
      name: WebrtcDirectorIntegration
      type: DWORD
      value: enable(1), disable(0)
    1. Enable Team in Citrix
      Enable optimization of Microsoft Teams:
      To enable optimization for Microsoft Teams, use the Studio policy described in Microsoft Teams redirection policy (it is ON by default). In addition to this Policy being enabled, HDX checks to verify that the version of the Citrix Workspace app is equal to or greater than the minimum required version. If you enabled the Policy and the Citrix Workspace app version is supported, the HKEY_CURRENT_USER\Software\Citrix\HDXMediaStream\MSTeamsRedirSupport registry key is set to 1 automatically on the VDA. The Microsoft Teams application reads the key to load in VDI mode.


    • If you are using version 1906.2 VDAs or higher with older Controller versions (for example, version 7.15), which do not have the Policy available in Studio, you can still be optimized because HDX optimization for Microsoft Teams is enabled by default in the VDA.
    • If you click About > Version, the Citrix HDX Optimized legend displays:
    • Optimized for Citrix legend
    Citrix HDX optimized
    1. Troubleshooting MS teams in Citrix 
      This material is copied from other sources and is not my material. You will see word-for-word references in blogs. This is me trying to pull it all together in one area.
    • Check Teams are optimized.
      • When Teams are running optimized, the HdxRtcEngine.exe process runs on the endpoint and the WebSocketAgent.exe process runs on the VDA.
      • Check status of services.
      • There are a couple of services required to be running on the VDA for successful Teams optimization.
    • Citrix HDX Teams Redirection Service: Provides establishment of virtual channel used with Microsoft Teams.
    • Citrix HDX HTML5 Video Redirection Service: Responsible for TLS termination of secure WebSockets and spawning the WebSocketAgent.exe process into user sessions when Teams starts. This service also runs as WebSocketService.exe and needs to be listening on You can confirm this using command netstat -anob -p tcp | findstr 9002 on the VDA.
    • On successful connection, the state turns to ESTABLISHED.
    • Using HDX Monitor
    • The latest versions of HDX Monitor allow you to see some information about active Teams calls.
    • When viewing session information via HDX Monitor, if the Number of connections under Webrtc is set to 0, either Teams has not been launched within the session or has been launched but is not optimized.
    • When Teams is running optimized, the number of connections for the session will change to 1.
    • When a Teams call is in progress, the Virtual channel state will switch from Idle to Active. HDX Monitor will also show you the maximum Kbps outgoing and incoming bandwidth used for the entire HDX session over all Teams calls.
    1. Gathering Logs
      There are various logs you can turn to when troubleshooting HDX Optimization for Teams.
      Client Endpoint (Windows)
      Folder: %LocalAppData%\Temp\HdxRtcEngine
      Contains hdxrtcengine.log and webrpc.log.
      Additionally, there are log files stored on Mac and Linux endpoints, and you also have the option of enabling CDF tracing using specific trace providers.
    1. To prevent Teams from installing in Office updates:
      If your organization isn’t ready to deploy Teams and you use Group Policy, you can enable the Don’t install Microsoft Teams with new installations or updates of Office policy setting. Most placed I see take the defaults. Which will install Teams from the 0365 media. Build a custom XML file and exclude Teams.
    • It will add this key:
    • If you do get Teams to install from Office updates (which I had, and I didn’t realize it), you will see Teams auto-start upon logging in. 
    • You will see this:
      • User auto Start HKCU\Software\Microsoft\WIndows\Current Verison\Run
        • C:\Users\%username%\AppData\Local\Microsoft\Teams\Update.exe –processStart “Teams.exe” –process-start-args “–system-initiated”
      • Machine auto Start
        • HKLM\Software\\WOW6432Node\Microsoft\WIndows\Current Verison\Run
        • %ProgramFiles%\Teams Installer\Teams.exe –checkInstall –source=PROPLUS
      1. Outlook Plugin appears to break at times or may never load.
      1. Outlook Plugin appears to break at times, and this is what I have found so far that fixes it.
        • Nick Panaccio shared a great script with me that helped a lot in this area:

      $ErrorActionPreference = 'SilentlyContinue'

      #We need to add the following items to allow Teams meeting links to open Teams and not have IE prompt to allow the action

      If (!(Test-Path "HKCU:\Software\Microsoft\Internet Explorer\ProtocolExecute\msteams")) {

          New-Item "HKCU:\Software\Microsoft\Internet Explorer\ProtocolExecute\" -Name "msteams" -Force | Out-Null


      New-ItemProperty "HKCU:\Software\Microsoft\Internet Explorer\ProtocolExecute\msteams\" -Name "WarnOnOpen" -Value 0 -PropertyType "DWORD" -Force | Out-Null

      If (!(Test-Path "HKCU:\Software\Classes\msteams")) {

          New-Item "HKCU:\Software\Classes\msteams\shell\open\" -Name "command" -Force | Out-Null


      New-ItemProperty "HKCU:\Software\Classes\msteams\" -Name "(Default)" -Value "URL:msteams" -PropertyType "String" -Force | Out-Null

      New-ItemProperty "HKCU:\Software\Classes\msteams\" -Name "URL Protocol" -Value "" -PropertyType "String" -Force | Out-Null

      New-ItemProperty "HKCU:\Software\Classes\msteams\shell\open\command\" -Name "(Default)" -Value """C:\Program Files (x86)\Microsoft\Teams\current\Teams.exe"" ""%1""" -PropertyType "String" -Force | Out-Null

      If (!(Test-Path "HKCU:\Software\Classes\TeamsURL")) {

          New-Item "HKCU:\Software\Classes\TeamsURL\shell\open\" -Name "command" -Force | Out-Null


      New-ItemProperty "HKCU:\Software\Classes\TeamsURL\shell\open\command\" -Name "(Default)" -Value """C:\Program Files (x86)\Microsoft\Teams\current\Teams.exe"" ""%1""" -PropertyType "String" -Force | Out-Null

      #We need to add the following items to get the 'New Teams Meeting' button to appear in Outlook

      New-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts\" -Name "msteams_msteams" -Value 0 -PropertyType "DWORD" -Force | Out-Null

      New-Item "HKCU:\Software\Microsoft\Office\Outlook\AddIns\" -Name "TeamsAddin.FastConnect" -Force | Out-Null

      New-ItemProperty "HKCU:\Software\Microsoft\Office\Outlook\AddIns\TeamsAddin.FastConnect\" -Name "Description" -Value "Microsoft Teams Meeting Add-in for Microsoft Office" -PropertyType "String" -Force | Out-Null

      New-ItemProperty "HKCU:\Software\Microsoft\Office\Outlook\AddIns\TeamsAddin.FastConnect\" -Name "LoadBehavior" -Value 0x3 -PropertyType "DWORD" -Force | Out-Null

      New-ItemProperty "HKCU:\Software\Microsoft\Office\Outlook\AddIns\TeamsAddin.FastConnect\" -Name "FriendlyName" -Value "Microsoft Teams Meeting Add-in for Microsoft Office" -PropertyType "String" -Force | Out-Null

      #We need to add the following items to preconfigure Teams

      If (!(Test-Path "$Env:AppData\Microsoft\Teams")) {

          New-Item "$Env:AppData\Microsoft\Teams\" -ItemType "Directory" -Force | Out-Null


      Copy-Item -Path "$PSScriptRoot\desktop-config.json" -Destination "$Env:AppData\Microsoft\Teams" -Recurse -Force

      If (!(Test-Path "HKCU:\Software\Classes\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}")) {

          New-Item "HKCU:\Software\Classes\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}\LocalServer\" -Force | Out-Null


      New-ItemProperty "HKCU:\Software\Classes\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}\LocalServer\" -Name "(Default)" -Value "C:\Program Files (x86)\Microsoft\Teams\current\Teams.exe" -Force | Out-Null

      If (!(Test-Path "HKCU:\Software\Classes\WOW6432Node\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}")) {

          New-Item "HKCU:\Software\Classes\WOW6432Node\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}\LocalServer\" -Force | Out-Null


      New-ItemProperty "HKCU:\Software\Classes\WOW6432Node\CLSID\{00425F68-FFC1-445F-8EDF-EF78B84BA1C7}\LocalServer\" -Name "(Default)" -Value "C:\Program Files (x86)\Microsoft\Teams\current\Teams.exe" -Force | Out-Null

      1. I was updated that screen sharing may act up. If this happens, remove the Contents from AppData and all Teams data. Then allow it to rebuild the files etc.

      This blog will continue to be updated…questions and comments are welcome below!

      See more posts by Ray Davis here.

      Are you a member of CUGC? Join FREE today!

      Leave a Reply