# Remove-SpecificTeamsVersions.ps1 # Removes specified vulnerable/old versions of classic Microsoft Teams and Teams Machine-Wide Installer. # Leaves new Teams / MSTeams MSIX app installed. $ErrorActionPreference = "Continue" Write-Output "Starting targeted Microsoft Teams cleanup..." # Versions to remove $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" ) # Stop Teams-related processes $ProcessNames = @( "Teams", "ms-teams", "msteams", "Microsoft.Teams", "Update" ) foreach ($ProcessName in $ProcessNames) { Get-Process -Name $ProcessName -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue } Start-Sleep -Seconds 5 # Registry uninstall locations $UninstallRegistryPaths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) # Remove matching Teams Machine-Wide Installer versions Write-Output "Checking for targeted Teams Machine-Wide Installer versions..." $MachineWideInstallers = foreach ($Path in $UninstallRegistryPaths) { Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "Teams Machine-Wide Installer" -and $TargetVersions -contains $_.DisplayVersion } } foreach ($App in $MachineWideInstallers) { Write-Output "Found targeted Teams Machine-Wide Installer: $($App.DisplayVersion)" if ($App.UninstallString -match "\{[A-Fa-f0-9\-]{36}\}") { $ProductCode = $Matches[0] Write-Output "Removing Teams Machine-Wide Installer using MSI product code: $ProductCode" Start-Process -FilePath "msiexec.exe" ` -ArgumentList "/x $ProductCode /qn /norestart" ` -Wait } elseif ($App.UninstallString) { Write-Output "Removing Teams Machine-Wide Installer using uninstall string." Start-Process -FilePath "cmd.exe" ` -ArgumentList "/c $($App.UninstallString) /quiet /norestart" ` -Wait } else { Write-Output "No uninstall string found for Teams Machine-Wide Installer version $($App.DisplayVersion)." } } # Remove matching classic Teams per-user installs Write-Output "Checking user profiles for targeted classic Teams versions..." $UserProfiles = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notin @( "Public", "Default", "Default User", "All Users", "defaultuser0" ) } foreach ($Profile in $UserProfiles) { $TeamsFolder = Join-Path $Profile.FullName "AppData\Local\Microsoft\Teams" $UpdateExe = Join-Path $TeamsFolder "Update.exe" $CurrentExe = Join-Path $TeamsFolder "current\Teams.exe" if (-not (Test-Path $TeamsFolder)) { continue } $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 ($TargetVersions -contains $DetectedVersion) { Write-Output "Found targeted classic Teams version $DetectedVersion in profile: $($Profile.Name)" if (Test-Path $UpdateExe) { Write-Output "Attempting silent uninstall for profile: $($Profile.Name)" Start-Process -FilePath $UpdateExe ` -ArgumentList "--uninstall -s" ` -Wait ` -ErrorAction SilentlyContinue Start-Sleep -Seconds 3 } if (Test-Path $TeamsFolder) { Write-Output "Removing remaining classic Teams folder for profile: $($Profile.Name)" Remove-Item -Path $TeamsFolder -Recurse -Force -ErrorAction SilentlyContinue } } else { Write-Output "Skipping profile $($Profile.Name). Classic Teams version '$DetectedVersion' is not in target list." } } # Check HKCU-style per-user uninstall entries under user registry hives if loaded Write-Output "Checking loaded user registry hives for targeted classic Teams uninstall entries..." $LoadedUserUninstallPaths = Get-ChildItem "Registry::HKEY_USERS" -ErrorAction SilentlyContinue | ForEach-Object { "Registry::$($_.Name)\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" } foreach ($Path in $LoadedUserUninstallPaths) { $UserTeamsApps = Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object { ( $_.DisplayName -eq "Microsoft Teams" -or $_.DisplayName -eq "MicrosoftTeams" ) -and $TargetVersions -contains $_.DisplayVersion } foreach ($App in $UserTeamsApps) { Write-Output "Found targeted per-user Teams uninstall entry: $($App.DisplayName) $($App.DisplayVersion)" if ($App.UninstallString) { Start-Process -FilePath "cmd.exe" ` -ArgumentList "/c $($App.UninstallString) --uninstall -s" ` -Wait ` -ErrorAction SilentlyContinue } } } # Verify new Teams remains installed Write-Output "Checking for new Teams / MSTeams..." $NewTeams = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq "MSTeams" } if ($NewTeams) { Write-Output "New Teams / MSTeams is installed and was left in place:" $NewTeams | Select-Object Name, Version, PackageFullName | Format-List | Out-String | Write-Output } else { Write-Output "WARNING: New Teams / MSTeams was not detected." } # Final verification Write-Output "Performing final verification..." $RemainingMachineWide = foreach ($Path in $UninstallRegistryPaths) { Get-ItemProperty $Path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "Teams Machine-Wide Installer" -and $TargetVersions -contains $_.DisplayVersion } } $RemainingClassicTeamsFolders = foreach ($Profile in $UserProfiles) { $TeamsFolder = Join-Path $Profile.FullName "AppData\Local\Microsoft\Teams" $CurrentExe = Join-Path $TeamsFolder "current\Teams.exe" if (Test-Path $CurrentExe) { $Version = (Get-Item $CurrentExe).VersionInfo.FileVersion if ($TargetVersions -contains $Version) { [PSCustomObject]@{ Profile = $Profile.Name Version = $Version Path = $TeamsFolder } } } } if ($RemainingMachineWide -or $RemainingClassicTeamsFolders) { Write-Output "Targeted Teams cleanup completed, but some targeted versions may still remain." if ($RemainingMachineWide) { Write-Output "Remaining Teams Machine-Wide Installer entries:" $RemainingMachineWide | Select-Object DisplayName, DisplayVersion, UninstallString | Format-Table -AutoSize | Out-String | Write-Output } if ($RemainingClassicTeamsFolders) { Write-Output "Remaining classic Teams folders:" $RemainingClassicTeamsFolders | Format-Table -AutoSize | Out-String | Write-Output } exit 1 } else { Write-Output "Targeted Teams versions were successfully removed or were not present." exit 0 }