# Remove-ClassicTeams.ps1 # Removes classic Microsoft Teams and Teams Machine-Wide Installer. # Leaves new Teams / MSTeams MSIX app installed. $ErrorActionPreference = "Continue" Write-Output "Starting classic Teams cleanup..." # Stop Teams-related processes $processNames = @( "Teams", "ms-teams", "msteams", "Microsoft.Teams", "Update" ) foreach ($process in $processNames) { Get-Process -Name $process -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue } Start-Sleep -Seconds 5 # Remove Teams Machine-Wide Installer from HKLM uninstall registry $uninstallPaths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $machineWideInstallers = foreach ($path in $uninstallPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "Teams Machine-Wide Installer" } } foreach ($app in $machineWideInstallers) { Write-Output "Found Teams Machine-Wide Installer: $($app.DisplayName) $($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 "Attempting uninstall using uninstall string: $($app.UninstallString)" Start-Process -FilePath "cmd.exe" -ArgumentList "/c $($app.UninstallString) /quiet /norestart" -Wait } } # Remove classic Teams per-user installs $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" if (Test-Path $updateExe) { Write-Output "Uninstalling classic Teams 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 } } # Remove common classic Teams leftovers $leftoverPaths = @( "$env:ProgramData\Microsoft\Teams", "$env:ProgramData\Microsoft\TeamsMachineInstaller" ) foreach ($path in $leftoverPaths) { if (Test-Path $path) { Write-Output "Removing leftover path: $path" Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue } } # Confirm new Teams remains installed $newTeams = Get-AppxPackage -AllUsers | Where-Object { $_.Name -eq "MSTeams" } if ($newTeams) { Write-Output "New Teams detected and left installed:" $newTeams | Select-Object Name, Version, PackageFullName | Format-List | Out-String | Write-Output } else { Write-Output "WARNING: New Teams / MSTeams was not detected after cleanup." } # Final verification for classic Teams entries $remainingMachineWide = foreach ($path in $uninstallPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq "Teams Machine-Wide Installer" } } $remainingClassicFolders = foreach ($profile in $userProfiles) { $teamsFolder = Join-Path $profile.FullName "AppData\Local\Microsoft\Teams" if (Test-Path $teamsFolder) { $teamsFolder } } if ($remainingMachineWide -or $remainingClassicFolders) { Write-Output "Classic Teams cleanup completed, but some remnants may remain." if ($remainingMachineWide) { $remainingMachineWide | Select-Object DisplayName, DisplayVersion | Format-Table | Out-String | Write-Output } if ($remainingClassicFolders) { $remainingClassicFolders | ForEach-Object { Write-Output "Remaining folder: $_" } } exit 1 } else { Write-Output "Classic Teams and Teams Machine-Wide Installer cleanup completed successfully." exit 0 }