(184) Microsoft Intune - Removing Dell Bloatware and Dell Apps
- 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.

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



Comments