- teams: harden Classic Teams removal, protect New Teams, and clean HKU run keys - dotnet: add bootstrapper EXE uninstall support and remove orphaned 3.1.* folders - teams: add MSIX package targeting and version parsing for vulnerable New Teams builds - m365: improve Graph SDK export speed, reuse sessions, and add null-safe handling
135 lines
5.7 KiB
PowerShell
135 lines
5.7 KiB
PowerShell
#Requires -RunAsAdministrator
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Removes Classic Microsoft Teams and Teams Machine-Wide Installer.
|
|
.DESCRIPTION
|
|
Stops Classic Teams processes, uninstalls the Machine-Wide Installer via MSI,
|
|
removes per-user Classic Teams installations, cleans residual files/registry run keys,
|
|
and verifies that New Teams (MSTeams) remains intact.
|
|
#>
|
|
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
Write-Host "Starting Classic Microsoft Teams cleanup..." -ForegroundColor Cyan
|
|
|
|
# 1. Stop ONLY Classic Teams processes (preserve New Teams)
|
|
Get-Process -Name "Teams" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
|
|
# Stop Update.exe processes originating specifically from Classic Teams directories
|
|
Get-Process -Name "Update" -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.Path -like "*\Microsoft\Teams\Update.exe"
|
|
} | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
|
|
Start-Sleep -Seconds 3
|
|
|
|
# 2. Remove Teams Machine-Wide Installer from HKLM 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 \vert{} Where-Object {$_.DisplayName -eq "Teams Machine-Wide Installer"
|
|
}
|
|
}
|
|
|
|
foreach ($app in$machineWideInstallers) {
|
|
Write-Host "Found Teams Machine-Wide Installer: $($app.DisplayName) $($app.DisplayVersion)" -ForegroundColor Yellow
|
|
|
|
if ($app.UninstallString -match "\{[A-Fa-f0-9\-]{36}\}") {
|
|
$productCode =$Matches[0]
|
|
Write-Host "Uninstalling Machine-Wide Installer via MSI product code: $productCode" -ForegroundColor Cyan
|
|
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $productCode /qn /norestart" -Wait -NoNewWindow
|
|
}
|
|
elseif ($app.UninstallString) {
|
|
Write-Host "Uninstalling via UninstallString: $($app.UninstallString)" -ForegroundColor Cyan
|
|
if ($app.UninstallString -match "msiexec") {
|
|
$args =$app.UninstallString -replace "msiexec.exe", "" -replace "/I", "/x"
|
|
Start-Process -FilePath "msiexec.exe" -ArgumentList "$args /qn /norestart" -Wait -NoNewWindow
|
|
} else {
|
|
Start-Process -FilePath "cmd.exe" -ArgumentList "/c `"$($app.UninstallString)`" /quiet /norestart" -Wait -NoNewWindow
|
|
}
|
|
}
|
|
}
|
|
|
|
# 3. Clean per-user Classic Teams installations
|
|
$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"
|
|
$updateExe = Join-Path$localTeamsFolder "Update.exe"
|
|
|
|
if (Test-Path $updateExe) {
|
|
Write-Host "Uninstalling Classic Teams for profile: $($profile.Name)" -ForegroundColor Cyan
|
|
Start-Process -FilePath $updateExe -ArgumentList "--uninstall -s" -Wait -ErrorAction SilentlyContinue
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
|
|
# Remove residual AppData folders (both Local and Roaming)
|
|
foreach ($folder in @($localTeamsFolder,$roamingTeamsFolder)) {
|
|
if (Test-Path $folder) {
|
|
Write-Host "Removing directory: $folder" -ForegroundColor Yellow
|
|
Remove-Item -Path $folder -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# 4. Remove System-Wide ProgramData Leftovers
|
|
$leftoverPaths = @(
|
|
"$env:ProgramData\Microsoft\Teams",
|
|
"$env:ProgramData\Microsoft\TeamsMachineInstaller",
|
|
"$env:ProgramData\Microsoft\TeamsCustomData"
|
|
)
|
|
|
|
foreach ($path in$leftoverPaths) {
|
|
if (Test-Path $path) {
|
|
Write-Host "Removing leftover ProgramData path: $path" -ForegroundColor Yellow
|
|
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
# 5. Clean Startup Registry 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) {
|
|
Write-Host "Removing Classic Teams startup reg key from hive: $($_.PSChildName)" -ForegroundColor Yellow
|
|
Remove-ItemProperty -Path $runKey -Name "com.squirrel.teams.teams" -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# 6. Confirm New Teams (MSTeams) status
|
|
$newTeams = Get-AppxPackage -Name "MSTeams" -AllUsers -ErrorAction SilentlyContinue
|
|
|
|
if ($newTeams) {
|
|
Write-Host "New Teams (MSTeams) is installed:" -ForegroundColor Green
|
|
$newTeams | Select-Object Name, Version, PackageFullName | Format-Table -AutoSize | Out-String | Write-Host
|
|
} else {
|
|
Write-Host "WARNING: New Teams (MSTeams) was not detected on this device." -ForegroundColor Red
|
|
}
|
|
|
|
# 7. Final Verification
|
|
$remainingMachineWide = foreach ($path in$uninstallPaths) {
|
|
Get-ItemProperty $path -ErrorAction SilentlyContinue \vert{} Where-Object {$_.DisplayName -eq "Teams Machine-Wide Installer"
|
|
}
|
|
}
|
|
|
|
$remainingClassicFolders = foreach ($profile in$userProfiles) {
|
|
$localTeamsFolder = Join-Path$profile.FullName "AppData\Local\Microsoft\Teams"
|
|
if (Test-Path $localTeamsFolder) {$localTeamsFolder }
|
|
}
|
|
|
|
if ($remainingMachineWide -or$remainingClassicFolders) {
|
|
Write-Host "Cleanup completed, but some Classic Teams remnants remain." -ForegroundColor Red
|
|
exit 1
|
|
} else {
|
|
Write-Host "Classic Teams and Teams Machine-Wide Installer cleanup completed successfully." -ForegroundColor Green
|
|
exit 0
|
|
} |