#Requires -RunAsAdministrator <# .SYNOPSIS Removes specific vulnerable/outdated versions of Classic Teams and New Teams (MSTeams). .DESCRIPTION Checks for targeted build numbers across Classic Teams (Machine-Wide Installer, user AppData) and New Teams (MSIX AppX provisioned and per-user packages), cleanly uninstalling only the matching versions while leaving compliant versions untouched. #> $ErrorActionPreference = "Continue" Write-Host "Starting targeted Microsoft Teams cleanup..." -ForegroundColor Cyan # Targeted vulnerable versions (includes Classic Teams 1.x and New Teams 23x/24x/25x builds) $TargetVersions = @( "24334.1103.3302.5694", "25045.406.3471.2143", "24124.2402.2858.5617", "24004.1403.2634.2418", "23195.1506.2253.6778", "24277.3102.3183.2670", "24256.2502.3123.1", "24165.1306.2986.9504", "25031.702.3408.1909", "24244.507.3118.4732", "23119.303.2080.2726", "1.7.0.7956", "25044.2208.3471.2155", "24348.802.3311.5092", "23335.242.2641.4129" ) # Helper function for version string normalization & comparison function Test-IsTargetVersion { param ( [string]$VersionString, [string[]]$TargetList ) if ([string]::IsNullOrWhiteSpace($VersionString)) { return$false } $cleanVersion =$VersionString.Trim() if ($TargetList -contains $cleanVersion) { return$true } try { $parsedVersion = [version]$cleanVersion foreach ($target in$TargetList) { try { if ([version]$target -eq $parsedVersion) { return$true } } catch {} } } catch {} return $false } # 1. Safely stop targeted processes Write-Host "Checking for running processes..." -ForegroundColor Cyan Get-Process -Name "Teams" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Get-Process -Name "Update" -ErrorAction SilentlyContinue | Where-Object { $_.Path -like "*\Microsoft\Teams\Update.exe" } | Stop-Process -Force -ErrorAction SilentlyContinue # Stop ms-teams ONLY if the running executable belongs to a target version Get-Process -Name "ms-teams" -ErrorAction SilentlyContinue | ForEach-Object { $procVersion =$_.MainModule.FileVersionInfo.FileVersion if (Test-IsTargetVersion -VersionString $procVersion -TargetList$TargetVersions) { Write-Host "Stopping New Teams process (running vulnerable version $procVersion)..." -ForegroundColor Yellow Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue } } # 2. Remediate targeted Teams Machine-Wide Installer (HKLM) Write-Host "`nScanning Teams Machine-Wide Installer..." -ForegroundColor Cyan $UninstallRegistryPaths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) foreach ($path in $UninstallRegistryPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "Teams Machine-Wide Installer" -and (Test-IsTargetVersion -VersionString $_.DisplayVersion -TargetList $TargetVersions) } | ForEach-Object { Write-Host "Found targeted Machine-Wide Installer version: $($_.DisplayVersion)" -ForegroundColor Yellow if ($_.UninstallString -match "\{[A-Fa-f0-9\-]{36}\}") { $productCode = $Matches[0] Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $productCode /qn /norestart" -Wait -NoNewWindow } elseif ($_.UninstallString) { Start-Process -FilePath "cmd.exe" -ArgumentList "/c `"$($_.UninstallString)`" /quiet /norestart" -Wait -NoNewWindow } } } # 3. Remediate targeted Classic Teams (User Profiles) Write-Host "`nScanning user profiles for Classic Teams..." -ForegroundColor Cyan $usersRoot = Join-Path$env:SystemDrive "Users" $userProfiles = Get-ChildItem -Path $usersRoot -Directory -ErrorAction SilentlyContinue \vert{} Where-Object {$_.Name -notin @("Public", "Default", "Default User", "All Users", "defaultuser0") } foreach ($profile in$userProfiles) { $localTeamsFolder = Join-Path$profile.FullName "AppData\Local\Microsoft\Teams" $roamingTeamsFolder = Join-Path$profile.FullName "AppData\Roaming\Microsoft\Teams" $currentExe = Join-Path$localTeamsFolder "current\Teams.exe" $updateExe = Join-Path$localTeamsFolder "Update.exe" if (Test-Path $localTeamsFolder) { $detectedVersion =$null if (Test-Path $currentExe) { $detectedVersion = (Get-Item$currentExe).VersionInfo.FileVersion } if (-not $detectedVersion -and (Test-Path$updateExe)) { $detectedVersion = (Get-Item$updateExe).VersionInfo.FileVersion } if (Test-IsTargetVersion -VersionString $detectedVersion -TargetList$TargetVersions) { Write-Host "Removing Classic Teams ($detectedVersion) for profile: $($profile.Name)" -ForegroundColor Yellow if (Test-Path $updateExe) { Start-Process -FilePath $updateExe -ArgumentList "--uninstall -s" -Wait -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 } Remove-Item -Path $localTeamsFolder -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path $roamingTeamsFolder -Recurse -Force -ErrorAction SilentlyContinue } } } # 4. Remediate targeted New Teams (AppX / MSIX Packages) Write-Host "`nScanning New Teams (MSTeams) MSIX packages..." -ForegroundColor Cyan # Remove provisioned package if version matches Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "MSTeams" -and (Test-IsTargetVersion -VersionString $_.Version -TargetList $TargetVersions) } | ForEach-Object { Write-Host "Removing targeted provisioned MSTeams package version: $($_.Version)" -ForegroundColor Yellow Remove-AppxProvisionedPackage -Online -PackageName $_.PackageName -ErrorAction SilentlyContinue } # Remove per-user AppX packages if version matches Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue | Where-Object { Test-IsTargetVersion -VersionString $_.Version -TargetList $TargetVersions } | ForEach-Object { Write-Host "Removing targeted MSTeams AppX package version: $($_.Version) for all users" -ForegroundColor Yellow Remove-AppxPackage -Package $_.PackageFullName -AllUsers -ErrorAction SilentlyContinue } # 5. Clean Startup Run Keys across loaded user hives $hkuPath = "Registry::HKEY_USERS" Get-ChildItem -Path $hkuPath -ErrorAction SilentlyContinue | ForEach-Object { $runKey = Join-Path $_.PSPath "Software\Microsoft\Windows\CurrentVersion\Run" if (Test-Path $runKey) { $val = Get-ItemProperty -Path $runKey -Name "com.squirrel.teams.teams" -ErrorAction SilentlyContinue if ($val) { Remove-ItemProperty -Path $runKey -Name "com.squirrel.teams.teams" -ErrorAction SilentlyContinue } } } # 6. Final Verification Write-Host "`nPerforming final verification..." -ForegroundColor Cyan $remainingMachineWide = foreach ($path in$UninstallRegistryPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue \vert{} Where-Object {$_.DisplayName -eq "Teams Machine-Wide Installer" -and (Test-IsTargetVersion -VersionString $_.DisplayVersion -TargetList$TargetVersions) } } $remainingClassicFolders = foreach ($profile in$userProfiles) { $exe = Join-Path$profile.FullName "AppData\Local\Microsoft\Teams\current\Teams.exe" if (Test-Path $exe) { $ver = (Get-Item$exe).VersionInfo.FileVersion if (Test-IsTargetVersion -VersionString $ver -TargetList $TargetVersions) {$exe } } } $remainingNewTeams = Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue | Where-Object { Test-IsTargetVersion -VersionString $_.Version -TargetList$TargetVersions } if ($remainingMachineWide -or $remainingClassicFolders -or$remainingNewTeams) { Write-Host "ERROR: Some targeted Teams versions still remain on the endpoint." -ForegroundColor Red exit 1 } else { Write-Host "Targeted Teams remediation completed successfully." -ForegroundColor Green # Display active/healthy New Teams version if installed $healthyTeams = Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue if ($healthyTeams) { Write-Host "Active, non-vulnerable New Teams installation detected:" -ForegroundColor Green $healthyTeams | Select-Object Name, Version, PackageFullName | Format-Table -AutoSize | Out-String | Write-Host } exit 0 }