Windows 10 Debloater
Windows 10 Debloater
#This will self elevate the script so with a UAC prompt since this script needs to
be run as an Administrator in order to function properly.
If (!([Security.Principal.WindowsPrincipal]
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.Wi
ndowsBuiltInRole]'Administrator')) {
Write-Host "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-Host " 3"
Start-Sleep 1
Write-Host " 2"
Start-Sleep 1
Write-Host " 1"
Start-Sleep 1
Start-Process powershell.exe -ArgumentList ("-NoProfile -ExecutionPolicy Bypass
-File `"{0}`"" -f $PSCommandPath) -Verb RunAs
Exit
}
$DebloatFolder = "C:\Temp\Windows10Debloater"
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."
}
Function DebloatAll {
#Removes AppxPackages
#Credit to /u/GavinEke for a modified version of my whitelist code
$WhitelistedApps = 'Microsoft.ScreenSketch|Microsoft.Paint3D|
Microsoft.WindowsCalculator|Microsoft.WindowsStore|Microsoft.Windows.Photos|
CanonicalGroupLimited.UbuntuonWindows|`
Microsoft.XboxGameCallableUI|Microsoft.XboxGamingOverlay|Microsoft.Xbox.TCUI|
Microsoft.XboxGamingOverlay|Microsoft.XboxIdentityProvider|
Microsoft.MicrosoftStickyNotes|Microsoft.MSPaint|Microsoft.WindowsCamera|.NET|
Framework|`
Microsoft.HEIFImageExtension|Microsoft.ScreenSketch|Microsoft.StorePurchaseApp|
Microsoft.VP9VideoExtensions|Microsoft.WebMediaExtensions|
Microsoft.WebpImageExtension|Microsoft.DesktopAppInstaller|WindSynthBerry|
MIDIBerry|Slack'
#NonRemovable Apps that where getting attempted and the system would reject the
uninstall, speeds up debloat and prevents 'initalizing' overlay when removing apps
$NonRemovable = '1527c705-839a-4832-9118-54d4Bd6a0c89|c5e2524a-ea46-4f67-841f-
6a9465d9d515|E2A4F912-2574-4A75-9BB0-0D023378592B|F46D4000-FD22-4DB4-AC8E-
4E1DDDE828FE|InputApp|Microsoft.AAD.BrokerPlugin|Microsoft.AccountsControl|`
Microsoft.BioEnrollment|Microsoft.CredDialogHost|Microsoft.ECApp|
Microsoft.LockApp|Microsoft.MicrosoftEdgeDevToolsClient|Microsoft.MicrosoftEdge|
Microsoft.PPIProjection|Microsoft.Win32WebViewHost|Microsoft.Windows.Apprep.ChxApp|
`
Microsoft.Windows.AssignedAccessLockApp|Microsoft.Windows.CapturePicker|
Microsoft.Windows.CloudExperienceHost|Microsoft.Windows.ContentDeliveryManager|
Microsoft.Windows.Cortana|Microsoft.Windows.NarratorQuickStart|`
Microsoft.Windows.ParentalControls|Microsoft.Windows.PeopleExperienceHost|
Microsoft.Windows.PinningConfirmationDialog|Microsoft.Windows.SecHealthUI|
Microsoft.Windows.SecureAssessmentBrowser|Microsoft.Windows.ShellExperienceHost|`
Microsoft.Windows.XGpuEjectDialog|Microsoft.XboxGameCallableUI|
Windows.CBSPreview|windows.immersivecontrolpanel|Windows.PrintDialog|
Microsoft.VCLibs.140.00|Microsoft.Services.Store.Engagement|Microsoft.UI.Xaml.2.0|
*Nvidia*'
Get-AppxPackage -AllUsers | Where-Object {$_.Name -NotMatch $WhitelistedApps -
and $_.Name -NotMatch $NonRemovable} | Remove-AppxPackage
Get-AppxPackage | Where-Object {$_.Name -NotMatch $WhitelistedApps -and $_.Name
-NotMatch $NonRemovable} | Remove-AppxPackage
Get-AppxProvisionedPackage -Online | Where-Object {$_.PackageName -NotMatch
$WhitelistedApps -and $_.PackageName -NotMatch $NonRemovable} | Remove-
AppxProvisionedPackage -Online
}
Function DebloatBlacklist {
$Bloatware = @(
#Optional: Typically not removed but you can if you need to for some reason
#"*Microsoft.Advertising.Xaml_10.1712.5.0_x64__8wekyb3d8bbwe*"
#"*Microsoft.Advertising.Xaml_10.1712.5.0_x86__8wekyb3d8bbwe*"
#"*Microsoft.BingWeather*"
#"*Microsoft.MSPaint*"
#"*Microsoft.MicrosoftStickyNotes*"
#"*Microsoft.Windows.Photos*"
#"*Microsoft.WindowsCalculator*"
#"*Microsoft.WindowsStore*"
)
foreach ($Bloat in $Bloatware) {
Get-AppxPackage -Name $Bloat| Remove-AppxPackage
Get-AppxProvisionedPackage -Online | Where-Object DisplayName -like $Bloat
| Remove-AppxProvisionedPackage -Online
Write-Output "Trying to remove $Bloat."
}
}
Function Remove-Keys {
$Keys = @(
#Windows File
"HKCR:\Extensions\ContractId\Windows.File\PackageId\
ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0"
#This writes the output of each key it is removing and also removes the keys
listed above.
ForEach ($Key in $Keys) {
Write-Output "Removing $Key from registry"
Remove-Item $Key -Recurse
}
}
Function Protect-Privacy {
If (!(Test-Path $registryOEM)) {
New-Item $registryOEM
}
Set-ItemProperty $registryOEM ContentDeliveryAllowed -Value 0
Set-ItemProperty $registryOEM OemPreInstalledAppsEnabled -Value 0
Set-ItemProperty $registryOEM PreInstalledAppsEnabled -Value 0
Set-ItemProperty $registryOEM PreInstalledAppsEverEnabled -Value 0
Set-ItemProperty $registryOEM SilentInstalledAppsEnabled -Value 0
Set-ItemProperty $registryOEM SystemPaneSuggestionsEnabled -Value 0
Function DisableCortana {
Write-Host "Disabling Cortana"
$Cortana1 = "HKCU:\SOFTWARE\Microsoft\Personalization\Settings"
$Cortana2 = "HKCU:\SOFTWARE\Microsoft\InputPersonalization"
$Cortana3 = "HKCU:\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore"
If (!(Test-Path $Cortana1)) {
New-Item $Cortana1
}
Set-ItemProperty $Cortana1 AcceptedPrivacyPolicy -Value 0
If (!(Test-Path $Cortana2)) {
New-Item $Cortana2
}
Set-ItemProperty $Cortana2 RestrictImplicitTextCollection -Value 1
Set-ItemProperty $Cortana2 RestrictImplicitInkCollection -Value 1
If (!(Test-Path $Cortana3)) {
New-Item $Cortana3
}
Set-ItemProperty $Cortana3 HarvestContacts -Value 0
Function EnableCortana {
Write-Host "Re-enabling Cortana"
$Cortana1 = "HKCU:\SOFTWARE\Microsoft\Personalization\Settings"
$Cortana2 = "HKCU:\SOFTWARE\Microsoft\InputPersonalization"
$Cortana3 = "HKCU:\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore"
If (!(Test-Path $Cortana1)) {
New-Item $Cortana1
}
Set-ItemProperty $Cortana1 AcceptedPrivacyPolicy -Value 1
If (!(Test-Path $Cortana2)) {
New-Item $Cortana2
}
Set-ItemProperty $Cortana2 RestrictImplicitTextCollection -Value 0
Set-ItemProperty $Cortana2 RestrictImplicitInkCollection -Value 0
If (!(Test-Path $Cortana3)) {
New-Item $Cortana3
}
Set-ItemProperty $Cortana3 HarvestContacts -Value 1
}
Function Stop-EdgePDF {
Function Revert-Changes {
#This function will revert the changes you made when running the Start-Debloat
function.
#Re-enables scheduled tasks that were disabled when running the Debloat switch
Write-Output "Enabling scheduled tasks that were disabled"
Get-ScheduledTask XblGameSaveTaskLogon | Enable-ScheduledTask
Get-ScheduledTask XblGameSaveTask | Enable-ScheduledTask
Get-ScheduledTask Consolidator | Enable-ScheduledTask
Get-ScheduledTask UsbCeip | Enable-ScheduledTask
Get-ScheduledTask DmClient | Enable-ScheduledTask
Get-ScheduledTask DmClientOnScenarioDownload | Enable-ScheduledTask
Function CheckDMWService {
Param([switch]$Debloat)
Function Enable-EdgePDF {
Write-Output "Setting Edge back to default"
$NoPDF = "HKCR:\.pdf"
$NoProgids = "HKCR:\.pdf\OpenWithProgids"
$NoWithList = "HKCR:\.pdf\OpenWithList"
#Sets edge back to default
If (Get-ItemProperty $NoPDF NoOpenWith) {
Remove-ItemProperty $NoPDF NoOpenWith
}
If (Get-ItemProperty $NoPDF NoStaticDefaultVerb) {
Remove-ItemProperty $NoPDF NoStaticDefaultVerb
}
If (Get-ItemProperty $NoProgids NoOpenWith) {
Remove-ItemProperty $NoProgids NoOpenWith
}
If (Get-ItemProperty $NoProgids NoStaticDefaultVerb) {
Remove-ItemProperty $NoProgids NoStaticDefaultVerb
}
If (Get-ItemProperty $NoWithList NoOpenWith) {
Remove-ItemProperty $NoWithList NoOpenWith
}
If (Get-ItemProperty $NoWithList NoStaticDefaultVerb) {
Remove-ItemProperty $NoWithList NoStaticDefaultVerb
}
Function FixWhitelistedApps {
Function UninstallOneDrive {
Write-Host "Checking for pre-existing files and folders located in the OneDrive
folders..."
Start-Sleep 1
If (Test-Path "$env:USERPROFILE\OneDrive\*") {
Write-Host "Files found within the OneDrive folder! Checking to see if a
folder named OneDriveBackupFiles exists."
Start-Sleep 1
If (Test-Path "$env:USERPROFILE\Desktop\OneDriveBackupFiles") {
Write-Host "A folder named OneDriveBackupFiles already exists on your
desktop. All files from your OneDrive location will be moved to that folder."
}
else {
If (!(Test-Path "$env:USERPROFILE\Desktop\OneDriveBackupFiles")) {
Write-Host "A folder named OneDriveBackupFiles will be created and
will be located on your desktop. All files from your OneDrive location will be
located in that folder."
New-item -Path "$env:USERPROFILE\Desktop" -Name
"OneDriveBackupFiles"-ItemType Directory -Force
Write-Host "Successfully created the folder 'OneDriveBackupFiles'
on your desktop."
}
}
Start-Sleep 1
Move-Item -Path "$env:USERPROFILE\OneDrive\*" -Destination
"$env:USERPROFILE\Desktop\OneDriveBackupFiles" -Force
Write-Host "Successfully moved all files/folders from your OneDrive folder
to the folder 'OneDriveBackupFiles' on your desktop."
Start-Sleep 1
Write-Host "Proceeding with the removal of OneDrive."
Start-Sleep 1
}
Else {
Write-Host "Either the OneDrive folder does not exist or there are no files
to be found in the folder. Proceeding with removal of OneDrive."
Start-Sleep 1
Write-Host "Enabling the Group Policy 'Prevent the usage of OneDrive for
File Storage'."
$OneDriveKey = 'HKLM:Software\Policies\Microsoft\Windows\OneDrive'
If (!(Test-Path $OneDriveKey)) {
Mkdir $OneDriveKey
Set-ItemProperty $OneDriveKey -Name OneDrive -Value DisableFileSyncNGSC
}
Set-ItemProperty $OneDriveKey -Name OneDrive -Value DisableFileSyncNGSC
}
Write-Host "Enabling the Group Policy 'Prevent the usage of OneDrive for
File Storage'."
$OneDriveKey = 'HKLM:Software\Policies\Microsoft\Windows\OneDrive'
If (!(Test-Path $OneDriveKey)) {
Mkdir $OneDriveKey
}
Start-Process $onedrive "/uninstall" -NoNewWindow -Wait
Start-Sleep 2
Write-Host "Stopping explorer"
Start-Sleep 1
taskkill.exe /F /IM explorer.exe
Start-Sleep 3
Write-Host "Removing leftover files"
If (Test-Path "$env:USERPROFILE\OneDrive") {
Remove-Item "$env:USERPROFILE\OneDrive" -Force -Recurse
}
If (Test-Path "$env:LOCALAPPDATA\Microsoft\OneDrive") {
Remove-Item "$env:LOCALAPPDATA\Microsoft\OneDrive" -Force -Recurse
}
If (Test-Path "$env:PROGRAMDATA\Microsoft OneDrive") {
Remove-Item "$env:PROGRAMDATA\Microsoft OneDrive" -Force -Recurse
}
If (Test-Path "$env:SYSTEMDRIVE\OneDriveTemp") {
Remove-Item "$env:SYSTEMDRIVE\OneDriveTemp" -Force -Recurse
}
Write-Host "Removing OneDrive from windows explorer"
If (!(Test-Path $ExplorerReg1)) {
New-Item $ExplorerReg1
}
Set-ItemProperty $ExplorerReg1 System.IsPinnedToNameSpaceTree -Value 0
If (!(Test-Path $ExplorerReg2)) {
New-Item $ExplorerReg2
}
Set-ItemProperty $ExplorerReg2 System.IsPinnedToNameSpaceTree -Value 0
Write-Host "Restarting Explorer that was shut down before."
Start-Process explorer.exe -NoNewWindow
Write-Host "OneDrive has been successfully uninstalled!"
Remove-item env:OneDrive
}
}
Function UnpinStart {
# https://superuser.com/a/1442733
#Requires -RunAsAdministrator
$START_MENU_LAYOUT = @"
<LayoutModificationTemplate
xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout"
xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout" Version="1"
xmlns:taskbar="http://schemas.microsoft.com/Start/2014/TaskbarLayout"
xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification">
<LayoutOptions StartTileGroupCellWidth="6" />
<DefaultLayoutOverride>
<StartLayoutCollection>
<defaultlayout:StartLayout GroupCellWidth="6" />
</StartLayoutCollection>
</DefaultLayoutOverride>
</LayoutModificationTemplate>
"@
$layoutFile="C:\Windows\StartMenuLayout.xml"
#Assign the start layout and force it to apply with "LockedStartLayout" at both
the machine and user level
foreach ($regAlias in $regAliases){
$basePath = $regAlias + ":\SOFTWARE\Policies\Microsoft\Windows"
$keyPath = $basePath + "\Explorer"
IF(!(Test-Path -Path $keyPath)) {
New-Item -Path $basePath -Name "Explorer"
}
Set-ItemProperty -Path $keyPath -Name "LockedStartLayout" -Value 1
Set-ItemProperty -Path $keyPath -Name "StartLayoutFile" -Value $layoutFile
}
#Restart Explorer, open the start menu (necessary to load the new layout), and
give it a few seconds to process
Stop-Process -name explorer
Start-Sleep -s 5
$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^{ESCAPE}')
Start-Sleep -s 5
Remove-Item $layoutFile
}
Function Remove3dObjects {
#Removes 3D Objects from the 'My Computer' submenu in explorer
Write-Host "Removing 3D Objects from explorer 'My Computer' submenu"
$Objects32 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\
MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}"
$Objects64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\
Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}"
If (Test-Path $Objects32) {
Remove-Item $Objects32 -Recurse
}
If (Test-Path $Objects64) {
Remove-Item $Objects64 -Recurse
}
}
Function Restore3dObjects {
#Restores 3D Objects from the 'My Computer' submenu in explorer
Write-Host "Restoring 3D Objects from explorer 'My Computer' submenu"
$Objects32 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\
MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}"
$Objects64 = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\
Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}"
If (!(Test-Path $Objects32)) {
New-Item $Objects32
}
If (!(Test-Path $Objects64)) {
New-Item $Objects64
}
}
#Function DisableLastUsedFilesAndFolders {
# Write-Host = "Disable Explorer to show last used files and folders."
# Invoke-Item (start powershell ((Split-Path $MyInvocation.InvocationName) + "\
Individual Scripts\Disable Last Used Files and Folders View.ps1"))
#}
}
}
#Prompt asking if you want to install .NET
$Prompt6 = [Windows.MessageBox]::Show($InstallNET, "Install .Net", $Button,
$Warn)
Switch ($Prompt6) {
Yes {
Write-Host "Initializing the installation of .NET 3.5..."
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All
Write-Host ".NET 3.5 has been successfully installed!"
}
No {
Write-Host "Skipping .NET install."
}
}
# #Prompt asking if you want to deactivate Last Used Files and Folders
# $Prompt7 = [Windows.MessageBox]::Show($LastUsedFilesFolders, "Deactivate
Last Used Files and Folders", $Button, $Warn)
# Switch ($Prompt7) {
# Yes {
# DisableLastUsedFilesAndFolders
# Write-Host "Last Used Files and Folders will no longer been
shown!"
# }
# No {
# Write-Host "Skipping Hiding Last used Files and Folders."
# }
# }