top of page
Search

(184) Microsoft Intune - Removing Dell Bloatware and Dell Apps

  • Writer: Mr B SOE way
    Mr B SOE way
  • 5 hours ago
  • 11 min read

One of our customers listed me a detail list of Dell vulernable apps within their tenant. I tried to re-invent the wheel by using my HP Bloatware removal remediation script which did partial removing these bloatware apps.


I ended up using Andrew Taylor's script with some modifications in place by removing all the unwanted bloatware lines he has added, and only focusing on Dell bloatware and Dell installed apps.





############################################################################################################
#                                         Initial Setup                                                    #
#                                                                                                          #
############################################################################################################
param (
    [string[]]$customwhitelist,
    [string[]]$TasksToRemove  # Add this parameter for scheduled tasks to remove
)

##Elevate if needed

If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
    write-output "You didn't run this script as an Administrator. This script will self elevate to run as an Administrator and continue."
    Start-Sleep 1
    write-output "                                               3"
    Start-Sleep 1
    write-output "                                               2"
    Start-Sleep 1
    write-output "                                               1"
    Start-Sleep 1
    #Start-Process powershell.exe -ArgumentList ("-NoProfile -ExecutionPolicy Bypass -File `"{0}`" -WhitelistApps {1}" -f $PSCommandPath, ($WhitelistApps -join ',')) -Verb RunAs
    Start-Process powershell.exe -ArgumentList ("-NoProfile -ExecutionPolicy Bypass -File `"{0}`" -customwhitelist {1} -TasksToRemove {2}" -f $PSCommandPath, ($customwhitelist -join ','), ($TasksToRemove -join ',')) -Verb RunAs
    Exit
}

#Get the Current start time in UTC format, so that Time Zone Changes don't affect total runtime calculation
$startUtc = [datetime]::UtcNow
#no errors throughout
$ErrorActionPreference = 'silentlycontinue'
#no progressbars to slow down powershell transfers
$OrginalProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'


#Create Folder
$DebloatFolder = "C:\ProgramData\MrBSOEWay\logs"
If (Test-Path $DebloatFolder) {
    Write-Output "$DebloatFolder exists. Skipping."
}
Else {
    Write-Output "The folder '$DebloatFolder' doesn't exist. This folder will be used for storing logs created after the script runs. Creating now."
    Start-Sleep 1
    New-Item -Path "$DebloatFolder" -ItemType Directory
    Write-Output "The folder $DebloatFolder was successfully created."
}

Start-Transcript -Path "C:\ProgramData\MrBSOEWay\logs\Debloat.log"

function Remove-CustomScheduledTasks {
    param (
        [string[]]$TaskNames
    )

    Write-Output "Removing specified scheduled tasks..."

    foreach ($taskName in $TaskNames) {
        Write-Output "Attempting to remove task: $taskName"

        # Check if the task exists
        $task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue

        if ($task) {
            try {
                # First disable the task
                Disable-ScheduledTask -TaskName $taskName -ErrorAction Stop | Out-Null

                # Then unregister (remove) the task
                Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction Stop
                Write-Output "Successfully removed scheduled task: $taskName"
            }
            catch {
                Write-Output "Failed to remove scheduled task: $taskName. Error: $_"
            }
        }
        else {
            Write-Output "Scheduled task not found: $taskName"
        }
    }
}


############################################################################################################
#                                        Remove AppX Packages                                              #
#                                                                                                          #
############################################################################################################

#Removes AppxPackages
$WhitelistedApps = @(
    'Dell SupportAssist OS Recovery Plugin for Dell Update'
)
##If $customwhitelist is set, split on the comma and add to whitelist
if ($customwhitelist) {
    $customWhitelistApps = $customwhitelist -split ","
    foreach ($whitelistapp in $customwhitelistapps) {
        ##Add to the array
        $WhitelistedApps += $whitelistapp
    }
}

#NonRemovable Apps that where getting attempted and the system would reject the uninstall, speeds up debloat and prevents 'initalizing' overlay when removing apps
$NonRemovable = @(
)

##Combine the two arrays
$appstoignore = $WhitelistedApps += $NonRemovable

##Bloat list for future reference
$Bloatware = @(
    #Unnecessary Windows 10/11 AppX Apps
    "Dell Optimizer Core"
    "Dell SupportAssist Remediation"
    "Dell Pair"
    "Dell Display Manager 2.0"
    "Dell Display Manager 2.1"
    "Dell Display Manager 2.2"
    "Dell Peripheral Manager"
)


$provisioned = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -in $Bloatware -and $_.DisplayName -notin $appstoignore -and $_.DisplayName -notlike 'MicrosoftWindows.Voice*' -and $_.DisplayName -notlike 'Microsoft.LanguageExperiencePack*' -and $_.DisplayName -notlike 'MicrosoftWindows.Speech*' }
foreach ($appxprov in $provisioned) {
    $packagename = $appxprov.PackageName
    $displayname = $appxprov.DisplayName
    write-output "Removing $displayname AppX Provisioning Package"
    try {
        Remove-AppxProvisionedPackage -PackageName $packagename -Online -ErrorAction SilentlyContinue
        write-output "Removed $displayname AppX Provisioning Package"
    }
    catch {
        write-output "Unable to remove $displayname AppX Provisioning Package"
    }

}


$appxinstalled = Get-AppxPackage -AllUsers | Where-Object { $_.Name -in $Bloatware -and $_.Name -notin $appstoignore -and $_.Name -notlike 'MicrosoftWindows.Voice*' -and $_.Name -notlike 'Microsoft.LanguageExperiencePack*' -and $_.Name -notlike 'MicrosoftWindows.Speech*' }
foreach ($appxapp in $appxinstalled) {
    $packagename = $appxapp.PackageFullName
    $displayname = $appxapp.Name
    write-output "$displayname AppX Package exists"
    write-output "Removing $displayname AppX Package"
    try {
        Remove-AppxPackage -Package $packagename -AllUsers -ErrorAction SilentlyContinue
        write-output "Removed $displayname AppX Package"
    }
    catch {
        write-output "$displayname AppX Package does not exist"
    }



}

############################################################################################################
#                                       Grab all Uninstall Strings                                         #
#                                                                                                          #
############################################################################################################


write-output "Checking 32-bit System Registry"
##Search for 32-bit versions and list them
$allstring = @()
$path1 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
#Loop Through the apps if name has Adobe and NOT reader
$32apps = Get-ChildItem -Path $path1 | Get-ItemProperty | Select-Object -Property DisplayName, UninstallString

foreach ($32app in $32apps) {
    #Get uninstall string
    $string1 = $32app.uninstallstring
    #Check if it's an MSI install
    if ($string1 -match "^msiexec*") {
        #MSI install, replace the I with an X and make it quiet
        $string2 = $string1 + " /quiet /norestart"
        $string2 = $string2 -replace "/I", "/X "
        #Create custom object with name and string
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $32app.DisplayName
            String = $string2
        }
    }
    else {
        #Exe installer, run straight path
        $string2 = $string1
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $32app.DisplayName
            String = $string2
        }
    }

}
write-output "32-bit check complete"
write-output "Checking 64-bit System registry"
##Search for 64-bit versions and list them

$path2 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
#Loop Through the apps if name has Adobe and NOT reader
$64apps = Get-ChildItem -Path $path2 | Get-ItemProperty | Select-Object -Property DisplayName, UninstallString

foreach ($64app in $64apps) {
    #Get uninstall string
    $string1 = $64app.uninstallstring
    #Check if it's an MSI install
    if ($string1 -match "^msiexec*") {
        #MSI install, replace the I with an X and make it quiet
        $string2 = $string1 + " /quiet /norestart"
        $string2 = $string2 -replace "/I", "/X "
        #Uninstall with string2 params
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $64app.DisplayName
            String = $string2
        }
    }
    else {
        #Exe installer, run straight path
        $string2 = $string1
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $64app.DisplayName
            String = $string2
        }
    }

}

write-output "64-bit checks complete"

##USER
write-output "Checking 32-bit User Registry"
##Search for 32-bit versions and list them
$path1 = "HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
##Check if path exists
if (Test-Path $path1) {
    #Loop Through the apps if name has Adobe and NOT reader
    $32apps = Get-ChildItem -Path $path1 | Get-ItemProperty | Select-Object -Property DisplayName, UninstallString

    foreach ($32app in $32apps) {
        #Get uninstall string
        $string1 = $32app.uninstallstring
        #Check if it's an MSI install
        if ($string1 -match "^msiexec*") {
            #MSI install, replace the I with an X and make it quiet
            $string2 = $string1 + " /quiet /norestart"
            $string2 = $string2 -replace "/I", "/X "
            #Create custom object with name and string
            $allstring += New-Object -TypeName PSObject -Property @{
                Name   = $32app.DisplayName
                String = $string2
            }
        }
        else {
            #Exe installer, run straight path
            $string2 = $string1
            $allstring += New-Object -TypeName PSObject -Property @{
                Name   = $32app.DisplayName
                String = $string2
            }
        }
    }
}
write-output "32-bit check complete"
write-output "Checking 64-bit Use registry"
##Search for 64-bit versions and list them

$path2 = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
#Loop Through the apps if name has Adobe and NOT reader
$64apps = Get-ChildItem -Path $path2 | Get-ItemProperty | Select-Object -Property DisplayName, UninstallString

foreach ($64app in $64apps) {
    #Get uninstall string
    $string1 = $64app.uninstallstring
    #Check if it's an MSI install
    if ($string1 -match "^msiexec*") {
        #MSI install, replace the I with an X and make it quiet
        $string2 = $string1 + " /quiet /norestart"
        $string2 = $string2 -replace "/I", "/X "
        #Uninstall with string2 params
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $64app.DisplayName
            String = $string2
        }
    }
    else {
        #Exe installer, run straight path
        $string2 = $string1
        $allstring += New-Object -TypeName PSObject -Property @{
            Name   = $64app.DisplayName
            String = $string2
        }
    }

}


function UninstallAppFull {

    param (
        [string]$appName
    )

    # Get a list of installed applications from Programs and Features
    $installedApps = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,
    HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Where-Object { $null -ne $_.DisplayName } |
    Select-Object DisplayName, UninstallString

    $userInstalledApps = Get-ItemProperty HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Where-Object { $null -ne $_.DisplayName } |
    Select-Object DisplayName, UninstallString

    $allInstalledApps = $installedApps + $userInstalledApps | Where-Object { $_.DisplayName -eq "$appName" }

    # Loop through the list of installed applications and uninstall them

    foreach ($app in $allInstalledApps) {
        $uninstallString = $app.UninstallString
        $displayName = $app.DisplayName
        if ($uninstallString -match "^msiexec*") {
            #MSI install, replace the I with an X and make it quiet
            $string2 = $uninstallString + " /quiet /norestart"
            $string2 = $string2 -replace "/I", "/X "
        }
        else {
            #Exe installer, run straight path
            $string2 = $uninstallString
        }
        write-output "Uninstalling: $displayName"
        Start-Process $string2
        write-output "Uninstalled: $displayName" -ForegroundColor Green
    }
}


############################################################################################################
#                                        Remove Manufacturer Bloat                                         #
#                                                                                                          #
############################################################################################################
##Check Manufacturer
write-output "Detecting Manufacturer"
$details = Get-CimInstance -ClassName Win32_ComputerSystem
$manufacturer = $details.Manufacturer

if ($manufacturer -like "*Dell*") {
    write-output "Dell detected"
    #Remove Dell bloat

    ##Dell

    $UninstallPrograms = @(
        "Dell Optimizer"
        "Dell Power Manager"
        "DellOptimizerUI"
        "Dell SupportAssist OS Recovery"
        "Dell SupportAssist"
        "Dell Optimizer Service"
        "Dell Optimizer Core"
        "DellInc.PartnerPromo"
        "DellInc.DellOptimizer"
        "DellInc.DellCommandUpdate"
        "DellInc.DellPowerManager"
        "DellInc.DellDigitalDelivery"
        "DellInc.DellSupportAssistforPCs"
        "DellInc.PartnerPromo"
        "Dell Command | Update"
        "Dell Command | Update for Windows Universal"
        "Dell Command | Update for Windows 10"
        "Dell Command | Power Manager"
        "Dell Digital Delivery Service"
        "Dell Digital Delivery"
        "Dell Peripheral Manager"
        "Dell Power Manager Service"
        "Dell SupportAssist Remediation"
        "SupportAssist Recovery Assistant"
        "Dell SupportAssist OS Recovery Plugin for Dell Update"
        "Dell SupportAssistAgent"
        "Dell Update - SupportAssist Update Plugin"
        "Dell Core Services"
        "Dell Pair"
        "Dell Display Manager 2.0"
        "Dell Display Manager 2.1"
        "Dell Display Manager 2.2"
        "Dell SupportAssist Remediation"
        "Dell Update - SupportAssist Update Plugin"
        "DB6EA5DB.MediaSuiteEssentialsforDell"
        "DB6EA5DB.Power2GoforDell"
        "DB6EA5DB.PowerDirectorforDell"
        "DB6EA5DB.PowerMediaPlayerforDell"     
        "Dell Active Pen Service"
        "Dell ControlVault Host Components Installer 64 bit"
        "Dell Display and Peripheral Manager"
        "Dell Trusted Device"
        "Dell Trusted Device Agent"       
        "Dell Watchdog Timer"
        "Dell.SupportAssistforPCs"
        "DellDockFW_UPGRADE_UTILITY version 1.2"
        "DellInc.6066037A8FCF7"
        "DellInc.AlienwareCommandCenter"
        "DellInc.DellCommandUpdate"
        "DellInc.DellPrecisionOptimizer"  
    )



    $UninstallPrograms = $UninstallPrograms | Where-Object { $appstoignore -notcontains $_ }


    foreach ($app in $UninstallPrograms) {

        if (Get-AppxProvisionedPackage -Online | Where-Object DisplayName -like $app -ErrorAction SilentlyContinue) {
            Get-AppxProvisionedPackage -Online | Where-Object DisplayName -like $app | Remove-AppxProvisionedPackage -Online
            write-output "Removed provisioned package for $app."
        }
        else {
            write-output "Provisioned package for $app not found."
        }

        if (Get-AppxPackage -allusers -Name $app -ErrorAction SilentlyContinue) {
            Get-AppxPackage -allusers -Name $app | Remove-AppxPackage -AllUsers
            write-output "Removed $app."
        }
        else {
            write-output "$app not found."
        }

        UninstallAppFull -appName $app



    }

# Process each package pattern
foreach ($pattern in $uninstallPrograms) {
    $patternName = $pattern
    $minVersion = $pattern.MinVersion
    Write-Output "Checking for packages matching pattern: $patternName"

    # Search for matching packages in the registry
    $matchingPackages = @()
    
    # Check in 32-bit and 64-bit registry locations
    $registryPaths = @(
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    
    foreach ($registryPath in $registryPaths) {
        $packages = Get-ItemProperty -Path $registryPath -ErrorAction SilentlyContinue | 
                    Where-Object { $_.DisplayName -match $patternName }
        
        # Filter by minimum version if specified
        if ($minVersion -and $packages) {
            $packages = $packages | Where-Object { 
                if ($_.DisplayVersion) {
                    try {
                        [version]$_.DisplayVersion -ge [version]$minVersion
                    } catch {
                        # If version comparison fails, include it anyway for safety
                        $true
                    }
                } else {
                    # If no version information, include it for safety
                    $true
                }
            }
        }
        
        $matchingPackages += $packages
    }
    
    if ($matchingPackages.Count -eq 0) {
        Write-Output "No packages found matching pattern: $patternName"
        continue
    }
    
    Write-Output "Found $($matchingPackages.Count) package(s) matching pattern: $patternName"
    
    # Process each matching package
    foreach ($package in $matchingPackages) {
        $displayName = $package.DisplayName
        $uninstallString = $package.UninstallString
        $quietUninstallString = $package.QuietUninstallString
        $version = $package.DisplayVersion
        
        Write-Output "Attempting to uninstall: $displayName (Version: $version)"
        
        # Try to use the UninstallAppFull function first
        Write-Output "Trying to uninstall via UninstallAppFull..."
        UninstallAppFull -appName $displayName
        
        # If UninstallAppFull doesn't work, fall back to direct uninstallation
        # Check if uninstall string exists and attempt uninstall
        if ($quietUninstallString) {
            Write-Output "Using quiet uninstall string: $quietUninstallString"
            try {
                if ($quietUninstallString -match "msiexec") {
                    # For MSI-based uninstalls, add /quiet
                    $uninstallCommand = $quietUninstallString + " /quiet"
                    Start-Process "cmd.exe" -ArgumentList "/c $uninstallCommand" -Wait -NoNewWindow
                } else {
                    # For EXE-based uninstalls
                    $uninstallParts = $quietUninstallString -split ' ', 2
                    $uninstallExe = $uninstallParts[0].Trim('"')
                    $uninstallArgs = if ($uninstallParts.Count -gt 1) { $uninstallParts[1] } else { "" }
                    
                    Start-Process -FilePath $uninstallExe -ArgumentList $uninstallArgs -Wait -NoNewWindow
                }
                Write-Output "Quiet uninstall completed for: $displayName"
            } catch {
                Write-Output "Error during quiet uninstall: $_"
            }
        } elseif ($uninstallString) {
            Write-Output "Using standard uninstall string: $uninstallString"
            try {
                if ($uninstallString -match "msiexec") {
                    # For MSI-based uninstalls, add /quiet
                    if ($uninstallString -match "/I{") {
                        # Change /I to /X for uninstall if needed
                        $uninstallString = $uninstallString -replace "/I", "/X"
                    }
                    $uninstallCommand = $uninstallString + " /quiet"
                    Start-Process "cmd.exe" -ArgumentList "/c $uninstallCommand" -Wait -NoNewWindow
                } else {
                    # For EXE-based uninstalls
                    $uninstallParts = $uninstallString -split ' ', 2
                    $uninstallExe = $uninstallParts[0].Trim('"')
                    $uninstallArgs = if ($uninstallParts.Count -gt 1) { $uninstallParts[1] } else { "" }
                    
                    # Add silent parameters for common installers
                    if ($uninstallString -match "uninstall.exe|uninst.exe|setup.exe|installer.exe") {
                        $uninstallArgs += " /S /silent /quiet /uninstall"
                    }
                    
                    Start-Process -FilePath $uninstallExe -ArgumentList $uninstallArgs -Wait -NoNewWindow
                }
                Write-Output "Standard uninstall completed for: $displayName"
            } catch {
                Write-Output "Error during standard uninstall: $_"
            }
        } else {
            Write-Output "No uninstall string found for: $displayName"
        }
    }
}

    ##Belt and braces, remove via CIM too
    #foreach ($program in $UninstallPrograms) {
    #    write-output "Removing $program"
    #    Get-CimInstance -Query "SELECT * FROM Win32_Product WHERE name = '$program'" | Invoke-CimMethod -MethodName Uninstall
    #}

    ##Manual Removals

    ##Dell Optimizer
    $dellSA = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -like "Dell*Optimizer*Core" } | Select-Object -Property UninstallString

    ForEach ($sa in $dellSA) {
        If ($sa.UninstallString) {
            try {
                cmd.exe /c $sa.UninstallString -silent
            }
            catch {
                Write-Warning "Failed to uninstall Dell Optimizer"
            }
        }
    }


    ##Dell Dell SupportAssist Remediation
    $dellSA = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -match "Dell SupportAssist Remediation" } | Select-Object -Property QuietUninstallString

    ForEach ($sa in $dellSA) {
        If ($sa.QuietUninstallString) {
            try {
                cmd.exe /c $sa.QuietUninstallString
            }
            catch {
                Write-Warning "Failed to uninstall Dell Support Assist Remediation"
            }
        }
    }

    ##Dell Dell SupportAssist OS Recovery Plugin for Dell Update
    $dellSA = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -match "Dell SupportAssist OS Recovery Plugin for Dell Update" } | Select-Object -Property QuietUninstallString

    ForEach ($sa in $dellSA) {
        If ($sa.QuietUninstallString) {
            try {
                cmd.exe /c $sa.QuietUninstallString
            }
            catch {
                Write-Warning "Failed to uninstall Dell Support OS Recovery Plugin"
            }
        }
    }



    ##Dell Display Manager
    $dellSA = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -like "Dell*Display*Manager*" } | Select-Object -Property UninstallString

    ForEach ($sa in $dellSA) {
        If ($sa.UninstallString) {
            try {
                cmd.exe /c $sa.UninstallString /S
            }
            catch {
                Write-Warning "Failed to uninstall Dell Display Manager"
            }
        }
    }

    ##Dell Peripheral Manager

    try {
        start-process c:\windows\system32\cmd.exe '/c "C:\Program Files\Dell\Dell Peripheral Manager\Uninstall.exe" /S'
    }
    catch {
        Write-Warning "Failed to uninstall Dell Peripheral Manager"
    }


    ##Dell Pair

    try {
        start-process c:\windows\system32\cmd.exe '/c "C:\Program Files\Dell\Dell Pair\Uninstall.exe" /S'
    }
    catch {
        Write-Warning "Failed to uninstall Dell Pair"
    }

}


# Process each package pattern
foreach ($pattern in $uninstallPrograms) {
    $patternName = $pattern
    $minVersion = $pattern.MinVersion
    Write-Output "Checking for packages matching pattern: $patternName"

    # Search for matching packages in the registry
    $matchingPackages = @()
    
    # Check in 32-bit and 64-bit registry locations
    $registryPaths = @(
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    
    foreach ($registryPath in $registryPaths) {
        $packages = Get-ItemProperty -Path $registryPath -ErrorAction SilentlyContinue | 
                    Where-Object { $_.DisplayName -match $patternName }
        
        # Filter by minimum version if specified
        if ($minVersion -and $packages) {
            $packages = $packages | Where-Object { 
                if ($_.DisplayVersion) {
                    try {
                        [version]$_.DisplayVersion -ge [version]$minVersion
                    } catch {
                        # If version comparison fails, include it anyway for safety
                        $true
                    }
                } else {
                    # If no version information, include it for safety
                    $true
                }
            }
        }
        
        $matchingPackages += $packages
    }
    
    if ($matchingPackages.Count -eq 0) {
        Write-Output "No packages found matching pattern: $patternName"
        continue
    }
    
    Write-Output "Found $($matchingPackages.Count) package(s) matching pattern: $patternName"
    
    # Process each matching package
    foreach ($package in $matchingPackages) {
        $displayName = $package.DisplayName
        $uninstallString = $package.UninstallString
        $quietUninstallString = $package.QuietUninstallString
        $version = $package.DisplayVersion
        
        Write-Output "Attempting to uninstall: $displayName (Version: $version)"
        
        # Try to use the UninstallAppFull function first
        Write-Output "Trying to uninstall via UninstallAppFull..."
        UninstallAppFull -appName $displayName
        
        # If UninstallAppFull doesn't work, fall back to direct uninstallation
        # Check if uninstall string exists and attempt uninstall
        if ($quietUninstallString) {
            Write-Output "Using quiet uninstall string: $quietUninstallString"
            try {
                if ($quietUninstallString -match "msiexec") {
                    # For MSI-based uninstalls, add /quiet
                    $uninstallCommand = $quietUninstallString + " /quiet"
                    Start-Process "cmd.exe" -ArgumentList "/c $uninstallCommand" -Wait -NoNewWindow
                } else {
                    # For EXE-based uninstalls
                    $uninstallParts = $quietUninstallString -split ' ', 2
                    $uninstallExe = $uninstallParts[0].Trim('"')
                    $uninstallArgs = if ($uninstallParts.Count -gt 1) { $uninstallParts[1] } else { "" }
                    
                    Start-Process -FilePath $uninstallExe -ArgumentList $uninstallArgs -Wait -NoNewWindow
                }
                Write-Output "Quiet uninstall completed for: $displayName"
            } catch {
                Write-Output "Error during quiet uninstall: $_"
            }
        } elseif ($uninstallString) {
            Write-Output "Using standard uninstall string: $uninstallString"
            try {
                if ($uninstallString -match "msiexec") {
                    # For MSI-based uninstalls, add /quiet
                    if ($uninstallString -match "/I{") {
                        # Change /I to /X for uninstall if needed
                        $uninstallString = $uninstallString -replace "/I", "/X"
                    }
                    $uninstallCommand = $uninstallString + " /quiet"
                    Start-Process "cmd.exe" -ArgumentList "/c $uninstallCommand" -Wait -NoNewWindow
                } else {
                    # For EXE-based uninstalls
                    $uninstallParts = $uninstallString -split ' ', 2
                    $uninstallExe = $uninstallParts[0].Trim('"')
                    $uninstallArgs = if ($uninstallParts.Count -gt 1) { $uninstallParts[1] } else { "" }
                    
                    # Add silent parameters for common installers
                    if ($uninstallString -match "uninstall.exe|uninst.exe|setup.exe|installer.exe") {
                        $uninstallArgs += " /S /silent /quiet /uninstall"
                    }
                    
                    Start-Process -FilePath $uninstallExe -ArgumentList $uninstallArgs -Wait -NoNewWindow
                }
                Write-Output "Standard uninstall completed for: $displayName"
            } catch {
                Write-Output "Error during standard uninstall: $_"
            }
        } else {
            Write-Output "No uninstall string found for: $displayName"
        }
    }
}

##Look for anything else

##Make sure Intune hasn't installed anything so we don't remove installed apps

$intunepath = "HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps"
$intunecomplete = @(Get-ChildItem $intunepath).count
$userpath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
$userprofiles = Get-ChildItem $userpath | Get-ItemProperty

$nonAdminLoggedOn = $false
foreach ($user in $userprofiles) {
    # Exclude default, system, and network service profiles, and the Administrator profile
    if ($user.PSChildName -notin '.DEFAULT', 'S-1-5-18', 'S-1-5-19', 'S-1-5-20' -and $user.PSChildName -notmatch 'S-1-5-21-\d+-\d+-\d+-500') {
        $nonAdminLoggedOn = $true
        break
    }
}

# Format the runtime with hours, minutes, and seconds
if ($runTime.TotalHours -ge 1) {
    $runTimeFormatted = 'Duration: {0:hh} hr {0:mm} min {0:ss} sec' -f $runTime
}
else {
    $runTimeFormatted = 'Duration: {0:mm} min {0:ss} sec' -f $runTime
}

write-output "Completed"
write-output "Total Script $($runTimeFormatted)"

#Set ProgressPreerence back
$ProgressPreference = $OrginalProgressPreference
Stop-Transcript


The added extra bits I added were in lines 384 to 399 if you were to open this in VSCode.



if (test-path "C:\ProgramData\MrBSOEWay\logs\Debloat.log"){"Installed"}

Wrapped it up as win32 app, this will remove the bloatware.

ree

The log files can be found C:\ProgramData\MrBSOEWay\logs\Debloat.log


 
 
 

Comments


bottom of page