卸载微软电脑管家:一次性彻底移除

背景

这阵子想把「微软电脑管家」(Microsoft PC Manager)从机器上清掉。常规卸载走完流程,任务栏图标没了,但重启后它又"自己回来了"。期间还踩了两个坑:PowerShell 执行策略阻止脚本运行中文输出导致脚本乱码报语法错。下面是完整解决方案和一键脚本,亲测可复现。


先说结论

  • 正确流程是:结束后台进程 → 卸载(含 Store/传统安装)→ 清残留文件 → 清理启动项/计划任务 →(可选)关闭自动回装来源
  • 一键脚本能把整套动作做完;考虑到编码问题,我给出英文输出版脚本,避免中文乱码导致的语法错误。
  • 临时绕过 PowerShell 执行策略再运行脚本,不用永久降低安全性。

快速上手(一步到位)

  1. 把下面的脚本内容保存为 Remove-PCManager.ps1(建议用 VS Code 保存为 UTF-8;英文版脚本不要求 BOM)。

  2. 管理员 打开 PowerShell,先执行(只对当前窗口生效):

    复制代码
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
  3. 运行脚本:

    复制代码
    .\Remove-PCManager.ps1
  4. 完成后重启一次电脑。


一键卸载脚本(英文输出版,避免中文编码坑)

复制代码
<#
  Remove-PCManager.ps1
  What it does:
    1) Kill PC Manager related processes/services
    2) Uninstall via winget / registry (MSI/EXE) / Microsoft Store (Appx)
    3) Clean leftover files, shortcuts, startup entries, scheduled tasks
    4) (Optional) Set policies to reduce auto-reinstall

  Usage:
    - Run PowerShell as Administrator
    - (Temporary) bypass policy for this session:
        Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
    - Execute:
        .\Remove-PCManager.ps1
#>

function Ensure-Admin {
  $id = [Security.Principal.WindowsIdentity]::GetCurrent()
  $p  = New-Object Security.Principal.WindowsPrincipal($id)
  if (-not $p.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "Re-launching with admin rights..." -ForegroundColor Yellow
    $psi = New-Object System.Diagnostics.ProcessStartInfo
    $psi.FileName = "powershell.exe"
    $psi.Arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
    $psi.Verb = "runas"
    try { [Diagnostics.Process]::Start($psi) | Out-Null } catch { Write-Host "UAC cancelled. Exit." -ForegroundColor Red }
    exit
  }
}
Ensure-Admin

$ErrorActionPreference = "SilentlyContinue"

function Stop-Targets {
  Write-Host "`n[1/7] Stopping related processes/services..." -ForegroundColor Cyan
  $procNames = @("PCManager","PCMgr","MSPCManager","MicrosoftPCManager","pcmanager")
  foreach ($n in $procNames) {
    Get-Process -Name $n -ErrorAction SilentlyContinue | Stop-Process -Force
  }
  Get-Process | Where-Object { $_.Path -and ($_.Path -match "PC\s*Manager|PCManager") } | Stop-Process -Force

  Get-Service | Where-Object { $_.Name -match "PCManager|PCMgr" -or $_.DisplayName -match "PC Manager" } |
    ForEach-Object {
      if ($_.Status -ne 'Stopped') { Stop-Service $_ -Force }
      Set-Service $_ -StartupType Disabled
    }
}

function Try-Winget-Uninstall {
  Write-Host "`n[2/7] Trying winget uninstall..." -ForegroundColor Cyan
  $winget = Get-Command winget -ErrorAction SilentlyContinue
  if ($winget) {
    winget uninstall --silent --accept-source-agreements --accept-package-agreements --force --id Microsoft.PCManager 2>$null
    winget uninstall --silent --accept-source-agreements --accept-package-agreements --force --name "Microsoft PC Manager" 2>$null
    winget uninstall --silent --accept-source-agreements --accept-package-agreements --force --name "PC Manager" 2>$null
    winget uninstall --silent --accept-source-agreements --accept-package-agreements --force --name "微软电脑管家" 2>$null
  } else {
    Write-Host "winget not found, skip." -ForegroundColor DarkYellow
  }
}

function Uninstall-FromUninstallKey {
  Write-Host "`n[3/7] Trying registry uninstall (MSI/EXE)..." -ForegroundColor Cyan
  $roots = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
  )
  foreach ($root in $roots) {
    Get-ChildItem $root -ErrorAction SilentlyContinue | ForEach-Object {
      $p = Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue
      if ($p -and $p.DisplayName -match "PC\s*Manager|微软电脑管家") {
        $us = $p.UninstallString
        Write-Host " - Found: $($p.DisplayName)"
        if ($us) {
          if ($us -match "msiexec(\.exe)?") {
            $cmd = $us -replace "/I","/x"
            if ($cmd -notmatch "/x") { $cmd = "$cmd /x" }
            if ($cmd -notmatch "/qn") { $cmd = "$cmd /qn" }
            Start-Process -FilePath "cmd.exe" -ArgumentList "/c",$cmd -Wait -WindowStyle Hidden
          } else {
            Start-Process -FilePath "cmd.exe" -ArgumentList "/c","`"$us`"" -Wait
          }
        }
      }
    }
  }
}

function Remove-StoreApp {
  Write-Host "`n[4/7] Removing Microsoft Store app (if any)..." -ForegroundColor Cyan
  $pkgs = Get-AppxPackage -AllUsers | Where-Object {
    $_.Name -match "PCManager|MicrosoftPCManager" -or $_.PackageFamilyName -match "PCManager"
  }
  foreach ($p in $pkgs) {
    Write-Host " - Remove Appx: $($p.Name)"
    Remove-AppxPackage -Package $p.PackageFullName -AllUsers -ErrorAction SilentlyContinue
  }
  $prov = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -match "PCManager|MicrosoftPCManager" }
  foreach ($pp in $prov) {
    Write-Host " - Remove provisioned: $($pp.DisplayName)"
    Remove-AppxProvisionedPackage -Online -PackageName $pp.PackageName | Out-Null
  }
}

function Cleanup-Files {
  Write-Host "`n[5/7] Cleaning leftover files/shortcuts..." -ForegroundColor Cyan
  $paths = @(
    "$Env:ProgramFiles\Microsoft PC Manager",
    "$Env:ProgramFiles\PC Manager",
    "$Env:ProgramFiles(x86)\Microsoft PC Manager",
    "$Env:ProgramFiles(x86)\PC Manager",
    "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft PC Manager",
    "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\PC Manager",
    "$Env:AppData\PCManager",
    "$Env:LocalAppData\PCManager",
    "$Env:LocalAppData\Packages\*PCManager*"
  )
  foreach ($p in $paths) {
    if (Test-Path $p) {
      Write-Host " - Delete: $p"
      Remove-Item -Path $p -Recurse -Force -ErrorAction SilentlyContinue
    }
  }
}

function Cleanup-StartupAndTasks {
  Write-Host "`n[6/7] Cleaning startup entries, shortcuts and scheduled tasks..." -ForegroundColor Cyan
  $runKeys = @(
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
  )
  foreach ($rk in $runKeys) {
    if (Test-Path $rk) {
      $props = Get-ItemProperty -Path $rk
      foreach ($prop in $props.PSObject.Properties) {
        if ($prop.MemberType -eq "NoteProperty" -and ($prop.Value -is [string]) -and ($prop.Value -match "PC\s*Manager|PCManager|微软电脑管家")) {
          Write-Host " - Remove startup: $($prop.Name) ($rk)"
          Remove-ItemProperty -Path $rk -Name $prop.Name -ErrorAction SilentlyContinue
        }
      }
    }
  }

  Get-ChildItem "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs\*.lnk" -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -match "PC\s*Manager|微软电脑管家" } | Remove-Item -Force -ErrorAction SilentlyContinue
  Get-ChildItem "$Env:AppData\Microsoft\Windows\Start Menu\Programs\*.lnk" -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -match "PC\s*Manager|微软电脑管家" } | Remove-Item -Force -ErrorAction SilentlyContinue

  Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object {
    $_.TaskName -match "PC\s*Manager|PCManager|微软电脑管家" -or $_.TaskPath -match "PCManager"
  } | ForEach-Object {
    Write-Host " - Remove scheduled task: $($_.TaskName)"
    Unregister-ScheduledTask -TaskName $_.TaskName -TaskPath $_.TaskPath -Confirm:$false -ErrorAction SilentlyContinue
  }
}

function Optional-Block-Reinstall {
  param([switch]$EnableBlock)
  if (-not $EnableBlock) { return }
  Write-Host "`n[7/7] Setting policies to reduce auto-reinstall..." -ForegroundColor Cyan
  New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Force | Out-Null
  New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore" -Name "AutoDownload" -Value 2 -PropertyType DWord -Force | Out-Null
  New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Force | Out-Null
  New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableConsumerFeatures" -Value 1 -PropertyType DWord -Force | Out-Null
  Write-Host " - Done. You can revert these in policy settings later."
}

# ---- Execute ----
Stop-Targets
Try-Winget-Uninstall
Uninstall-FromUninstallKey
Remove-StoreApp
Cleanup-Files
Cleanup-StartupAndTasks
# Turn this on if you keep seeing it come back from Store or consumer experience:
Optional-Block-Reinstall -EnableBlock:$false

Write-Host "`nAll done. Please reboot your PC." -ForegroundColor Green

常见坑位 & 处理办法

  • 脚本报"在此系统上禁止运行脚本"

    解决:临时放行当前会话即可(安全、用完恢复)

复制代码
  Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
  • 中文乱码导致脚本语法错误

    如果你用了中文输出版脚本,请用 VS Code「保存为编码 → UTF-8 with BOM」。

    避坑法:直接用上面英文输出版,不依赖 BOM 也不会乱码。

  • 卸载后又装回来了

    多半来自 Microsoft Store 自动更新或"消费者体验"推送。把脚本最后一行的:

复制代码
  Optional-Block-Reinstall -EnableBlock:$false

改成:
*

复制代码
  Optional-Block-Reinstall -EnableBlock:$true

运行一次,再重启。

  • 找不到 winget

    没关系,脚本会自动走注册表卸载 + Appx 移除,不影响结果。


需要恢复设置时怎么做?

若你启用了"防回装"(脚本会写入两条策略),想恢复默认:

  • 打开 Microsoft Store ,重新开启 自动更新应用
  • 或删除这两个策略键值(需要管理员):
    • HKLM\SOFTWARE\Policies\Microsoft\WindowsStore\AutoDownload
    • HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent\DisableConsumerFeatures

小结

这次折腾的关键经验有三点:

  1. 卸载要成体系,别只点"卸载"。
  2. PowerShell 脚本先临时绕过执行策略,跑完就关窗口。
  3. 避免中文编码坑------脚本用英文输出最省心,或者 UTF-8 with BOM 保存。
相关推荐
qq_427506082 小时前
基于Vue 3和Element Plus利用h、render函数写一个简单的tooltip局部or全局指令
前端·javascript·vue.js
泥菩萨^_^2 小时前
【每天认识一个漏洞】React 和 Next.js RCE漏洞
前端·javascript·react.js
1024肥宅2 小时前
JavaScript常用设计模式完整指南
前端·javascript·设计模式
董世昌412 小时前
js怎样控制浏览器前进、后退、页面跳转?
开发语言·前端·javascript
走,带你去玩3 小时前
uniapp live-pusher + 腾讯云直播
前端·javascript·uni-app
徐同保3 小时前
electron打包项目
前端·javascript·electron
Maybyy3 小时前
如何在项目里面添加一个可以左右翻动并显示指定日期的日历
前端·vue.js
柯南二号3 小时前
【大前端】【Android】用 Python 脚本模拟点击 Android APP —— 全面技术指南
android·前端·python
Arvin_Rong3 小时前
前端动态 API 生成与封装:前端 API 调用的一种思路
前端