Universal Uninstaller
Log In or Register to download the BES file, and more.

0 Votes

Description

This task will uninstall any program that matches the entered Display Name.

Display Name selects the program to uninstall by matching the DisplayName value in the registry for the program.
Example: Google Chrome

Match Type determines if an exact match or partial match is used for the Display Name value. If "Notepad" is entered for the Display Name, Exact would uninstall programs named exactly "Notepad", Partial would also uninstall something like "Notepad++".
Options: Exact, Partial

Version specifies to uninstall all versions less than this value.
Example: 1.2.0.0

Version Inclusion determines if the specified version is included or excluded from being uninstalled. If "1.2.0.0" is entered for Version, Exclude would uninstall any version less than 1.2.0.0, Include would also uninstall 1.2.0.0.
Options: Exclude, Include

MSI Switch adds a switch to the uninstaller's executable. Only applies to MSI uninstallers.
Example: /qn /norestart FULL_UNINSTALL=YES

EXE Switch adds a switch to the uninstaller's executable. Only applies to EXE uninstallers. Recommended to leave blank unless the program's uninstall method does not run silently.
Example: /silent

Exit Codes defines a list of exit codes returned from the uninstaller that indicate success. Enter these as a list of comma separated values.
Example: 0,1,3010

Force determines if the uninstall registry key is forcibly removed if the uninstaller executable isn't detected. Recommended to leave False.
Options: True, False


Property Details

ID27371
StatusBeta - Preliminary testing ready for more
TitleUniversal Uninstaller
DomainBESC
SourceInternal
Source Release Date1/7/2025 12:00:00 AM
Keywordsuninstall, uninstallstring, msi, msiexec, exe, gui, parameter
Is TaskTrue
Added by on 1/21/2025 1:38:46 PM
Last Modified by on 1/21/2025 1:38:46 PM
Counters 132 Views / 4 Downloads
User Rating 1 star 2 star 3 star 4 star 5 star * Average over 0 ratings. ** Log In or Register to add your rating.

Relevance

Used in 95 fixlets and 101 analyses   * Results in a true/false
Show indented relevance
true

Actions

Action 1 (default)

Action Link Click here to deploy this action.
Script Type BigFix Action Script
// Disable redirecting 64-bit registry paths to 32-bit paths
action uses wow64 redirection false

parameter "ScriptPath" = "__Download\UniversalUninstaller.ps1"

// Delete PowerShell script if already detected to prevent errors w/ copy action
if {exists parameter "ScriptPath"}
delete {parameter "ScriptPath"}

// Create PowerShell script
createfile until ENDOFSCRIPT

param (
    [Parameter(Mandatory)]
    [string]$displayName,
    [ValidateSet('Exact', 'Partial')]
    [string]$matchType = 'Exact',
    [version]$version = '9999.0.0.0',
    [ValidateSet('Exclude', 'Include')]
    [string]$versionInclusion = 'Exclude',
    [string]$msiSwitch = '/qn',
    [string]$exeSwitch = $null,
    [array]$exitCodes = (0,3010),
    [switch]$force
)

# Revert whitespace parameters to default values
if ([string]::IsNullOrWhiteSpace($msiSwitch)) {{ $msiSwitch = '/qn' }
if ([string]::IsNullOrWhiteSpace($exeSwitch)) {{ $exeSwitch = $null }
if ([string]::IsNullOrWhiteSpace($exitCodes)) {{ $exitCodes = (0,3010) }

# Get all uninstall registry keys
$uninstallPaths =
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"

$uninstallString = Get-ChildItem $uninstallPaths | ForEach-Object {{
    Get-ItemProperty -LiteralPath $_.PsPath | Where-Object {{
        $item = $_

        $condition1 = switch ($matchType) {{
            'Exact' {{$item.DisplayName -eq $displayName}
            'Partial' {{$item.DisplayName -match $displayName}
        }
        $condition2 = switch ($versionInclusion) {{
            'Exclude' {{[version]$item.DisplayVersion -lt $version}
            'Include' {{[version]$item.DisplayVersion -le $version}
        }

        $condition1 -and $condition2
    } | Select-Object PsPath, DisplayName, UninstallString, QuietUninstallString
}

$uninstallString | ForEach-Object {{
    $_.DisplayName

    $string = $(
        if ([string]::IsNullOrWhiteSpace($_.QuietUninstallString)) {{ $_.UninstallString }
        else {{ $_.QuietUninstallString }
    ) -replace '(?)([a-zA-Z]:\\[^"]+\.(bat|cmd|exe|msi))(?!")', '"$1"'

    $uninstallParams = @{{
        Wait        = $true
        PassThru    = $true
    }

    # If uninstall string is msiexec uninstaller
    if ($string -match '/[IX]\{{[^}]*\}') {{
        $uninstallParams.FilePath = $string.Replace($matches[0], '')
        $uninstallParams.ArgumentList =
            if ($uninstallParams.ArgumentList -match $msiSwitch) {{ $matches[0] }
            else {{ $matches[0] + " $msiSwitch" }
    # If uninstall string is .cmd/.bat/.exe uninstaller
    } elseif ($string -match '"[^"]*"') {{
        $uninstallParams.FilePath = $matches[0]
        if ($exeSwitch) {{
            $uninstallParams.ArgumentList = $exeSwitch
        } elseif (![string]::IsNullOrWhiteSpace($string.Replace($matches[0], ''))) {{
            $uninstallParams.ArgumentList = $string.Replace($matches[0], '')
        }

        # Remove registry key if -Force switch used and executable doesn't exist
        if (!(Test-Path $matches[0])) {{
            if ($force) {{
                Remove-Item -LiteralPath $_.PsPath -Force -Recurse
            } else {{
                Write-Host "- Uninstaller not detected"
                Write-Host " $($matches[0])"
                $throw = $true
            }

            return
        }
    } else {{
        return
    }

    # Start uninstaller
    $process = Start-Process @uninstallParams

    # Check if uninstalled successfully
    if ((Test-Path -LiteralPath $_.PsPath) -and ($process.ExitCode -notin $exitCodes)) {{
        Write-Host "- Failed to uninstall"
        Write-Host " ExitCode = $($process.ExitCode)"
        $throw = $true
    } else {{
        Write-Host "- Uninstalled"
    }
}

# Throw if any uninstall failed
if ($throw) {{ throw }

ENDOFSCRIPT

// Run PowerShell script
copy __createfile {parameter "ScriptPath"}
wait powershell.exe -ExecutionPolicy Bypass -File "{parameter "ScriptPath"}" -DisplayName "{parameter "DisplayName"}" -MatchType {parameter "MatchType"} -Version "{parameter "Version"}" -VersionInclusion {parameter "VersionInclusion"} -MsiSwitch "{parameter "MsiSwitch"}" -ExeSwitch "{parameter "ExeSwitch"}" -ExitCodes {parameter "ExitCodes"} {if parameter "Force" = "True" then "-Force" else ""}
delete {parameter "ScriptPath"}
Success Criteria

This action will be considered successful when the applicability relevance evaluates to false.


Sharing

Social Media:
Share this page on Yammer

Comments

Log In or Register to leave comments!