已获取注册表项所有权,如何修改原有ACL并应用到所有子项?
解决注册表ACL修改及递归应用到子项的问题
一、修改原有ACL(避免保留旧规则)
你当前使用SetAccessRule时,默认是添加新规则而非替换同用户的现有规则,因此原有ACL会保留。要修改目标用户的权限,需先移除该用户的现有访问规则,再添加新规则:
# 目标注册表路径 $keyPath = 'HKLM:\SOFTWARE\MyKEY' # 获取当前项的ACL $acl = Get-Acl -Path $keyPath # 定义新的访问规则 $newAccessRule = New-Object System.Security.AccessControl.RegistryAccessRule( "BUILTIN\Users", # 中文系统需改为"BUILTIN\用户" "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow" ) # 查找并移除Users组的所有现有规则 $existingRules = $acl.Access | Where-Object { $_.IdentityReference.Value -eq "BUILTIN\Users" } foreach ($rule in $existingRules) { $acl.RemoveAccessRule($rule) } # 添加新规则并应用 $acl.AddAccessRule($newAccessRule) Set-Acl -Path $keyPath -AclObject $acl
二、递归应用ACL到所有子项
要将修改后的ACL同步到目标项的所有子项,可通过两种方式实现:
方法1:递归函数遍历
function Set-RegistryAclRecursively { param( [string]$RegistryPath, [System.Security.AccessControl.RegistrySecurity]$TargetAcl ) # 设置当前项的ACL Set-Acl -Path $RegistryPath -AclObject $TargetAcl # 遍历所有子项并递归设置 $childKeys = Get-ChildItem -Path $RegistryPath -ErrorAction SilentlyContinue foreach ($childKey in $childKeys) { Set-RegistryAclRecursively -RegistryPath $childKey.PSPath -TargetAcl $TargetAcl } } # 先修改根项的ACL(复用上面的代码) $rootKeyPath = 'HKLM:\SOFTWARE\MyKEY' $acl = Get-Acl -Path $rootKeyPath $newAccessRule = New-Object System.Security.AccessControl.RegistryAccessRule( "BUILTIN\Users", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow" ) $existingRules = $acl.Access | Where-Object { $_.IdentityReference.Value -eq "BUILTIN\Users" } foreach ($rule in $existingRules) { $acl.RemoveAccessRule($rule) } $acl.AddAccessRule($newAccessRule) Set-Acl -Path $rootKeyPath -AclObject $acl # 调用函数递归应用到所有子项 Set-RegistryAclRecursively -RegistryPath $rootKeyPath -TargetAcl $acl
方法2:批量遍历所有项
$rootKeyPath = 'HKLM:\SOFTWARE\MyKEY' # 获取修改后的根项ACL $modifiedAcl = Get-Acl -Path $rootKeyPath # 递归获取所有子项,包含根项本身 $allRegistryKeys = Get-ChildItem -Path $rootKeyPath -Recurse -ErrorAction SilentlyContinue $allRegistryKeys += Get-Item -Path $rootKeyPath # 批量设置ACL foreach ($key in $allRegistryKeys) { Set-Acl -Path $key.PSPath -AclObject $modifiedAcl }
注意事项
- 必须以管理员身份运行PowerShell,否则无法修改HKLM路径下的注册表权限。
- 用户组标识需匹配系统语言,中文系统改为
"BUILTIN\用户"。 -ErrorAction SilentlyContinue用于跳过无法访问的子项,避免脚本中断。
内容的提问来源于stack exchange,提问作者zexal985236
相关产品推荐
相关产品推荐

