[QuickPost] (new) Microsoft Teams VDI – Monitoring API Script (W365, AVD, Citrix)
UPDATE 23rd of May 2025
After a conversation with Fernando K. and Kenny W. from Microsoft, I realized that my initial approach to detecting Teams optimization didn’t cover all possible scenarios and was a bit too simplistic.
I’ve now updated the script in blog, github and also ControlUp to incorporate these new insights, and I’m releasing version 1.1 for download.
The vdiMode parameter behaves as follows…
The first digit indicates the vendor of the remoting solution:
1 and 2 = Citrix
3 = Horizon
5 = AVD / Windows 365
The second digit represents the type of optimization:
1 = Not optimized
2 = WebRTC
3 = SlimCore
It’s important to note that SlimCore is only fully utilized if the vdiConnectedState is set to “remote”.
=======================================
On May 6, 2025, Fernando Klurfan—former Citrix rockstar and now Microsoft rockstar—published an insightful blog post introducing a range of new features for Microsoft Teams for VDI:
Microsoft Teams VDI – State of the Union, Spring 2025
Among the many exciting enhancements, one feature in particular caught my attention: Monitoring API.
This new API opens up promising possibilities for administrators and EUC professionals. It provides real-time visibility into key telemetry and session data, allowing for better troubleshooting, diagnostics, and performance monitoring of Teams running inside virtualized environments like Citrix, Omnissa Horizon, or AVD/W365.
Fernando even references a potential PowerShell script that can query and display live telemetry data from Teams when running in VDI mode.
I found this especially compelling—so much so that I asked ChatGPT to help me create such a script. The result works remarkably well, and I’d like to share it with you.
The script interacts with the new Monitoring API and pulls live data from a running Teams session. Depending on the optimization method used, the output varies:
- SlimCore Optimized
- WebRTC Optimized
WebRTC optimization doesnt throw that much information…
- Not optimized
<screenshot follows>
You can get the script here or at Github (CLICK HERE):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
<# .SYNOPSIS Parses the Teams VDI connection info JSON file and outputs key session details including VDI optimization status, connected state, software versions, and peripheral device info. .DESCRIPTION This script reads the 'vdi_connection_info.json' file from the Teams cache directory in a VDI environment. It extracts details such as VDI Optimization version, connection state, Teams and plugin versions, client platform, OS version, available and selected peripherals, and secondary ringer. Additionally, it converts timestamps to human-readable format and resolves OS build numbers to friendly Windows or Windows Server version names. .EXAMPLE PS C:\> .\Get-TeamsOptimization.ps1 Outputs all current session info from the Teams VDI JSON file in a readable format. .EXAMPLE PS C:\> .\Get-TeamsOptimization.ps1 | Out-File .\TeamsVDIReport.txt Exports the session info to a text file for review. .NOTES Version: 1.1 Author: Markus Zehnle (ChatGPT tbh) Created: 2025-05-19 Updated: 2025-05-23 Requires: PowerShell 5.1 or later JSON Source: C:\Users\<username>\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\tfw\vdi_connection_info.json .VERSION HISTORY 1.0 2025-05-19 Initial version 1.1 2025-05-23 Added detailed vdiMode parsing (Thanks Fernando K. and Kenny W. from Microsoft) .LINK Microsoft Teams VDI Monitoring API documentation https://learn.microsoft.com/en-us/microsoftteams/vdi-2#monitoring-api #> $tfwPath = "$env:LOCALAPPDATA\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\tfw\vdi_connection_info.json" if (-Not (Test-Path -Path $tfwPath)) { Write-Error "The file vdi_connection_info.json cannot be found: $tfwPath" exit 1 } $jsonContent = Get-Content -Path $tfwPath -Raw | ConvertFrom-Json $session = $jsonContent.VdiConnectionInfo | Select-Object -Last 1 $vdiState = $session.vdiConnectedState $vdiVersion = $session.vdiVersionInfo $devices = $session.devices $timestampReadable = (Get-Date -Date "1970-01-01 00:00:00Z").AddMilliseconds($vdiState.timestamp).ToLocalTime().ToString("dd.MM.yyyy HH:mm:ss") function Get-WindowsVersionName { try { $osInfo = Get-ItemProperty -Path "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" $actualBuild = $osInfo.CurrentBuildNumber $actualMinor = $osInfo.UBR $sku = $osInfo.EditionID $productName = $osInfo.ProductName } catch { return "Unknown Windows Version" } $versionName = switch ($true) { ($actualBuild -eq 26100 -and $productName -like "*Server*") { "Windows Server 2025" } ($actualBuild -eq 26100) { "Windows 11 24H2" } ($actualBuild -eq 25300) { "Windows 11 Insider Dev" } ($actualBuild -eq 22631) { "Windows 11 23H2" } ($actualBuild -eq 22621) { "Windows 11 22H2" } ($actualBuild -eq 22000) { "Windows 11 21H2" } ($actualBuild -eq 20348) { "Windows Server 2022" } ($actualBuild -eq 19045) { "Windows 10 22H2" } ($actualBuild -eq 19044) { "Windows 10 21H2" } ($actualBuild -eq 17763) { "Windows Server 2019" } default { "Unknown Windows Version" } } return "$versionName (OS Build $actualBuild.$actualMinor) [$sku]" } function Get-DeviceLabels { param ($deviceList) return ($deviceList | ForEach-Object { $_.label }) -join ', ' } function Get-VdiModeDetails { param ([string]$vdiMode) if (-not $vdiMode -or $vdiMode.Length -lt 4) { return "Unknown (Invalid Code)" } $platformCode = $vdiMode.Substring(0, 1) $optimizationCode = $vdiMode.Substring(1, 1) $platform = switch ($platformCode) { "1" { "Citrix" } "2" { "Citrix" } "3" { "Horizon" } "5" { "AVD/W365" } default { "Unknown Platform" } } $optimization = switch ($optimizationCode) { "0" { "not optimized" } "1" { "WebRTC optimized" } "2" { "SlimCore optimized" } default { "Unknown Optimization" } } return "$platform $optimization ($vdiMode)" } Write-Host "`n=== Microsoft Teams VDI Monitoring ===" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "Session Timestamp", $timestampReadable) Write-Host ("{0,-25}: {1}" -f "VM OS Version", (Get-WindowsVersionName)) #Write-Host ("{0,-25}: {1}" -f "Connected Stack", $vdiState.connectedStack) Write-Host ("{0,-25}: {1}" -f "VDI Mode Details", (Get-VdiModeDetails $vdiState.vdiMode)) # SlimCore-specific section with correct condition if ($vdiState.vdiMode.Substring(1,1) -eq "2" -and $vdiState.connectedStack -eq "remote") { Write-Host "`n--- SlimCore Optimization Information ---" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "SlimCore Version", $vdiVersion.remoteSlimcoreVersion) Write-Host ("{0,-25}: {1}" -f "VDIBridge Version", $vdiVersion.bridgeVersion) Write-Host ("{0,-25}: {1}" -f "Teams Plugin Version", $vdiVersion.pluginVersion) Write-Host ("{0,-25}: {1}" -f "Teams Version", $vdiVersion.teamsVersion) Write-Host "`n--- Remote Client Information ---" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "Remote Client", $vdiVersion.rdClientProductName) Write-Host ("{0,-25}: {1}" -f "Remote Client Version", $vdiVersion.rdClientVersion) Write-Host "`n--- Available Peripheral Devices ---" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "Speakers", (Get-DeviceLabels $devices.speaker.available)) Write-Host ("{0,-25}: {1}" -f "Cameras", (Get-DeviceLabels $devices.camera.available)) Write-Host ("{0,-25}: {1}" -f "Microphones", (Get-DeviceLabels $devices.microphone.available)) Write-Host "`n--- Selected Peripheral Devices ---" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "Speaker", $devices.speaker.selected) Write-Host ("{0,-25}: {1}" -f "Camera", $devices.camera.selected) Write-Host ("{0,-25}: {1}" -f "Microphone", $devices.microphone.selected) Write-Host ("{0,-25}: {1}" -f "Secondary Ringtone", $devices.secondaryRinger) } elseif ($vdiState.vdiMode.Substring(1,1) -eq "2") { Write-Host "`n--- SlimCore Optimization Information ---" -ForegroundColor Cyan Write-Host ("{0,-25}: {1}" -f "SlimCore Optimization", "Failed to load SlimCore optimization. Please restart Teams.") -ForegroundColor Red } |
As always, please exercise caution and review any script before executing it—especially those downloaded from the internet.
Disclaimer: I assume no liability for any damage caused by running this script.
You are very welcome to fix the bugs and modify the script on your behalf.
One More Thing
If you’re using ControlUp (like I do), you can download a ready-made XML version of the script here to import it into the ControlUp RealtimeDX Console.
Show Microsoft Teams for VDI Optimization (new Teams only).xml
A script for ControlUp for Desktops, aka EdgeDX, will follow soon.
It’s exciting to see Microsoft finally providing tools that enable deeper insight and better control over the virtualized Teams experience. I’m looking forward to seeing how this evolves—and to hearing how others are using it in their environments.
Let me know what you think—and feel free to improve or expand the script as needed!
2 thoughts on “[QuickPost] (new) Microsoft Teams VDI – Monitoring API Script (W365, AVD, Citrix)”
Brian Langston 23-05-2025 at 15:06
Hi, great script. One item I noticed is that on my machine, Slimcore optimization shows as mode 2201. I’ll check the others and update here as well.
Markus Zehnle 23-05-2025 at 15:18
Hi Brian,
thanks for testing.
I had a chat with Fernando an engineering which showed that my reverse engineering regarding vdiMode was not completely right 🙂
I hope I can update my script later…