When Mozilla Firefox is marked as unsanctioned in our environment, my next move is to clean up existing installs across all managed devices.
Before we standardized our browsers, users were free to install whatever they liked, which left Firefox scattered across hundreds of endpoints. I don’t waste time with manual cleanup; I’ve automated the entire process.
Scoping at Scale with KQL
I start by getting a clear picture of the “infestation.” I use KQL (Kusto Query Language) in Defender Advanced Hunting to see exactly which versions are out there and how many devices are affected:
// My Firefox Discovery Query
DeviceTvmSoftwareInventory
| where SoftwareName contains "Firefox"
| summarize DeviceCount = dcount(DeviceName), Versions = make_set(SoftwareVersion) by SoftwareName
| order by DeviceCount desc
This query gives me an immediate count and version list, which I use to target my Intune remediations effectively.
The Strategy: Automating the Cleanup
I use Intune Proactive Remediation with a two-script system:
- Detection: Finds Firefox in the registry, Program Files, and user profiles.
- Remediation: Wipes everything—processes, files, shortcuts, services, and scheduled tasks.
Detection Logic
My script scans three main areas where Firefox likes to hide:
- Registry - 64-bit/32-bit uninstall keys and per-user installs.
- Program Files - Standard install locations.
- User Profiles - AppData folders.
$findings = @()
$uninstallPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
)
foreach ($path in $uninstallPaths) {
if (Test-Path $path) {
$apps = Get-ItemProperty "$path\*" -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName -like "*Firefox*" }
foreach ($app in $apps) {
$findings += "Registry: $($app.DisplayName)"
}
}
}
if ($findings.Count -gt 0) { exit 1 } else { exit 0 }
Full script: firefox-removal-detection.ps1
The Kill: Remediation
My remediation script is designed to be thorough. It stops all active processes before attempting the uninstall to ensure nothing is locked.
- Stop Processes - Firefox, plugin-container, and updaters.
- Uninstall - Uses the registry uninstall string (handles helper.exe and msiexec).
- Cleanup - Deletes directories in Program Files, ProgramData, and AppData.
- Final Polish - Removes shortcuts, the MozillaMaintenance service, and update tasks.
# My Process Kill List
$firefoxProcesses = @("firefox", "firefox-esr", "plugin-container", "crashreporter", "updater")
foreach ($proc in $firefoxProcesses) {
Get-Process -Name $proc -ErrorAction SilentlyContinue | Stop-Process -Force
}
Full script: firefox-removal-remediation.ps1
Outcome and Verification
I monitor the progress directly in the Intune portal under Devices > Scripts and remediations.
Success looks like a “fixed” status on my devices. I also check my custom logs at C:\ProgramData\Eriteach\Logs\ if I see any stubborn installs that require a manual look.
Lessons Learned
- User Profiles - The script cleans all profiles on the machine. I always warn users that bookmarks and saved passwords will be gone.
- Force Close - Since I force-close the process, I run this remediation during off-hours or maintenance windows to minimize disruption.
Related Links
- Auto-Update Firefox with Intune - My workflow for when I need to keep Firefox but stay updated.
- Intune Remediations overview
- Microsoft Defender software inventory