refactor(scripts): optimize system remediation and M365 export scripts

- 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
This commit is contained in:
mattspeer committed 2026-10-04 10:58:05 -05:00
1 parent 4fd95b76d6
commit 5ef82842f2
19 files changed
+1651 -1268

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
#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
}