如何通过 PowerShell 脚本一键修复 Defender 排除项权限?
时间: 2025-07-29 12:37:06 浏览: 2
<think>我们计划通过PowerShell脚本修复WindowsDefender排除项的权限问题。根据之前的解决方案,核心是修改注册表项`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsDefender\Exclusions`的权限,将其所有者设置为Administrators,并赋予Administrators、SYSTEM和TrustedInstaller完全控制权限。由于PowerShell可以操作注册表权限,我们将使用`Set-Acl`命令来修改访问控制列表(ACL)。步骤如下:1.以管理员身份运行PowerShell(必需,否则修改注册表权限会失败)2.获取目标注册表路径的当前ACL3.设置所有者(Administrators)4.添加三个主体的完全控制权限:Administrators,SYSTEM,TrustedInstaller5.应用新的ACL注意:在修改ACL之前,最好备份当前的ACL,以便在需要时恢复。我们编写一个脚本,包含以下功能:-备份当前注册表项的ACL到文件(可选)-修改所有者为Administrators-添加完全控制权限给Administrators、SYSTEM和TrustedInstaller-递归应用到子项(因为Exclusions下有Paths、Processes等子项,需要一并修改)但是,由于权限问题,递归修改可能会遇到某些子项拒绝访问,因此我们需要对每个子项单独操作。步骤详解:1.定义注册表路径:`"HKLM:\SOFTWARE\Microsoft\WindowsDefender\Exclusions"`2.获取当前ACL对象:`$acl=Get-Acl-Path$registryPath`3.设置所有者:-使用`$acl.SetOwner([System.Security.Principal.NTAccount]("Administrators"))`4.为三个主体添加完全控制权限(允许):-创建新的访问规则:`$accessRule=New-ObjectSystem.Security.AccessControl.RegistryAccessRule(主体,"FullControl","ContainerInherit,ObjectInherit","None","Allow")`-将规则添加到ACL:`$acl.SetAccessRule($accessRule)`5.应用修改后的ACL:`Set-Acl-Path$registryPath-AclObject$acl`6.递归处理子项:使用`Get-ChildItem-Path$registryPath-Recurse`获取所有子项,然后对每个子项重复上述2-5步骤(注意:递归获取子项时,可能会遇到权限不足而无法访问,因此我们需要在修改了父项权限后再尝试递归修改子项)但是,由于我们修改了父项权限后,子项的所有者可能还是原来的,因此需要递归修改每个子项的所有者和权限。另外,由于TrustedInstaller是服务账户,其名称在系统中为`NTSERVICE\TrustedInstaller`,但在注册表权限中,我们通常使用`NTSERVICE\TrustedInstaller`。同样,SYSTEM账户为`NTAUTHORITY\SYSTEM`,Administrators为`BUILTIN\Administrators`(或直接使用`Administrators`,系统会自动解析)。注意:在PowerShell中,注册表路径使用`HKLM:\`开头(需要PSDrive支持,默认存在)。由于修改注册表权限需要管理员权限,因此脚本必须以管理员身份运行。我们编写脚本如下:注意:在修改权限之前,先检查当前用户是否是管理员,如果不是则提示并退出。脚本内容:```powershell#必须以管理员身份运行$currentPrincipal=New-ObjectSecurity.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())if(-not$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)){Write-Host"请以管理员身份运行此脚本!"-ForegroundColorRedexit1}#目标注册表路径$registryPath="HKLM:\SOFTWARE\Microsoft\WindowsDefender\Exclusions"#定义需要赋予权限的主体$administrators=[System.Security.Principal.NTAccount]("Administrators")$system=[System.Security.Principal.NTAccount]("SYSTEM")$trustedInstaller=[System.Security.Principal.NTAccount]("NTSERVICE\TrustedInstaller")#定义访问规则:完全控制,允许,并设置继承$accessRuleAdmin=New-ObjectSystem.Security.AccessControl.RegistryAccessRule($administrators,"FullControl","ContainerInherit,ObjectInherit","None","Allow")$accessRuleSystem=New-ObjectSystem.Security.AccessControl.RegistryAccessRule($system,"FullControl","ContainerInherit,ObjectInherit","None","Allow")$accessRuleTrustedInstaller=New-ObjectSystem.Security.AccessControl.RegistryAccessRule($trustedInstaller,"FullControl","ContainerInherit,ObjectInherit","None","Allow")#递归函数,用于设置注册表项及其所有子项的权限functionSet-RegistryPermissionsRecursively{param([string]$Path)#获取当前项的ACL$acl=Get-Acl-Path$Path#设置所有者$acl.SetOwner($administrators)#清除所有现有权限(可选,但通常不建议,因为可能会破坏系统设置)#我们选择只添加我们需要的权限,保留原有权限可能会造成冲突,但为了安全,我们只添加而不清除,然后确保我们需要的权限存在。#先移除已有的Administrators、SYSTEM、TrustedInstaller的规则(如果存在),然后重新添加,避免重复$acl.Access|Where-Object{$_.IdentityReference-in@('Administrators','NTAUTHORITY\SYSTEM','NTSERVICE\TrustedInstaller')}|ForEach-Object{$acl.RemoveAccessRuleSpecific($_)}#添加新的访问规则$acl.AddAccessRule($accessRuleAdmin)$acl.AddAccessRule($accessRuleSystem)$acl.AddAccessRule($accessRuleTrustedInstaller)#应用到当前项Set-Acl-Path$Path-AclObject$acl#递归处理子项Get-ChildItem-Path$Path|ForEach-Object{Set-RegistryPermissionsRecursively-Path$_.PSPath}}#调用函数处理目标路径Set-RegistryPermissionsRecursively-Path$registryPathWrite-Host"已成功修复WindowsDefender排除项的权限。请重启计算机使更改完全生效。"-ForegroundColorGreen```注意:由于注册表项可能较多,递归处理需要时间。另外,移除已有的这三个主体的规则是为了避免重复,确保我们添加的规则是新的。但是,上述脚本中移除规则时使用了硬编码的主体名称,但要注意在系统中,同一个主体可能有不同的表示(如`BUILTIN\Administrators`和`Administrators`),所以这里我们使用字符串匹配。但根据经验,在HKLM下,这三个主体的表示通常是固定的:`Administrators`,`NTAUTHORITY\SYSTEM`,`NTSERVICE\TrustedInstaller`。另外,由于`Get-ChildItem`在访问某些子项时可能因为权限问题而失败,但我们在修改了父项权限后,应该能够访问子项。如果递归过程中遇到错误,可以忽略并继续(但这里我们不忽略,因为我们已经修改了父项权限,应该能够访问子项)。重要提示:修改注册表权限有风险,建议在运行脚本前创建系统还原点。由于我们只修改了`Exclusions`及其子项,不会影响其他注册表项,因此相对安全。使用此脚本后,重启计算机,然后尝试添加排除项。如果问题依旧,请检查组策略设置和第三方杀毒软件干扰。相关问题:§§相关问题§§1.如何验证注册表权限是否修改成功?2.如果PowerShell脚本运行时报错“拒绝访问”怎么办?3.如何创建系统还原点的PowerShell脚本?4.如何检查WindowsDefender实时保护状态是否影响排除项设置?</think>### PowerShell 脚本修复 Windows Defender 排除项权限问题
以下是完整的 PowerShell 脚本解决方案,用于修复注册表权限问题,解决 "无法保存对 Exclusions 的更改,拒绝访问" 错误:
```powershell
# 必须以管理员身份运行
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
exit
}
# 目标注册表路径
$registryPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Exclusions"
# 定义安全主体
$administrators = [System.Security.Principal.NTAccount]("Administrators")
$system = [System.Security.Principal.NTAccount]("SYSTEM")
$trustedInstaller = [System.Security.Principal.NTAccount]("NT SERVICE\TrustedInstaller")
# 递归修复权限函数
function Repair-RegistryPermissions {
param(
[string]$Path
)
try {
# 获取当前ACL
$acl = Get-Acl -Path $Path
# 设置所有者
$acl.SetOwner($administrators)
# 添加Administrators完全控制权限
$accessRule = New-Object System.Security.AccessControl.RegistryAccessRule(
$administrators,
"FullControl",
"ContainerInherit, ObjectInherit",
"None",
"Allow"
)
$acl.AddAccessRule($accessRule)
# 添加SYSTEM完全控制权限
$accessRule = New-Object System.Security.AccessControl.RegistryAccessRule(
$system,
"FullControl",
"ContainerInherit, ObjectInherit",
"None",
"Allow"
)
$acl.AddAccessRule($accessRule)
# 添加TrustedInstaller完全控制权限
$accessRule = New-Object System.Security.AccessControl.RegistryAccessRule(
$trustedInstaller,
"FullControl",
"ContainerInherit, ObjectInherit",
"None",
"Allow"
)
$acl.AddAccessRule($accessRule)
# 应用新ACL
Set-Acl -Path $Path -AclObject $acl
Write-Host "成功修复权限: $Path" -ForegroundColor Green
# 递归处理子项
Get-ChildItem -Path $Path | ForEach-Object {
Repair-RegistryPermissions -Path $_.PSPath
}
}
catch {
Write-Host "处理 $Path 时出错: $_" -ForegroundColor Red
}
}
# 执行修复
Write-Host "正在修复 Windows Defender 排除项权限..." -ForegroundColor Cyan
Repair-RegistryPermissions -Path $registryPath
# 重启Defender服务
Write-Host "正在重启 Windows Defender 服务..." -ForegroundColor Cyan
Stop-Service -Name WinDefend -Force -ErrorAction SilentlyContinue
Start-Service -Name WinDefend -ErrorAction SilentlyContinue
Write-Host "`n修复完成!请尝试重新添加排除项。" -ForegroundColor Green
Write-Host "如果问题仍然存在,请重启计算机后重试。" -ForegroundColor Yellow
```
### 使用说明:
1. **保存脚本**:将上述代码保存为 `.ps1` 文件(如 `FixDefenderPermissions.ps1`)
2. **执行脚本**:
```powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
.\FixDefenderPermissions.ps1
```
3. **验证修复**:打开 Windows 安全中心 > 病毒和威胁防护 > 管理设置 > 排除项,尝试添加新排除路径
### 脚本功能详解:
1. **权限自动提升**:自动检测并请求管理员权限
2. **递归权限修复**:
- 重置 `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions` 所有者
- 为 `Administrators`、`SYSTEM` 和 `TrustedInstaller` 添加完全控制权限
- 递归处理所有子注册表项
3. **服务重启**:自动重启 Windows Defender 服务应用更改
### 技术原理:
此脚本通过 PowerShell 的 ACL (Access Control List) 操作接口修复损坏的注册表权限链。关键步骤包括:
1. 使用 `SetOwner()` 方法将所有者重置为 Administrators
2. 通过 `RegistryAccessRule` 添加必要的访问控制规则
3. 递归处理子项确保完整修复
4. 服务重启确保内存中的权限状态更新
> ⚠️ **重要提示**:
> 1. 运行前建议创建系统还原点 (`rstrui`)
> 2. 企业环境中可能受组策略限制[^1]
> 3. 第三方安全软件可能覆盖权限设置[^2]
### 验证修复效果:
```powershell
# 检查权限是否修复
$acl = Get-Acl -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Exclusions"
$acl.Access | Format-Table IdentityReference, RegistryRights, AccessControlType
```
正常输出应包含:
```
IdentityReference RegistryRights AccessControlType
----------------- -------------- -----------------
BUILTIN\Administrators FullControl Allow
NT AUTHORITY\SYSTEM FullControl Allow
NT SERVICE\Trusted... FullControl Allow
```
### 相关问题:
阅读全文
相关推荐


















