Last active
January 24, 2026 17:59
-
-
Save asheroto/4b1313fc41b3801a1362d421ff577406 to your computer and use it in GitHub Desktop.
Forcefully removes Webroot Endpoint Protection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires -RunAsAdministrator | |
| <# | |
| .SYNOPSIS | |
| Force removes Webroot SecureAnywhere remnants. | |
| .DESCRIPTION | |
| Designed to be run in Safe Mode. Performs process termination, uninstall attempt, | |
| service removal, registry cleanup, and filesystem cleanup with existence checks. | |
| #> | |
| #region Guardrails | |
| function Test-IsAdmin { | |
| $CurrentUser = [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent() | |
| return $CurrentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | |
| } | |
| function Test-IsSafeMode { | |
| return (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SafeBoot\Option" -ErrorAction SilentlyContinue) -ne $null | |
| } | |
| if (-not (Test-IsAdmin)) { | |
| Write-Output "ERROR: Script must be run as Administrator." | |
| exit 1 | |
| } | |
| if (-not (Test-IsSafeMode)) { | |
| Write-Output "WARNING: System is not in Safe Mode. Cleanup may be incomplete." | |
| } | |
| #endregion | |
| #region Helper Functions | |
| function Remove-RegistryKey { | |
| param ([string]$Path) | |
| if (Test-Path $Path) { | |
| Write-Output "Removing registry key: $Path" | |
| Remove-Item -Path $Path -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| function Remove-Folder { | |
| param ([string]$Path) | |
| if (Test-Path $Path) { | |
| Write-Output "Removing folder: $Path" | |
| Remove-Item -Path $Path -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| function Remove-ServiceSafe { | |
| param ([string]$Name) | |
| $Service = Get-WmiObject -Class Win32_Service -Filter "Name='$Name'" -ErrorAction SilentlyContinue | |
| if ($null -ne $Service) { | |
| Write-Output "Disabling service: $Name" | |
| Set-Service -Name $Name -StartupType Disabled -ErrorAction SilentlyContinue | |
| Write-Output "Stopping service: $Name" | |
| Stop-Service -Name $Name -Force -ErrorAction SilentlyContinue | |
| Write-Output "Deleting service via sc.exe: $Name" | |
| sc.exe delete $Name | Out-Null | |
| } | |
| $SvcRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$Name" | |
| if (Test-Path $SvcRegPath) { | |
| Write-Output "Removing remaining service registry key: $SvcRegPath" | |
| Remove-Item -Path $SvcRegPath -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| #endregion | |
| #region Kill Processes First | |
| $Processes = @("WRSA","WRSVC","WRCore","WRSkyClient") | |
| foreach ($Proc in $Processes) { | |
| Get-Process -Name $Proc -ErrorAction SilentlyContinue | ForEach-Object { | |
| Write-Output "Killing process: $($_.Name)" | |
| $_.Kill() | |
| } | |
| } | |
| #endregion | |
| #region Attempt Official Uninstall | |
| $WrsaPaths = @( | |
| "$Env:ProgramFiles\Webroot\WRSA.exe", | |
| "$Env:ProgramFiles(x86)\Webroot\WRSA.exe" | |
| ) | |
| foreach ($Wrsa in $WrsaPaths) { | |
| if (Test-Path $Wrsa) { | |
| Write-Output "Attempting uninstall via: $Wrsa" | |
| Start-Process -FilePath $Wrsa -ArgumentList "-uninstall -quiet" -Wait -ErrorAction SilentlyContinue | |
| } | |
| } | |
| #endregion | |
| #region Services | |
| $ServiceNames = @( | |
| "WRSVC", | |
| "WRCoreService", | |
| "WRkrn", | |
| "WRBoot", | |
| "wrUrlFlt", | |
| "WRSkyClient" | |
| ) | |
| foreach ($ServiceName in $ServiceNames) { | |
| Remove-ServiceSafe -Name $ServiceName | |
| } | |
| #endregion | |
| #region Registry Cleanup | |
| $ControlSets = Get-ChildItem "HKLM:\SYSTEM" | Where-Object { $_.Name -like "*ControlSet*" } | |
| $RegKeys = @( | |
| "HKLM:\SOFTWARE\WRData", | |
| "HKLM:\SOFTWARE\WRMIDData", | |
| "HKLM:\SOFTWARE\WRCore", | |
| "HKLM:\SOFTWARE\webroot", | |
| "HKLM:\SOFTWARE\WOW6432Node\WRData", | |
| "HKLM:\SOFTWARE\WOW6432Node\WRMIDData", | |
| "HKLM:\SOFTWARE\WOW6432Node\WRCore", | |
| "HKLM:\SOFTWARE\WOW6432Node\webroot", | |
| "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WRUNINST", | |
| "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\WRUNINST" | |
| ) | |
| foreach ($Key in $RegKeys) { | |
| Remove-RegistryKey -Path $Key | |
| } | |
| foreach ($CS in $ControlSets) { | |
| foreach ($Svc in $ServiceNames) { | |
| Remove-RegistryKey -Path "$($CS.PSPath)\Services\$Svc" | |
| } | |
| } | |
| #endregion | |
| #region Startup Entries | |
| $StartupPaths = @( | |
| "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", | |
| "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" | |
| ) | |
| foreach ($Path in $StartupPaths) { | |
| if (Test-Path $Path) { | |
| $Props = Get-ItemProperty -Path $Path | |
| foreach ($Prop in $Props.PSObject.Properties) { | |
| if ($Prop.Value -match "Webroot|WRSA") { | |
| Write-Output "Removing startup entry '$($Prop.Name)' from $Path" | |
| Remove-ItemProperty -Path $Path -Name $Prop.Name -ErrorAction SilentlyContinue | |
| } | |
| } | |
| } | |
| } | |
| #endregion | |
| #region Filesystem Cleanup | |
| $Folders = @( | |
| "$Env:ProgramData\WRData", | |
| "$Env:ProgramData\WRCore", | |
| "$Env:ProgramFiles\Webroot", | |
| "$Env:ProgramFiles(x86)\Webroot", | |
| "$Env:ProgramFiles\Common Files\Webroot", | |
| "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Webroot SecureAnywhere", | |
| "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\OpenText Core Endpoint Protection" | |
| ) | |
| foreach ($Folder in $Folders) { | |
| Remove-Folder -Path $Folder | |
| } | |
| #endregion | |
| #region Uninstall Entry Scan | |
| $UninstallRoots = @( | |
| "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", | |
| "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | |
| ) | |
| foreach ($Root in $UninstallRoots) { | |
| Get-ChildItem $Root -ErrorAction SilentlyContinue | ForEach-Object { | |
| $Props = Get-ItemProperty $_.PsPath -ErrorAction SilentlyContinue | |
| if ($null -ne $Props.DisplayName -and $Props.DisplayName -match "Webroot") { | |
| Write-Output "Removing uninstall entry: $($Props.DisplayName)" | |
| Remove-Item -Path $_.PsPath -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| } | |
| } | |
| #endregion | |
| #region Verification | |
| $RemainingServices = @() | |
| foreach ($Svc in $ServiceNames) { | |
| $Query = sc.exe query $Svc 2>$null | |
| if ($Query -and ($Query -notmatch "FAILED 1060")) { | |
| $RemainingServices += $Svc | |
| } | |
| } | |
| if ($RemainingServices.Count -gt 0) { | |
| Write-Output "NOTICE: Services pending removal until reboot:" | |
| $RemainingServices | ForEach-Object { Write-Output " - $_" } | |
| Write-Output "Reboot is required to complete removal." | |
| } else { | |
| Write-Output "Verification passed: No remaining Webroot services detected." | |
| } | |
| #endregion | |
| Write-Output "Webroot cleanup completed. Please reboot the computer." | |
| exit 0 |
Author
@chadmark thanks for the info. For some reason on my computer, it has the TM symbol. I made some major revisions and added support for both, just in case.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am trying this against a number of machines we have rouge Webroot installs on. I did need to make one correction because of an error. On line 51, "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\OpenText™ Core Endpoint Protection",. The TM after OpenText throws a powershell error. Some unsupported character. Once I removed that, it ran properly. Waiting for the user to reboot and we will see if it works!