Debloating Windows with win_debloater.ps1

Sharing this script I use to make using Windows less obnoxious by removing a lot of the garbage Microsoft piled onto a default Windows install.

This script is a fork of Windows 10 Debloater I cleaned up to make it portable, compatible with both Windows 10 and 11 and, most importantly, easily auditable by the human eye.

Demo

click to watch demo video

Source

The most up-to-date copy can be found at @dbazile/win_debloater.

#
# win_debloater.ps1
#
# DESCRIPTION
#
#     Run in an admin Powershell session with the following:
#     > Set-ExecutionPolicy -Scope CurrentUser Unrestricted
#     > win_debloater.ps1
#
#     Forked from https://github.com/Sycnex/Windows10Debloater
#
# USAGE
#
#     win_debloater.ps1 [TASK...]
#
#     Tasks (all tasks run if none are specified):
#         - apps
#         - capabilities
#         - explorer
#         - features
#         - lockscreen
#         - onedrive
#         - startmenu
#         - taskbar
#         - telemetry
#

#Requires -RunAsAdministrator

$ErrorActionPreference = 'Stop'
$Host.PrivateData.VerboseForegroundColor = 'DarkCyan'

$TASKS = @('apps', 'capabilities', 'explorer', 'features', 'lockscreen', 'onedrive', 'startmenu', 'taskbar', 'telemetry')
$WIN10 = ([Environment]::OSVersion.Version.Build -lt 22000)


function Main {
    foreach ($s in $args) {
        if (!($s -in $TASKS)) {
            throw "error: unknown task '$s'; must be one of {$TASKS}"
        }
    }

    # Default to all tasks if none specified
    $tasks_ = if (!$args) { @($TASKS) } else { @($args) }

    try {
        Clear-Host

        New-PSDrive HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT | Out-Null
        Start-Transcript -OutputDirectory 'win_debloater'

        Write-Host "Tasks: $tasks_" -ForegroundColor Green

        if ('apps' -in $tasks_)         { Action-UninstallApplications }
        if ('capabilities' -in $tasks_) { Action-DisableWindowsCapabilities }
        if ('features' -in $tasks_)     { Action-DisableWindowsOptionalFeatures }
        if ('telemetry' -in $tasks_)    { Action-DisableTelemetry }
        if ('onedrive' -in $tasks_)     { Action-UninstallOneDrive }
        if ('explorer' -in $tasks_)     { Action-CleanExplorer }
        if ('lockscreen' -in $tasks_)   { Action-CleanLockScreen }
        if ('startmenu' -in $tasks_)    { Action-CleanStartMenu }
        if ('taskbar' -in $tasks_)      { Action-CleanTaskbar }

        Log-Message -Checkpoint 'Completed all tasks; prompting for reboot'

        if ($Host.UI.PromptForChoice('Debloater Complete', 'Debloater script completed. Reboot now?', @('&Yes', '&No'), 1) -eq 0) {
            Restart-Computer
        }
    }
    finally {
        Stop-Transcript
        Remove-PSDrive HKCR
    }
}


function Action-CleanExplorer {
    Log-Message -Checkpoint 'Clean Up Explorer'

    Log-Message 'remove 3d objects from sidebar'
    Registry-Unset -Recurse 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}'
    Registry-Unset -Recurse 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}'

    Log-Message 'show file extensions'
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' HideFileExt 0

    Log-Message 'change explorer default view'
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' LaunchTo 1
}


function Action-CleanLockScreen {
    Log-Message -Checkpoint 'Clean Up Lock Screen'

    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' RotatingLockScreenEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' RotatingLockScreenOverlayEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SoftLandingEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-338387Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SystemPaneSuggestionsEnabled 0
}


function Action-CleanStartMenu {
    # https://superuser.com/a/1442733

    Log-Message -Checkpoint 'Clean Up Start Menu (Windows 10)'

    if (!$WIN10) {
        Log-Message 'Not Windows 10; nothing to do'
        return
    }

    $layoutPath = 'C:\Windows\StartMenuLayout.xml'
    @(
        '<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>'
    ) | Out-File -Verbose $layoutPath -Encoding ASCII

    # Assign the start layout and force it to apply with "LockedStartLayout" at both the machine and user level
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer' LockedStartLayout 1
    Registry-Set 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer' LockedStartLayout 1
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer' StartLayoutFile $layoutPath
    Registry-Set 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer' StartLayoutFile $layoutPath

    # Restart Explorer, open the start menu (necessary to load the new layout), and give it a few seconds to process
    Log-Message 'induce explorer to load new layout'
    Stop-Process -Verbose -Force -Name 'explorer'
    Start-Sleep -s 5
    $wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^{ESCAPE}')
    Start-Sleep -s 5

    # Enable the ability to pin items again by disabling "LockedStartLayout"
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer' LockedStartLayout 0
    Registry-Set 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer' LockedStartLayout 0

    # Make clean start menu default for all new users
    Import-StartLayout -Verbose -LayoutPath $layoutPath -MountPath $env:SystemDrive\

    # Restart Explorer and delete the layout file
    Stop-Process -Verbose -Force -Name 'explorer'
    Start-Sleep 3

    Remove-Item -Verbose $layoutPath
}


function Action-CleanTaskbar() {
    Log-Message -Checkpoint 'Clean Up Taskbar'

    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search' SearchboxTaskbarMode 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Feeds' ShellFeedsTaskbarViewMode 2
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' ShowTaskViewButton 0

    Log-Message 'restart explorer'
    Stop-Process -Verbose -Force -Name 'explorer'
    Start-Sleep 3
}


function Action-DisableWindowsCapabilities {
    Log-Message -Checkpoint 'Disable Windows Capabilities (Windows 10)'

    if (!$WIN10) {
        Log-Message 'Not Windows 10; nothing to do'
        return
    }

    ## Get-WindowsCapability -Online | Sort-Object @('State','Name') | Select-Object Name
    $items = @(
        'Accessibility.Braille'
        'Analog.Holographic.Desktop'
        'App.StepsRecorder'
        'App.Support.QuickAssist'
        'App.WirelessDisplay.Connect'
        'Browser.InternetExplorer'
        'Hello.Face*'
        'MathRecognizer'
        'Media.WindowsMediaPlayer'
        'Microsoft.Onecore.StorageManagement'
        'Microsoft.WebDriver'
        'Microsoft.Windows.StorageManagement'
        'NetFX3'
        'Network.Irda'
        'OneCoreUAP.OneSync'
        'OpenSSH.Client'
        'OpenSSH.Server'
        'RIP.Listener'
        'Rsat.*'
        'SNMP.Client'
        'Tools.DeveloperMode.Core'
        'WMI-SNMP-Provider.Client'
        'Windows.Desktop.EMS-SAC.Tools'
        'XPS.Viewer'
    )

    $n = 1
    foreach ($item in $items) {
        $o = Get-WindowsCapability -Online -Name "${item}~~~~*"
        Log-Message '[{0,3}/{1,3}] {2} ({3})' $n $items.length $item ($o).State
        $o `
            | Remove-WindowsCapability -Online `
            | Out-Null

        $n++
    }
}


function Action-DisableWindowsOptionalFeatures {
    Log-Message -Checkpoint 'Disable Optional Windows Features'

    ## Get-WindowsOptionalFeature -Online | Sort-Object FeatureName | Select-Object @('State', 'FeatureName')
    $items = @(
        'MediaPlayback'
        'Microsoft-RemoteDesktopConnection'
        'Printing-PrintToPDFServices-Features'
        'Recall'
        'SearchEngine-Client-Package'
        'WindowsMediaPlayer'
        'WorkFolders-Client'
    )

    $n = 1
    foreach ($item in $items) {
        $o = Get-WindowsOptionalFeature -Online -FeatureName "${item}*"
        Log-Message '[{0,3}/{1,3}] {2} ({3})' $n $items.length $item $(if ($o) {$o.State} else {'Unknown'})
        $o `
            | Disable-WindowsOptionalFeature -Online -NoRestart -WarningAction:SilentlyContinue `
            | Out-Null

        $n++
    }
}


function Action-DisableTelemetry {
    Log-Message -Checkpoint 'Disable Telemetry'

    Log-Message 'apply registry changes'

    # AI garbage
    Registry-Set 'HKCU:\Software\Policies\Microsoft\Windows\WindowsAI' DisableAIDataAnalysis 1
    Registry-Set 'HKLM:\Software\Policies\Microsoft\Windows\WindowsAI' DisableAIDataAnalysis 1

    # Data Collection
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection' AllowTelemetry 0
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection' AllowTelemetry 0
    Registry-Set 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Policies\DataCollection' AllowTelemetry 0

    # Windows Feedback Experience
    Registry-Set 'HKCU:\Software\Microsoft\Siuf\Rules' PeriodInNanoSeconds 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' Enabled 0
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo' Enabled 0

    # Tailored experiences with diagnostic data for Current User
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Privacy' TailoredExperiencesWithDiagnosticDataEnabled 0

    # Online Speech Recognition
    Registry-Set 'HKCU:\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' HasAccepted 0

    # Inking & Typing
    Registry-Set 'HKCU:\Software\Microsoft\Input\TIPC' Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\InputPersonalization' RestrictImplicitInkCollection 1
    Registry-Set 'HKCU:\Software\Microsoft\InputPersonalization' RestrictImplicitTextCollection 1
    Registry-Set 'HKCU:\Software\Microsoft\InputPersonalization\TrainedDataStore' HarvestContacts 0
    Registry-Set 'HKCU:\Software\Microsoft\Personalization\Settings' AcceptedPrivacyPolicy 0

    # Disable app launch tracking
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' Start_TrackProgs 0
    Registry-Set 'HKCU:\Software\Policies\Microsoft\Windows\EdgeUI' DisableMFUTracking 1
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EdgeUI' DisableMFUTracking 1

    # Disable Cortana use in Windows Search
    Registry-Set 'HKCU:\Software\Policies\Microsoft\Windows\Explorer' DisableSearchBoxSuggestions 1
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search' AllowCortana 0
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search' CortanaConsent 0

    # Disable Copilot
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' ShowCopilotButton 0
    Registry-Set 'HKCU:\Software\Policies\Microsoft\Windows\WindowsCopilot' TurnOffWindowsCopilot 1
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' TurnOffWindowsCopilot 1

    # Disable Windows Suggestions
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement' ScoobeSystemSettingEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SilentInstalledAppsEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SoftLandingEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-310093Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-338388Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-338389Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-338393Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-353694Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SubscribedContent-353696Enabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SystemPaneSuggestionsEnabled 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' ShowSyncProviderNotifications 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' Start_IrisRecommendations 0
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested' Enabled 0

    # Disable Chat taskbar
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' HideSCAMeetNow 1
    Registry-Set 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' TaskbarMn 0

    # Disable Web Search in Start Menu
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search' BingSearchEnabled 0
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search' DisableWebSearch  1

    # Prevents bloatware applications from returning and removes Start Menu suggestions
    Registry-Set 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent' DisableWindowsConsumerFeatures 1
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' ContentDeliveryAllowed 0
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' OemPreInstalledAppsEnabled 0
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' PreInstalledAppsEnabled 0
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' PreInstalledAppsEverEnabled 0
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SilentInstalledAppsEnabled 0
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' SystemPaneSuggestionsEnabled 0

    # Prep mixed Reality Portal for removal
    Registry-Set -IfExists 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Holographic' FirstRunSucceeded 0

    # Wi-fi Sense
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting' Value 0
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots' Value 0
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config' AutoConnectAllowedOEM 0

    # Live tiles
    Registry-Set 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications' NoTileApplicationNotification 1

    # Location Tracking
    Registry-Set 'HKLM:\SYSTEM\CurrentControlSet\Services\lfsvc\Service\Configuration' Status 0
    Registry-Set 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}' SensorPermissionState 0

    # Disable People icon on Taskbar
    Registry-Set 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People' PeopleBand 0

    # Scheduled tasks
    Log-Message 'disable unnecessary scheduled tasks'
    Get-ScheduledTask 'XblGameSaveTaskLogon' -ErrorAction SilentlyContinue | Disable-ScheduledTask | Out-Null
    Get-ScheduledTask 'XblGameSaveTask' -ErrorAction SilentlyContinue | Disable-ScheduledTask | Out-Null
    Get-ScheduledTask 'Consolidator' | Disable-ScheduledTask | Out-Null
    Get-ScheduledTask 'UsbCeip' | Disable-ScheduledTask | Out-Null
    Get-ScheduledTask 'DmClient' | Disable-ScheduledTask | Out-Null
    Get-ScheduledTask 'DmClientOnScenarioDownload' | Disable-ScheduledTask | Out-Null

    # Device Management Wireless Application Protocol Push message routing service
    Log-Message 'disable Device Management WAP message routing service'
    Stop-Service 'dmwappushservice'
    Set-Service 'dmwappushservice' -StartupType Disabled

    # Diagnostics Tracking Service
    Log-Message 'disable Diagnostics Tracking Service'
    Stop-Service -Verbose 'DiagTrack'
    Set-Service -Verbose 'DiagTrack' -StartupType Disabled

    # CloudStore
    Log-Message 'remove CloudStore from registry'
    $tmp = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore'
    if (Test-Path $tmp) {
        Remove-Item -Verbose $tmp -Recurse -Force

        Log-Message 'restart explorer'
        Stop-Process -Verbose -Force -Name 'explorer'
        Start-Sleep -s 3
    }
}


function Action-UninstallApplications {
    Log-Message -Checkpoint 'Uninstall Applications'

    ## Get-AppxPackage -AllUsers | Where-Object -Property NonRemovable -eq $false | Sort-Object Name | Select-Object Name
    $items = @(
        # First Party
        'Clipchamp.Clipchamp'
        'MSTeams'
        'Microsoft.549981C3F5F10'  # Cortana
        'Microsoft.BingNews'
        'Microsoft.BingSearch'
        'Microsoft.BingWeather'
        'Microsoft.Copilot'
        'Microsoft.GamingApp'
        'Microsoft.GetHelp'
        'Microsoft.Getstarted'
        'Microsoft.Messaging'
        'Microsoft.Microsoft3DViewer'
        'Microsoft.MicrosoftEdge.Stable'
        'Microsoft.MicrosoftOfficeHub'
        'Microsoft.MicrosoftSolitaireCollection'
        'Microsoft.MicrosoftStickyNotes'
        'Microsoft.MixedReality.Portal'
        'Microsoft.NetworkSpeedTest'
        'Microsoft.News'
        'Microsoft.Office.*'
        'Microsoft.OneConnect'
        'Microsoft.OutlookForWindows'
        'Microsoft.People'
        'Microsoft.PowerAutomateDesktop'
        'Microsoft.Print3D'
        'Microsoft.RemoteDesktop'
        'Microsoft.ScreenSketch'
        'Microsoft.SkypeApp'
        'Microsoft.StorePurchaseApp'
        'Microsoft.Todos'
        'Microsoft.Wallet'
        'Microsoft.Whiteboard'
        'Microsoft.Windows.Ai.*'
        'Microsoft.Windows.DevHome'
        'Microsoft.WindowsAlarms'
        'Microsoft.WindowsCamera'
        'Microsoft.WindowsCommunicationsApps'
        'Microsoft.WindowsFeedbackHub'
        'Microsoft.WindowsMaps'
        'Microsoft.WindowsSoundRecorder'
        'Microsoft.Xbox*'
        'Microsoft.YourPhone'
        'Microsoft.ZuneMusic'
        'Microsoft.ZuneVideo'
        'MicrosoftCorporationII.QuickAssist'
        'MicrosoftWindows.Client.WebExperience'

        # Lots of things depend on these, so remove them last
        'Microsoft.Advertising.*'
        # 'Microsoft.Services.Store.Engagement'  # Photos requires this

        # Third-party crap
        '*ActiproSoftwareLLC*'
        '*AdobeSystemsIncorporated.AdobePhotoshopExpress*'
        '*BubbleWitch3Saga*'
        '*CandyCrush*'
        '*Dolby*'
        '*Duolingo*'
        '*EclipseManager*'
        '*Facebook*'
        '*Flipboard*'
        '*Minecraft*'
        '*PandoraMediaInc*'
        '*Royal Revolt*'
        '*Speed Test*'
        '*Spotify*'
        '*Sway*'
        '*Twitter*'
        '*Wunderlist*'
    )

    $n = 1
    foreach ($item in $items) {
        Log-Message "[{0,3}/{1,3}] remove '{2}'" $n $items.length $item

        Get-AppxPackage -Name $item `
            | Where-Object { $_.NonRemovable -eq $false } `
            | Remove-AppxPackage -Verbose

        Get-AppxPackage -AllUsers -Name $item `
            | Where-Object { $_.NonRemovable -eq $false } `
            | Remove-AppxPackage -Verbose

        Get-AppxProvisionedPackage -Online `
            | Where-Object { $_.PackageName -like "${item}*" } `
            | Remove-AppxProvisionedPackage -Online `
            | Out-Null

        $n++
    }

    Log-Message 'clean up registry keys'

    $keys = @(
        # Remove Background Tasks
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\46928bounde.EclipseManager_2.2.4.51_neutral__a5h4egax66k6y'
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0'
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\Microsoft.MicrosoftOfficeHub_17.7909.7600.0_x64__8wekyb3d8bbwe'
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\Microsoft.PPIProjection_10.0.15063.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\Microsoft.XboxGameCallableUI_1000.15063.0.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.BackgroundTasks\PackageId\Microsoft.XboxGameCallableUI_1000.16299.15.0_neutral_neutral_cw5n1h2txyewy'

        # Windows File
        'HKCR:\Extensions\ContractId\Windows.File\PackageId\ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0'

        # Possible leftovers from RemoveAppXPackage/RemoveAppXProvisionedPackage
        'HKCR:\Extensions\ContractId\Windows.Launch\PackageId\46928bounde.EclipseManager_2.2.4.51_neutral__a5h4egax66k6y'
        'HKCR:\Extensions\ContractId\Windows.Launch\PackageId\ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0'
        'HKCR:\Extensions\ContractId\Windows.Launch\PackageId\Microsoft.PPIProjection_10.0.15063.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.Launch\PackageId\Microsoft.XboxGameCallableUI_1000.15063.0.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.Launch\PackageId\Microsoft.XboxGameCallableUI_1000.16299.15.0_neutral_neutral_cw5n1h2txyewy'

        # Scheduled Tasks
        'HKCR:\Extensions\ContractId\Windows.PreInstalledConfigTask\PackageId\Microsoft.MicrosoftOfficeHub_17.7909.7600.0_x64__8wekyb3d8bbwe'

        # Windows Protocol Keys
        'HKCR:\Extensions\ContractId\Windows.Protocol\PackageId\ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0'
        'HKCR:\Extensions\ContractId\Windows.Protocol\PackageId\Microsoft.PPIProjection_10.0.15063.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.Protocol\PackageId\Microsoft.XboxGameCallableUI_1000.15063.0.0_neutral_neutral_cw5n1h2txyewy'
        'HKCR:\Extensions\ContractId\Windows.Protocol\PackageId\Microsoft.XboxGameCallableUI_1000.16299.15.0_neutral_neutral_cw5n1h2txyewy'

        # Windows Share Target
        'HKCR:\Extensions\ContractId\Windows.ShareTarget\PackageId\ActiproSoftwareLLC.562882FEEB491_2.6.18.18_neutral__24pqs290vpjk0'
    )

    foreach ($key in $keys) {
        Registry-Unset "$key"
    }
}


function Action-UninstallOneDrive {
    Log-Message -Checkpoint 'Uninstall OneDrive'

    # Prevent the usage of OneDrive for File Storage
    Registry-Set 'HKLM:\Software\Policies\Microsoft\Windows\OneDrive' OneDrive DisableFileSyncNGSC

    Log-Message 'stop OneDrive service'
    Stop-Process -Verbose -Force -Name 'OneDrive*'
    Start-Sleep 2

    Log-Message 'run uninstaller'
    $uninstallerPath = "$env:SYSTEMROOT\SysWOW64\OneDriveSetup.exe"
    if (!(Test-Path "$uninstallerPath")) {
        $uninstallerPath = "$env:SYSTEMROOT\System32\OneDriveSetup.exe"
    }

    if (Test-Path $uninstallerPath) {
        Start-Process $uninstallerPath '/uninstall' -NoNewWindow -Wait
        Start-Sleep 2
    }

    Log-Message 'stop explorer'
    taskkill.exe /F /IM explorer.exe
    Start-Sleep 3

    Log-Message 'clean up directories'
    foreach ($path in @(
        "$env:LOCALAPPDATA\Microsoft\OneDrive"
        "$env:OneDrive"
        "$env:PROGRAMDATA\Microsoft OneDrive"
        "$env:SYSTEMDRIVE\OneDriveTemp"
        "$env:USERPROFILE\OneDrive"
    )) {
        if (Test-Path $path) {
            Remove-Item -Verbose -Force -Recurse $path
        }
    }

    Log-Message 'remove OneDrive from explorer sidebar'
    Registry-Set 'HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}' System.IsPinnedToNameSpaceTree 0
    Registry-Set 'HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}' System.IsPinnedToNameSpaceTree 0

    Log-Message 'restart explorer'
    Start-Process explorer.exe -NoNewWindow -Wait
    Start-Sleep 3
}


function Log-Message([Switch] $Checkpoint, [string] $Message) {
    $msg = ($Message -f $args)
    if ($Checkpoint) {
        Write-Host -ForegroundColor Yellow "`n$msg"
    }
    else {
        Write-Host -ForegroundColor Cyan "----> $msg"
    }
}


function Registry-Set([Switch] $MustExist, [Switch] $IfExists, [string] $Path, [string] $Property, $Value) {
    if (!(Test-Path $Path)) {
        if ($MustExist) {
            throw "registry path '$Path' must already exist"
        }
        if ($IfExists) {
            return
        }

        New-Item -Verbose -Force $Path | Out-Null
    }

    if (!$Property -and !$Value) {
        return
    }

    Set-ItemProperty -Verbose $Path $Property -Value $Value
}


function Registry-Unset([Switch] $Recurse, [string] $Path) {
    if (!(Test-Path $Path)) {
        return
    }

    if ($Recurse) {
        Remove-Item -Verbose $Path -Recurse
    }
    else {
        Remove-Item -Verbose $Path
    }
}


Main @args
loading blog data