What is bloatware and How to Debloat Windows 11 to Improve Performance

In this article I will show you how to Debloat Windows 11 to Improve Performance, and deploy a DeBloat script via PowerShell. At the bottom, it also has a reference table with all of the applications you can add to the list to be removed when Windows OOBE has been initiated in Intune or the script has been run independently.

What is bloatware and How to Debloat Windows 11 to Improve Performance

What is Bloatware?

Bloatware is a term used to describe unwanted software that comes pre-installed on a new computer, smartphone, or tablet. It can take up space on your device, slow down your system, and reduce battery lifeBloatware is also known as crapware and can come in many different forms, such as trialware, desktop applications, and apps that run on the touch-oriented tablet mode.

This is something I usually deploy via Intune for customers that are going through the OOBE. As soon as the device has been signed into for the first time, this script will run and delete everything that’s listed below. As the list grows, I just update my Script in Intune. You can find an updated script fully compiled through my Github page.

Instructions

We first need to write a script in a certain format with multiple sections. The script contains a ‘tag’, ‘log’, ‘uninstall list’ and ‘execution’.

  1. We need to create a tag to let Intune/Windows know that we’ve installed this DeBloat script. This is the opening line in our PowerShell script as below;
if (-not (testpath "$env:programData)\Microsoft\W11Bloatware"))
{
mkdir "$(env:ProgramData)\Microsoft\Microsoft\W11Bloatware"
}
Set-Content -Path "$(env:ProgramData)\Microsoft\Microsoft\W11Bloatware.ps1.tag" -Value "Installed"

2. Next on our ps1 script, we need to start our logging and transcription for our Bloatware tool;

Start-Transcript "$(env:ProgramData)\Microsoft\Microsoft\W11Bloatware.log"

3. Now we can add our list of desired apps/packages we want installed up execution of our script;

$UninstallPackages = @(
"Microsoft.Getstarted"
"Microsoft.GetHelp"
)

you can continue the list in the format above with as many app ids you want.

Info

The format and accuracy is important in uninstalling unwanted applications. You need to find the App ID through Powershell, you cannot use the application name only as some are named the same. For example, Microsoft Teams (Work or School) is labelled the same in ‘winget list’ as Microsoft Teams (Standard).

4. The final part of our script contains the rule to check for installed by app id and then log if it’s to be uninstalled, provision, uninstall and then log;

$InstalledPackages = Get-AppxPackage -AllUsers | Where {($UninstallPackages -contains $_.Name)}
	
$ProvisionedPackages = Get-AppxProvisionedPackage -Online | Where {($UninstallPackages -contains $_.DisplayName)}

$InstalledPrograms = Get-Package | Where {$UninstallPrograms -contains $_.Name}

# Remove provisioned packages first
ForEach ($ProvPackage in $ProvisionedPackages) {
	
Write-Host -Object "Attempting to remove provisioned package: [$($ProvPackage.DisplayName)]..."

Try {
    $Null = Remove-AppxProvisionedPackage -PackageName $ProvPackage.PackageName -Online -ErrorAction Stop
    Write-Host -Object "Successfully removed provisioned package: [$($ProvPackage.DisplayName)]"
}
    Catch {Write-Warning -Message "Failed to remove provisioned package: [$($ProvPackage.DisplayName)]"}
}
	
# Remove appx packages
ForEach ($AppxPackage in $InstalledPackages) {
	                                            
Write-Host -Object "Attempting to remove Appx package: [$($AppxPackage.Name)]..."

Try {
$Null = Remove-AppxPackage -Package $AppxPackage.PackageFullName -AllUsers -ErrorAction Stop
Write-Host -Object "Successfully removed Appx package: [$($AppxPackage.Name)]"
}
    Catch {Write-Warning -Message "Failed to remove Appx package: [$($AppxPackage.Name)]"}
}
	
# Remove installed programs
$InstalledPrograms | ForEach {
Write-Host -Object "Attempting to uninstall: [$($_.Name)]..."
Try {
$Null = $_ | Uninstall-Package -AllVersions -Force -ErrorAction Stop
Write-Host -Object "Successfully uninstalled: [$($_.Name)]"
}
	    Catch {Write-Warning -Message "Failed to uninstall: [$($_.Name)]"}
}	
Stop-Transcript

All together, it should look like this;

# Create a tag file just so Intune knows this was installed
if (-not (Test-Path "$($env:ProgramData)\Microsoft\Microsoft\W11Bloatware"))
{
    Mkdir "$($env:ProgramData)\Microsoft\RemoveW10Bloatware"
}
Set-Content -Path "$($env:ProgramData)\Microsoft\Microsoft\W11Bloatware.ps1.tag" -Value "Installed"

# Start logging
Start-Transcript "$($env:ProgramData)\Microsoft\Microsoft\W11Bloatware.log"

# List of built-in apps to remove
$UninstallPackages = @(
    "Microsoft.Getstarted"
    "Microsoft.GetHelp"
)

$InstalledPackages = Get-AppxPackage -AllUsers | Where {($UninstallPackages -contains $_.Name)}

$ProvisionedPackages = Get-AppxProvisionedPackage -Online | Where {($UninstallPackages -contains $_.DisplayName)}

$InstalledPrograms = Get-Package | Where {$UninstallPrograms -contains $_.Name}

# Remove provisioned packages first
ForEach ($ProvPackage in $ProvisionedPackages) {

    Write-Host -Object "Attempting to remove provisioned package: [$($ProvPackage.DisplayName)]..."

    Try {
       $Null = Remove-AppxProvisionedPackage -PackageName $ProvPackage.PackageName -Online -ErrorAction Stop
       Write-Host -Object "Successfully removed provisioned package: [$($ProvPackage.DisplayName)]"
}
    Catch {Write-Warning -Message "Failed to remove provisioned package: [$($ProvPackage.DisplayName)]"}
}

# Remove appx packages
ForEach ($AppxPackage in $InstalledPackages) {
                                            
    Write-Host -Object "Attempting to remove Appx package: [$($AppxPackage.Name)]..."

    Try {
        $Null = Remove-AppxPackage -Package $AppxPackage.PackageFullName -AllUsers -ErrorAction Stop
        Write-Host -Object "Successfully removed Appx package: [$($AppxPackage.Name)]"
}
    Catch {Write-Warning -Message "Failed to remove Appx package: [$($AppxPackage.Name)]"}
}

# Remove installed programs
$InstalledPrograms | ForEach {

    Write-Host -Object "Attempting to uninstall: [$($_.Name)]..."

    Try {
        $Null = $_ | Uninstall-Package -AllVersions -Force -ErrorAction Stop
        Write-Host -Object "Successfully uninstalled: [$($_.Name)]"
}
    Catch {Write-Warning -Message "Failed to uninstall: [$($_.Name)]"}
}

Stop-Transcript

Bloatware table

ApplicationApplication ID
Microsoft Get StartedMicrosoft.Getstarted
Microsoft Get HelpMicrosoft.GetHelp
Microsoft 3D viewerMicrosoft.Microsoft3DViewer
Microsoft Office HubMicrosoft.MicrosoftOfficeHub
Microsoft Solitaire CollectionMicrosoft.MicrosoftSolitaireCollection
Mixed Reality PortalMicrosoft.MixedReality.Portal
Office One NoteMicrosoft.Office.OneNote
One ConnectMicrosoft.OneConnect
SkypeMicrosoft.SkypeApp
Feedback HubMicrosoft.WindowsFeedbackHub
XboxMicrosoft.Xbox.TCUI
XboxMicrosoft.GamingApp_8wekyb3d8bbwe
Xbox AppHubMicrosoft.XboxApp
Xbox Game OverlayMicrosoft.XboxApp
Xbox Gaming OverlayMicrosoft.XboxGameOverlay
Xbox Identity ProviderMicrosoft.XboxIdentityProvider
Xbox Speech to Text OverlayMicrosoft.XboxGamingOverlay
Microsoft Teams ClassicMicrosoft.Teams.Classic

Have another way of deploying the script or have any questions, leave a comment below.