TruGrid SecureRDP - Teams meetings optimization
Contents
- Overview
- Prerequisites
- What needs to be configured
- How to run the scripts
- Setting Remote Desktop as the default RDP client
- Verification
- Troubleshooting
- Endpoint script
- Session host script
Overview
Microsoft Teams runs unoptimized inside an RDP session by default - audio and video are rendered remotely and forwarded across the connection, adding latency and bandwidth cost. With media redirection, Teams audio and video run on the local endpoint while the rest of Teams lives in the remote session.
Configuration is needed on two sides:
- The endpoint - the machine where the TruGrid Windows Connector is installed and the user starts RDP sessions from
- The session host - the machine the user RDPs into
Each side has its own script. Both must be run for media optimization to work.
Prerequisites
- Windows 10 22H2 or Windows 11 (endpoint); Windows 10 22H2, Windows 11, or Windows Server 2019/2022 with the RDS role (session host)
- Local administrator rights on each machine
- Internet access for installer downloads
- A custom build of the TruGrid Windows Connector that launches sessions in the Remote Desktop client rather than
mstsc. This is available upon request from TruGrid support. The standard Connector cannot perform media optimization regardless of the components installed below.
What needs to be configured
On the endpoint
Item | Why it's needed | How the script handles it |
|---|---|---|
Microsoft Visual C++ Redistributable (x64) | Required runtime for the WebRTC redirector | Silent install |
Remote Desktop client (MSRDC, MSI install) | RDP client that supports Teams media optimization ( | Silent install via Microsoft's per-machine MSI |
Remote Desktop WebRTC redirector | Local-side WebRTC stack for redirected Teams media | Silent MSI install |
Default | Ensures | Opens Settings > Default Apps for the .rdp file type |
On the session host
Item | Why it's needed | How the script handles it |
|---|---|---|
Microsoft Visual C++ Redistributable (x64) | Required runtime for Teams and the WebRTC redirector | Silent install |
New Teams (per-machine install) | Multi-user installation of the new Teams client | Silent install via Microsoft's bootstrapper + MSIX |
Remote Desktop WebRTC redirector | Server-side WebRTC stack for redirected media | Silent MSI install |
| Tells Teams it is running in a redirected environment | Sets the DWORD to |
How to run the scripts
Recommended: PowerShell ISE
- Right-click Windows PowerShell ISE and choose Run as administrator.
- Paste the entire script (from the sections at the bottom of this article) into a new script pane.
- Press F5 to run.
The script checks the current state of each item, displays a status report, and prompts you in the console pane before installing anything. To run with different behavior, change the param block at the top of the script before pressing F5:
- Default (no changes): interactive - prompts before installing
- Set
[switch]$CheckOnly = $truein the param block: status report only, no install - Set
[switch]$Apply = $truein the param block: install everything missing without prompting
Run the endpoint script on the endpoint machine and the session host script on the session host machine. They are not interchangeable.
Setting Remote Desktop as the default RDP client
Windows blocks programmatic changes to file-type defaults as a security measure - the endpoint script cannot directly set Remote Desktop as the default for .rdp files. When this step is needed, the script opens Settings > Default Apps for the .rdp file type and waits for you to make the change.
In the dialog that appears:
- Find the entry showing the current default app for
.rdpfiles (likely "Remote Desktop Connection" /mstsc) - Click it
- Select Remote Desktop from the list - the entry corresponding to the MSRDC client, not "Remote Desktop Connection" (the classic
mstscentry) - Click Set default
- Close Settings and return to the script. Press Enter to continue.
After this change, double-clicking any .rdp file - whether from TruGrid or any other source - will open in the modern Remote Desktop client rather than the classic Remote Desktop Connection.
If Remote Desktop does not appear in the list of available defaults, confirm the previous step succeeded - the MSI install should have placed msrdc.exe (and msrdcw.exe) under C:\Program Files\Remote Desktop or the equivalent per-user path.
Verification
After both scripts have completed and the session host has been signed out and signed back in (the IsWVDEnvironment registry value is read at Teams startup), start a TruGrid RDP session from the endpoint into the session host. The session should now open in the Remote Desktop client rather than the classic mstsc window.
Inside the session, open Teams and start a call. In the call window, click the three-dot menu, then About > Version. The dialog should indicate "Media optimized for Virtual Desktop" or similar. If the indicator is missing, sign out of the session and back in once, then re-check.
Troubleshooting
Endpoint script reports the Remote Desktop client as missing after install. The MSI install completed but the binaries went somewhere unexpected. Check for msrdc.exe and msrdcw.exe under C:\Program Files\Remote Desktop (per-machine) or %LocalAppData%\Apps\Remote Desktop (per-user).
Default .rdp handler still shows mstsc after Settings change. Sign out and back in to the endpoint. Some default-app changes do not take effect for the current shell session.
**Alternatively **you can create a test file by opening an Remote Desktop App and click Save As and store the temporary file on the Dekstop > then make a right click find Open With and select another Remote Desktop Application
TruGrid still launches mstsc despite Remote Desktop being default. This means the standard TruGrid Connector is in use. The custom build is required - contact support.
Host script reports New Teams as missing after install. Classic Teams (per-user) can interfere with detection. Uninstall any per-user Teams installations:
Get-AppxPackage -AllUsers MicrosoftTeams | Remove-AppxPackage -AllUsersThen re-run the host script.
IsWVDEnvironment set but optimization indicator missing in Teams. Confirm Teams was restarted after the registry change. The value is read at process startup, not continuously. Also confirm the endpoint side is using the Remote Desktop client, not mstsc.
Teams audio still routes through the session after sign-out and sign-in. Verify the MsRdcWebRtcSvc service exists and is set to start automatically on both sides:
Get-Service MsRdcWebRtcSvc | Select-Object Status, StartTypeA script reports [ STILL MISSING ] for any item in the final summary. Scroll up to the install step output for that item - the script logs the installer's exit code and any error inline.
Endpoint script
Save as Optimize-TeamsForRdp-Client.ps1 and run on the endpoint.
# Optimize-TeamsForRdp-Client.ps1
# Configures a Windows machine acting as a TruGrid Connector endpoint for
# optimized Teams-over-RDP. Reference:
# https://learn.microsoft.com/en-us/azure/virtual-desktop/teams-on-avd
[CmdletBinding()]
param(
[switch]$Apply,
[switch]$CheckOnly
)
$ConfirmPreference = 'None'
$ProgressPreference = 'SilentlyContinue'
$ErrorActionPreference = 'Stop'
# --- Elevation check ---------------------------------------------------------
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [System.Security.Principal.WindowsPrincipal]::new($id)
if (-not $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "ERROR: This script must be run from an elevated PowerShell session." -ForegroundColor Red
Write-Host "Right-click PowerShell -> Run as administrator, then re-run this script."
return
}
$cacheDir = Join-Path $env:TEMP 'TruGrid-TeamsOptimization'
New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
# --- Win32 P/Invoke for file association lookup ------------------------------
if (-not ('Assoc' -as [type])) {
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
public class Assoc {
[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(uint flags, uint str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);
}
"@
}
# --- Check functions ---------------------------------------------------------
function Get-VcRedistStatus {
$key = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64' -ErrorAction SilentlyContinue
if ($key -and $key.Installed -eq 1) {
@{ Installed = $true; Detail = "v$($key.Version)" }
} else {
@{ Installed = $false; Detail = 'Not found' }
}
}
function Get-RemoteDesktopClientStatus {
# The Microsoft Desktop client (msrdc.exe / msrdcw.exe), installed via MSI
foreach ($path in @(
'C:\Program Files\Remote Desktop\msrdc.exe',
'C:\Program Files\Remote Desktop\msrdcw.exe',
(Join-Path $env:LOCALAPPDATA 'Apps\Remote Desktop\msrdc.exe'),
(Join-Path $env:LOCALAPPDATA 'Apps\Remote Desktop\msrdcw.exe')
)) {
if (Test-Path $path) {
$ver = (Get-Item $path).VersionInfo.FileVersion
$scope = if ($path -like "$env:LOCALAPPDATA*") { 'Per-user' } else { 'Per-machine' }
return @{ Installed = $true; Detail = "$scope v$ver ($([System.IO.Path]::GetFileName($path)))" }
}
}
@{ Installed = $false; Detail = 'Not installed' }
}
function Get-WebRtcStatus {
$svc = Get-Service 'MsRdcWebRtcSvc' -ErrorAction SilentlyContinue
$file = Test-Path 'C:\Program Files\Remote Desktop WebRTC Redirector\MsRdcWebRtcSvc.exe'
if ($svc -or $file) {
@{ Installed = $true; Detail = if ($svc) { "Service: $($svc.Status)" } else { 'File present' } }
} else {
@{ Installed = $false; Detail = 'Not installed' }
}
}
function Get-DefaultRdpHandlerStatus {
# Use the actual Win32 API Explorer uses (AssocQueryString) - authoritative
$buf = New-Object Text.StringBuilder 260
$size = [uint32]260
# ASSOCSTR_EXECUTABLE = 2
[void][Assoc]::AssocQueryString(0, 2, '.rdp', 'open', $buf, [ref]$size)
$path = $buf.ToString()
$exe = [System.IO.Path]::GetFileName($path)
if ($exe -match 'msrdc(w)?\.exe') {
@{ Installed = $true; Detail = "Handler: $exe ($path)" }
} elseif ($exe -match 'mstsc\.exe') {
@{ Installed = $false; Detail = "Currently mstsc.exe (legacy)" }
} elseif (-not $exe) {
@{ Installed = $false; Detail = 'No association resolved' }
} else {
@{ Installed = $false; Detail = "Unknown handler: $exe" }
}
}
# --- Install functions -------------------------------------------------------
function Install-VcRedist {
$url = 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
$target = Join-Path $cacheDir 'vc_redist.x64.exe'
Write-Host " Downloading from $url..." -NoNewline
Invoke-WebRequest -Uri $url -OutFile $target -UseBasicParsing
Write-Host " done."
Write-Host " Running silent install..." -NoNewline
$proc = Start-Process -FilePath $target -ArgumentList '/install','/quiet','/norestart' -Wait -PassThru
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "VC++ Redist installer failed with exit $($proc.ExitCode)"
}
}
function Install-RemoteDesktopClient {
# Per-machine MSI - silent install, no user interaction
$url = 'https://go.microsoft.com/fwlink/?linkid=2139369'
$target = Join-Path $cacheDir 'RemoteDesktop_x64.msi'
Write-Host " Downloading Remote Desktop client (per-machine MSI)..." -NoNewline
Invoke-WebRequest -Uri $url -OutFile $target -UseBasicParsing
Write-Host " done."
Write-Host " Running silent install..." -NoNewline
$proc = Start-Process msiexec.exe -ArgumentList "/i `"$target`"",'/qn','/norestart' -Wait -PassThru
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "Remote Desktop client install failed with exit $($proc.ExitCode)"
}
}
function Install-WebRtc {
$url = 'https://aka.ms/msrdcwebrtcsvc/msi'
$target = Join-Path $cacheDir 'MsRdcWebRtcSvc.msi'
Write-Host " Downloading from $url..." -NoNewline
Invoke-WebRequest -Uri $url -OutFile $target -UseBasicParsing
Write-Host " done."
Write-Host " Running silent install..." -NoNewline
$proc = Start-Process msiexec.exe -ArgumentList "/i `"$target`"",'/qn','/norestart' -Wait -PassThru
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "WebRTC MSI install failed with exit $($proc.ExitCode)"
}
}
function Set-DefaultRdpHandler {
Write-Host " Windows blocks programmatic default-app changes for security."
Write-Host " Opening Settings > Default Apps for the .rdp file type."
Write-Host " In the dialog that appears, select 'Remote Desktop' and click 'Set default'."
Start-Process 'ms-settings:defaultapps?extension=.rdp'
Write-Host " Press ENTER once Remote Desktop is selected as the default..."
[void](Read-Host)
}
# --- Status report -----------------------------------------------------------
Write-Host ""
Write-Host "TruGrid - Teams Optimization (Endpoint / Client)" -ForegroundColor Cyan
Write-Host "================================================="
Write-Host ""
$vcRedist = Get-VcRedistStatus
$rdClient = Get-RemoteDesktopClientStatus
$webRtc = Get-WebRtcStatus
$defaultHandler = Get-DefaultRdpHandlerStatus
$items = @(
@{ Name = 'VC++ Redistributable (x64)'; Status = $vcRedist; Installer = 'Install-VcRedist' }
@{ Name = 'Remote Desktop client (MSI)'; Status = $rdClient; Installer = 'Install-RemoteDesktopClient' }
@{ Name = 'Remote Desktop WebRTC'; Status = $webRtc; Installer = 'Install-WebRtc' }
@{ Name = 'Default .rdp handler set to Remote Desktop'; Status = $defaultHandler; Installer = 'Set-DefaultRdpHandler' }
)
foreach ($i in $items) {
$tag = if ($i.Status.Installed) { '[ OK ]' } else { '[ MISSING ]' }
$color = if ($i.Status.Installed) { 'Green' } else { 'Yellow' }
Write-Host " $tag $($i.Name) - $($i.Status.Detail)" -ForegroundColor $color
}
Write-Host ""
Write-Host " [ NOTE ] Custom TruGrid Connector build (Remote Desktop routing)" -ForegroundColor Cyan
Write-Host " Required so TruGrid launches sessions in Remote Desktop instead of mstsc."
Write-Host " Open a ticket with TruGrid support to obtain it."
Write-Host ""
$missing = $items | Where-Object { -not $_.Status.Installed }
if ($missing.Count -eq 0) {
Write-Host "All checked items satisfied. No action needed." -ForegroundColor Green
return
}
if ($CheckOnly) {
Write-Host "$($missing.Count) item(s) need attention. Re-run without -CheckOnly to install." -ForegroundColor Yellow
return
}
Write-Host "$($missing.Count) item(s) need to be installed or configured:" -ForegroundColor Yellow
$missing | ForEach-Object { Write-Host " - $($_.Name)" }
Write-Host ""
if (-not $Apply) {
$response = Read-Host "Apply fixes now? [Y/N]"
if ($response -notmatch '^[Yy]') {
Write-Host "Aborted by user." -ForegroundColor Yellow
return
}
}
# --- Apply ------------------------------------------------------------------
foreach ($i in $missing) {
Write-Host ""
Write-Host "Applying: $($i.Name)" -ForegroundColor Cyan
try {
& $i.Installer
Write-Host " Done." -ForegroundColor Green
} catch {
Write-Host " FAILED: $($_.Exception.Message)" -ForegroundColor Red
}
}
# --- Re-verify --------------------------------------------------------------
Write-Host ""
Write-Host "Re-verifying state..." -ForegroundColor Cyan
Write-Host ""
$finalItems = @(
@{ Name = 'VC++ Redistributable (x64)'; Status = (Get-VcRedistStatus) }
@{ Name = 'Remote Desktop client (MSI)'; Status = (Get-RemoteDesktopClientStatus) }
@{ Name = 'Remote Desktop WebRTC'; Status = (Get-WebRtcStatus) }
@{ Name = 'Default .rdp handler set to Remote Desktop'; Status = (Get-DefaultRdpHandlerStatus) }
)
foreach ($i in $finalItems) {
$tag = if ($i.Status.Installed) { '[ OK ]' } else { '[ STILL MISSING ]' }
$color = if ($i.Status.Installed) { 'Green' } else { 'Red' }
Write-Host " $tag $($i.Name) - $($i.Status.Detail)" -ForegroundColor $color
}
Write-Host ""
Write-Host "Endpoint Teams optimization complete." -ForegroundColor Cyan
Write-Host "Remember to also configure the session host(s) using Optimize-TeamsForRdp-Host.ps1."
Write-Host ""
Session host script
Save as Optimize-TeamsForRdp-Host.ps1 and run on the session host.
# Optimize-TeamsForRdp-Host.ps1
# Configures a Windows machine acting as an RDP Session Host (the machine
# customers RDP into) for optimized Teams. Reference:
# https://learn.microsoft.com/en-us/azure/virtual-desktop/teams-on-avd
[CmdletBinding()]
param(
[switch]$Apply,
[switch]$CheckOnly
)
$ConfirmPreference = 'None'
$ProgressPreference = 'SilentlyContinue'
$ErrorActionPreference = 'Stop'
# --- Elevation check ---------------------------------------------------------
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [System.Security.Principal.WindowsPrincipal]::new($id)
if (-not $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "ERROR: This script must be run from an elevated PowerShell session." -ForegroundColor Red
Write-Host "Right-click PowerShell -> Run as administrator, then re-run this script."
return
}
$cacheDir = Join-Path $env:TEMP 'TruGrid-TeamsOptimization'
New-Item -ItemType Directory -Path $cacheDir -Force | Out-Null
# --- Check functions ---------------------------------------------------------
function Get-VcRedistStatus {
$key = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64' -ErrorAction SilentlyContinue
if ($key -and $key.Installed -eq 1) {
@{ Installed = $true; Detail = "v$($key.Version)" }
} else {
@{ Installed = $false; Detail = 'Not found' }
}
}
function Get-NewTeamsStatus {
# Per-machine "New Teams" provisioning
$pkg = Get-AppxPackage -AllUsers -Name 'MSTeams' -ErrorAction SilentlyContinue
if ($pkg) {
@{ Installed = $true; Detail = "v$($pkg.Version) (per-machine)" }
} else {
@{ Installed = $false; Detail = 'Not installed per-machine' }
}
}
function Get-WebRtcStatus {
$svc = Get-Service 'MsRdcWebRtcSvc' -ErrorAction SilentlyContinue
$file = Test-Path 'C:\Program Files\Remote Desktop WebRTC Redirector\MsRdcWebRtcSvc.exe'
if ($svc -or $file) {
@{ Installed = $true; Detail = if ($svc) { "Service: $($svc.Status)" } else { 'File present' } }
} else {
@{ Installed = $false; Detail = 'Not installed' }
}
}
function Get-WvdRegistryStatus {
$val = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Teams' -ErrorAction SilentlyContinue).IsWVDEnvironment
if ($val -eq 1) {
@{ Installed = $true; Detail = 'IsWVDEnvironment = 1' }
} else {
@{ Installed = $false; Detail = if ($null -eq $val) { 'Key/value missing' } else { "IsWVDEnvironment = $val" } }
}
}
# --- Install functions -------------------------------------------------------
function Install-VcRedist {
$url = 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
$target = Join-Path $cacheDir 'vc_redist.x64.exe'
Write-Host " Downloading from $url..." -NoNewline
Invoke-WebRequest -Uri $url -OutFile $target -UseBasicParsing
Write-Host " done."
Write-Host " Running silent install..." -NoNewline
$proc = Start-Process -FilePath $target -ArgumentList '/install','/quiet','/norestart' -Wait -PassThru
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "VC++ Redist installer failed with exit $($proc.ExitCode)"
}
}
function Install-NewTeams {
$bootstrapperUrl = 'https://go.microsoft.com/fwlink/?linkid=2243204&clcid=0x409'
$msixUrl = 'https://go.microsoft.com/fwlink/?linkid=2196106'
$bootstrapper = Join-Path $cacheDir 'teamsbootstrapper.exe'
$msix = Join-Path $cacheDir 'MSTeams-x64.msix'
Write-Host " Downloading Teams bootstrapper..." -NoNewline
Invoke-WebRequest -Uri $bootstrapperUrl -OutFile $bootstrapper -UseBasicParsing
Write-Host " done."
Write-Host " Downloading Teams MSIX..." -NoNewline
Invoke-WebRequest -Uri $msixUrl -OutFile $msix -UseBasicParsing
Write-Host " done."
Write-Host " Running per-machine provisioning..." -NoNewline
$proc = Start-Process -FilePath $bootstrapper -ArgumentList '-p','-o',"`"$msix`"" -Wait -PassThru -NoNewWindow
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0) {
throw "Teams bootstrapper failed with exit $($proc.ExitCode)"
}
}
function Install-WebRtc {
$url = 'https://aka.ms/msrdcwebrtcsvc/msi'
$target = Join-Path $cacheDir 'MsRdcWebRtcSvc.msi'
Write-Host " Downloading from $url..." -NoNewline
Invoke-WebRequest -Uri $url -OutFile $target -UseBasicParsing
Write-Host " done."
Write-Host " Running silent install..." -NoNewline
$proc = Start-Process msiexec.exe -ArgumentList "/i `"$target`"",'/qn','/norestart' -Wait -PassThru
Write-Host " exit $($proc.ExitCode)."
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
throw "WebRTC MSI install failed with exit $($proc.ExitCode)"
}
}
function Set-WvdRegistry {
New-Item -Path 'HKLM:\SOFTWARE\Microsoft\Teams' -Force | Out-Null
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Teams' `
-Name IsWVDEnvironment -PropertyType DWORD -Value 1 -Force | Out-Null
Write-Host " Registry value set."
}
# --- Status report -----------------------------------------------------------
Write-Host ""
Write-Host "TruGrid - Teams Optimization (Session Host)" -ForegroundColor Cyan
Write-Host "============================================"
Write-Host ""
$vcRedist = Get-VcRedistStatus
$newTeams = Get-NewTeamsStatus
$webRtc = Get-WebRtcStatus
$wvdReg = Get-WvdRegistryStatus
$items = @(
@{ Name = 'VC++ Redistributable (x64)'; Status = $vcRedist; Installer = 'Install-VcRedist' }
@{ Name = 'New Teams (per-machine)'; Status = $newTeams; Installer = 'Install-NewTeams' }
@{ Name = 'Remote Desktop WebRTC'; Status = $webRtc; Installer = 'Install-WebRtc' }
@{ Name = 'IsWVDEnvironment registry'; Status = $wvdReg; Installer = 'Set-WvdRegistry' }
)
foreach ($i in $items) {
$tag = if ($i.Status.Installed) { '[ OK ]' } else { '[ MISSING ]' }
$color = if ($i.Status.Installed) { 'Green' } else { 'Yellow' }
Write-Host " $tag $($i.Name) - $($i.Status.Detail)" -ForegroundColor $color
}
Write-Host ""
$missing = $items | Where-Object { -not $_.Status.Installed }
if ($missing.Count -eq 0) {
Write-Host "All checked items satisfied. No action needed." -ForegroundColor Green
return
}
if ($CheckOnly) {
Write-Host "$($missing.Count) item(s) need attention. Re-run without -CheckOnly to install." -ForegroundColor Yellow
return
}
Write-Host "$($missing.Count) item(s) need to be installed/configured:" -ForegroundColor Yellow
$missing | ForEach-Object { Write-Host " - $($_.Name)" }
Write-Host ""
if (-not $Apply) {
$response = Read-Host "Apply fixes now? [Y/N]"
if ($response -notmatch '^[Yy]') {
Write-Host "Aborted by user." -ForegroundColor Yellow
return
}
}
# --- Apply ------------------------------------------------------------------
foreach ($i in $missing) {
Write-Host ""
Write-Host "Applying: $($i.Name)" -ForegroundColor Cyan
try {
& $i.Installer
Write-Host " Done." -ForegroundColor Green
} catch {
Write-Host " FAILED: $($_.Exception.Message)" -ForegroundColor Red
}
}
# --- Re-verify --------------------------------------------------------------
Write-Host ""
Write-Host "Re-verifying state..." -ForegroundColor Cyan
Write-Host ""
$finalItems = @(
@{ Name = 'VC++ Redistributable (x64)'; Status = (Get-VcRedistStatus) }
@{ Name = 'New Teams (per-machine)'; Status = (Get-NewTeamsStatus) }
@{ Name = 'Remote Desktop WebRTC'; Status = (Get-WebRtcStatus) }
@{ Name = 'IsWVDEnvironment registry'; Status = (Get-WvdRegistryStatus) }
)
foreach ($i in $finalItems) {
$tag = if ($i.Status.Installed) { '[ OK ]' } else { '[ STILL MISSING ]' }
$color = if ($i.Status.Installed) { 'Green' } else { 'Red' }
Write-Host " $tag $($i.Name) - $($i.Status.Detail)" -ForegroundColor $color
}
Write-Host ""
Write-Host "Session Host Teams optimization complete." -ForegroundColor Cyan
Write-Host "A user logon (or reboot) may be needed for Teams to pick up the WVD environment flag."
Write-Host ""
Updated on: 16/06/2026
Thank you!
