Remove-HPWolfSecurity.ps1

<#PSScriptInfo

.VERSION 1.0.0
.GUID a0dd5902-8d07-4dad-87ec-a4a7785c12f4
.AUTHOR V1s1t0r
.COMPANYNAME V1s1t0r
.COPYRIGHT (c) 2026 V1s1t0r. All rights reserved.
.TAGS Windows HP Wolf Security uninstall cleanup bloatware
.LICENSEURI https://opensource.org/licenses/MIT

#>


<#
.SYNOPSIS
Removes HP Wolf Security components.

.DESCRIPTION
Searches for and completely uninstalls HP Wolf Security, Sure Click, Sure Sense, and Bromium components.
Cleans background services, scheduled tasks, residual directories, and registry remnants.

.EXAMPLE
.\Remove-HPWolfSecurity.ps1
Executes the removal workflow with administrator privileges.
#>


#Requires -RunAsAdministrator

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param()

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'

$script:RebootRequired = $false
$ProgramFilesX86 = ${env:ProgramFiles(x86)}

# ------------------------------------------------------------
# FAST PRE-CHECK
# ------------------------------------------------------------
function Test-HpWolfInstalled {
    [CmdletBinding()]
    param()

    # 1. Registry uninstall keys
    $uninstallKeys = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    )
    foreach ($regPath in $uninstallKeys) {
        if (-not (Test-Path -LiteralPath $regPath)) { continue }
        $found = Get-ChildItem -Path $regPath -ErrorAction SilentlyContinue | Where-Object {
            $dn = $_.GetValue('DisplayName', $null) -as [string]
            $cn = $_.PSChildName
            ($cn -match 'HP Wolf|HP Security|Sure Click|Sure Sense|Bromium') -or
            ($dn -match 'HP Wolf|HP Security|Sure Click|Sure Sense|Bromium')
        }
        if ($found) { return $true }
    }

    # 2. Services
    $svc = Get-Service -ErrorAction SilentlyContinue | Where-Object {
        $_.Name -match 'HP.*Wolf|HP.*Security|SureClick|SureSense|Bromium' -or
        $_.DisplayName -match 'HP.*Wolf|HP.*Security|SureClick|SureSense|Bromium'
    }
    if ($svc) { return $true }

    # 3. Directories
    $dirPaths = @(
        "$env:ProgramFiles\HP\HP Wolf Security",
        "$ProgramFilesX86\HP\HP Wolf Security",
        "$env:ProgramFiles\Bromium",
        "$ProgramFilesX86\Bromium",
        "$env:ProgramData\HP\HP Wolf Security",
        "$env:ProgramData\Bromium"
    )
    foreach ($p in $dirPaths) {
        if (Test-Path -LiteralPath $p) { return $true }
    }

    # 4. Processes
    $proc = Get-Process -ErrorAction SilentlyContinue | Where-Object {
        $_.Name -match 'HP\.Wolf|HPSecurity|SureClick|SureSense|Bromium|HPWolf'
    }
    if ($proc) { return $true }

    return $false
}

function Test-PendingReboot {
    [CmdletBinding()]
    param()

    $checkPaths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired',
        'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
    )

    foreach ($path in $checkPaths) {
        if (Test-Path -Path $path) {
            if ($path -eq 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager') {
                $value = (Get-Item -Path $path -ErrorAction SilentlyContinue).GetValue('PendingFileRenameOperations', $null)
                if ($null -ne $value) { return $true }
            }
            else {
                return $true
            }
        }
    }
    return $false
}

function Stop-HpWolfProcesses {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Host '[INFO] Checking for running HP Wolf / Bromium processes...'
    $targetProcesses = Get-Process -ErrorAction SilentlyContinue | Where-Object {
        $_.Name -match 'HP\.Wolf|HPSecurity|SureClick|SureSense|Bromium|HPWolf'
    }

    foreach ($proc in $targetProcesses) {
        try {
            if ($PSCmdlet.ShouldProcess($proc.ProcessName, 'Kill process')) {
                Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
                Write-Host "[INFO] Terminated process '$($proc.ProcessName)' (PID: $($proc.Id))."
            }
        }
        catch {
            Write-Warning "Could not terminate process '$($proc.ProcessName)'."
        }
    }
}

function Remove-HpWolfMsiProducts {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Host '[INFO] Scanning Windows Installer database...'
    $allProducts = Get-CimInstance -ClassName Win32_Product -ErrorAction SilentlyContinue
    if (-not $allProducts) {
        Write-Host '[INFO] Win32_Product catalog returned no entries.'
        return
    }

    $patterns = @(
        'HP Wolf*',
        'HP Security*',
        'Wolf Security*',
        '*Wolf*Security*',
        '*Security Update Service*',
        '*Sure Click*',
        '*Sure Sense*',
        '*Bromium*'
    )

    $matchingProducts = @()
    foreach ($pattern in $patterns) {
        $matchingProducts += @($allProducts | Where-Object { $_.Name -like $pattern })
    }
    $matchingProducts = @($matchingProducts | Sort-Object Name -Unique)

    if ($matchingProducts.Count -eq 0) {
        Write-Host '[INFO] No matching HP Wolf products found in Windows Installer catalog.'
        return
    }

    Write-Host "[INFO] Found $($matchingProducts.Count) product(s) to uninstall."

    foreach ($item in $matchingProducts) {
        try {
            Write-Host "[INFO] Preparing to uninstall '$($item.Name)'..."
            if ($PSCmdlet.ShouldProcess($item.Name, 'Uninstall')) {
                $exitCode = 0

                if ($item.IdentifyingNumber -and $item.IdentifyingNumber -match '^\{[0-9A-Fa-f\-]+\}$') {
                    Write-Host "[INFO] Executing msiexec /x $($item.IdentifyingNumber) /qn /norestart..."
                    $proc = Start-Process -FilePath 'msiexec.exe' `
                        -ArgumentList "/x `"$($item.IdentifyingNumber)`" /qn /norestart" `
                        -Wait -PassThru -NoNewWindow
                    $exitCode = $proc.ExitCode
                }
                else {
                    $cimResult = Invoke-CimMethod -InputObject $item -MethodName 'Uninstall'
                    if ($cimResult -and $null -ne $cimResult.ReturnValue) {
                        $exitCode = [int]$cimResult.ReturnValue
                    }
                }

                switch ($exitCode) {
                    0    { Write-Host "[INFO] Successfully uninstalled '$($item.Name)'." }
                    3010 {
                        $script:RebootRequired = $true
                        Write-Host "[INFO] '$($item.Name)' uninstalled (reboot queued)." -ForegroundColor Yellow
                    }
                    1605 { Write-Host "[INFO] '$($item.Name)' is already uninstalled." }
                    default { Write-Warning "[$($item.Name)] uninstall returned exit code $exitCode." }
                }
            }
        }
        catch {
            Write-Warning "[$($item.Name)] uninstall failed: $($_.Exception.Message)"
        }

        Start-Sleep -Seconds 1
    }
}

function Remove-RegistryInstalledHpWolf {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    $uninstallKeys = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    )

    foreach ($regPath in $uninstallKeys) {
        if (-not (Test-Path -Path $regPath)) { continue }

        $subKeys = Get-ChildItem -Path $regPath -ErrorAction SilentlyContinue
        foreach ($key in $subKeys) {
            $displayName = $key.GetValue('DisplayName', $null) -as [string]
            $uninstallStr = $key.GetValue('UninstallString', $null) -as [string]

            if (-not $displayName) { continue }
            if ($displayName -notmatch 'HP Wolf|HP Security|Sure Click|Sure Sense|Bromium') { continue }

            Write-Host "[INFO] Found registry entry: '$displayName'..."
            if ($PSCmdlet.ShouldProcess($displayName, 'Uninstall via registry command')) {
                if ($uninstallStr -and $uninstallStr -match '\{[0-9A-Fa-f\-]+\}') {
                    $guid = $Matches[0]
                    Write-Host "[INFO] Executing msiexec /x $guid /qn /norestart for '$displayName'..."
                    $proc = Start-Process -FilePath 'msiexec.exe' `
                        -ArgumentList "/x `"$guid`" /qn /norestart" `
                        -Wait -PassThru -NoNewWindow
                    if ($proc.ExitCode -eq 3010) { $script:RebootRequired = $true }
                }
                elseif ($uninstallStr) {
                    Write-Host "[INFO] Invoking uninstall string for '$displayName'..."
                    try {
                        Start-Process -FilePath 'cmd.exe' -ArgumentList "/c `"$uninstallStr`" /qn /silent /norestart" -Wait -NoNewWindow -ErrorAction SilentlyContinue
                    }
                    catch {
                        Write-Warning "Could not run uninstaller for '$displayName'."
                    }
                }
            }
        }
    }
}

function Remove-HpWolfRemnants {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Host '[INFO] Cleaning up services...'
    $servicePatterns = @(
        'HP*Wolf*',
        'HP*Security*',
        'Wolf*Security*',
        '*Bromium*',
        '*SureClick*',
        '*SureSense*'
    )

    foreach ($pattern in $servicePatterns) {
        $services = Get-Service -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -like $pattern -or $_.DisplayName -like $pattern }

        foreach ($svc in $services) {
            if ($svc.Status -ne 'Stopped') {
                try {
                    if ($PSCmdlet.ShouldProcess($svc.Name, 'Stop service')) {
                        Stop-Service -Name $svc.Name -Force -ErrorAction SilentlyContinue
                        Write-Host "[INFO] Stopped service '$($svc.Name)'."
                    }
                }
                catch {
                    Write-Warning "Unable to stop service '$($svc.Name)': $($_.Exception.Message)"
                }
            }

            try {
                if ($PSCmdlet.ShouldProcess($svc.Name, 'Set service to Disabled')) {
                    Set-Service -Name $svc.Name -StartupType Disabled -ErrorAction SilentlyContinue
                    & sc.exe config "$($svc.Name)" start= disabled 2>$null | Out-Null
                    Write-Host "[INFO] Disabled service '$($svc.Name)'."
                }
            }
            catch {
                Write-Warning "Unable to disable service '$($svc.Name)'."
            }
        }
    }

    Write-Host '[INFO] Cleaning up scheduled tasks...'
    $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue |
        Where-Object {
            $_.TaskName -match 'HP.*Wolf|HP.*Security|Wolf.*Security|HP Wolf|HP Security|SureClick|SureSense|Bromium' -or
            $_.TaskPath -match 'HP.*Wolf|HP.*Security|Wolf.*Security|HP Wolf|HP Security|SureClick|SureSense|Bromium'
        }

    foreach ($task in $tasks) {
        try {
            if ($PSCmdlet.ShouldProcess($task.TaskName, 'Unregister scheduled task')) {
                Unregister-ScheduledTask -TaskName $task.TaskName -TaskPath $task.TaskPath -Confirm:$false -ErrorAction SilentlyContinue
                Write-Host "[INFO] Removed scheduled task '$($task.TaskName)'."
            }
        }
        catch {
            Write-Warning "Unable to unregister scheduled task '$($task.TaskName)': $($_.Exception.Message)"
        }
    }

    Write-Host '[INFO] Cleaning up leftover files and folders...'
    $pathsToClean = @(
        "$env:ProgramFiles\HP\Wolf*",
        "$env:ProgramFiles\HP\*Wolf*",
        "$env:ProgramFiles\HP\HP Security",
        "$env:ProgramFiles\HP\HP Sure Click",
        "$env:ProgramFiles\HP\HP Sure Sense",
        "$env:ProgramFiles\Bromium",
        "$ProgramFilesX86\HP\Wolf*",
        "$ProgramFilesX86\HP\*Wolf*",
        "$ProgramFilesX86\HP\HP Security",
        "$ProgramFilesX86\HP\HP Sure Click",
        "$ProgramFilesX86\HP\HP Sure Sense",
        "$ProgramFilesX86\Bromium",
        "$env:ProgramData\HP\Wolf*",
        "$env:ProgramData\HP\*Wolf*",
        "$env:ProgramData\HP\HP Security",
        "$env:ProgramData\HP\HP Sure Click",
        "$env:ProgramData\HP\HP Sure Sense",
        "$env:ProgramData\Bromium",
        "$env:LOCALAPPDATA\HP\Wolf*",
        "$env:LOCALAPPDATA\HP\*Wolf*",
        "$env:LOCALAPPDATA\HP\HP Security",
        "$env:LOCALAPPDATA\Bromium"
    )

    foreach ($pathPattern in $pathsToClean) {
        Get-ChildItem -Path $pathPattern -ErrorAction SilentlyContinue | ForEach-Object {
            try {
                if ($PSCmdlet.ShouldProcess($_.FullName, 'Delete file or directory')) {
                    Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
                    Write-Host "[INFO] Removed leftover path '$($_.FullName)'."
                }
            }
            catch {
                Write-Warning "Unable to remove path '$($_.FullName)': $($_.Exception.Message)"
            }
        }
    }

    Write-Host '[INFO] Cleaning up leftover registry keys...'
    $registryRoots = @(
        'HKLM:\SOFTWARE\HP',
        'HKLM:\SOFTWARE\WOW6432Node\HP',
        'HKLM:\SOFTWARE\Bromium',
        'HKLM:\SOFTWARE\WOW6432Node\Bromium',
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    )

    foreach ($root in $registryRoots) {
        if (-not (Test-Path -Path $root)) { continue }

        Get-ChildItem -Path $root -ErrorAction SilentlyContinue | ForEach-Object {
            $keyName = $_.PSChildName
            $displayName = $_.GetValue('DisplayName', $null) -as [string]

            if ($keyName -match 'HP Wolf|HP Security|Wolf Security|Bromium|SureClick|SureSense' -or
                $displayName -match 'HP Wolf|HP Security|Wolf Security|Bromium|SureClick|SureSense') {
                try {
                    if ($PSCmdlet.ShouldProcess($_.Name, 'Delete registry key')) {
                        Remove-Item -Path $_.PSPath -Recurse -Force -ErrorAction SilentlyContinue
                        Write-Host "[INFO] Removed registry key '$($_.Name)'."
                    }
                }
                catch {
                    Write-Warning "Unable to remove registry key '$($_.Name)': $($_.Exception.Message)"
                }
            }
        }
    }
}

function Invoke-HpWolfRemoval {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Stop-HpWolfProcesses
    Remove-HpWolfMsiProducts
    Remove-RegistryInstalledHpWolf
    Remove-HpWolfRemnants

    if (Test-PendingReboot) {
        $script:RebootRequired = $true
    }
}

# ------------------------------------------------------------
# MAIN EXECUTION
# ------------------------------------------------------------
try {
    Write-Host '==================================================' -ForegroundColor Cyan
    Write-Host '[INFO] Checking for HP Wolf Security installation...' -ForegroundColor Cyan
    Write-Host '==================================================' -ForegroundColor Cyan

    if (-not (Test-HpWolfInstalled)) {
        Write-Host '[INFO] No HP Wolf Security components detected on this system.' -ForegroundColor Green
        Write-Host '[INFO] Skipping removal — nothing to do.' -ForegroundColor Green
        Start-Sleep -Seconds 2
        exit 0
    }

    Write-Host '[INFO] HP Wolf Security components detected. Initiating removal...' -ForegroundColor Yellow
    Invoke-HpWolfRemoval

    Write-Host '--------------------------------------------------'
    $stillInstalled = Test-HpWolfInstalled
    if ($stillInstalled) {
        if ($script:RebootRequired) {
            Write-Host '[INFO] Components are queued for final removal on next restart.' -ForegroundColor Yellow
        }
        else {
            Write-Warning 'Some HP Wolf remnants may still be present. A manual check is recommended.'
        }
    }
    else {
        Write-Host '[INFO] All HP Wolf components removed cleanly.' -ForegroundColor Green
    }

    if ($script:RebootRequired -or (Test-PendingReboot)) {
        Write-Host '[INFO] Low-level drivers queued for cleanup on next PC restart.' -ForegroundColor Yellow
    }

    Write-Host '==================================================' -ForegroundColor Cyan
    Write-Host '[INFO] HP Wolf removal process finished.' -ForegroundColor Cyan
    Write-Host '==================================================' -ForegroundColor Cyan

    Start-Sleep -Seconds 3
}
catch {
    Write-Error "HP Wolf Removal encountered an error: $($_.Exception.Message)"
    Start-Sleep -Seconds 3
    exit 1
}