使用PowerShell获取文件夹所有权并设置继承时遇Set-Acl报错如何解决
故障原因
你遇到的报错核心原因是:当文件/文件夹的所有者为已删除AD账户对应的无效SID时,默认权限下Get-Acl无法读取该对象的ACL配置,返回空值,最终传给Set-Acl的AclObject参数为空触发报错。
解决步骤
- 前置要求
运行脚本的账户需具备本地管理员权限,且拥有「取得文件或其他对象的所有权」「备份/还原文件和目录」系统权限,建议直接以域管理员身份启动PowerShell运行。 - 脚本优化点
- 新增
Get-Acl错误捕获逻辑,避免空值传递 - 对ACL读取失败的对象,先调用系统自带
takeown命令强制夺取所有权,再重试ACL修改 - 添加执行日志输出,方便定位异常对象
优化后完整脚本
# 提前定义变量 $Dir = "需要处理的目标目录完整路径" $DomainAdmins = "你的域名\Domain Admins" $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $DomainAdmins # 获取所有对象,跳过访问被拒的提示 $ItemList = Get-ChildItem -Path $Dir -Recurse -ErrorAction SilentlyContinue foreach ($Item in $ItemList) { $Acl = $null try { # 尝试直接获取ACL $Acl = Get-Acl -Path $Item.FullName -ErrorAction Stop } catch { Write-Host "无法读取$($Item.FullName)的ACL,尝试强制夺取所有权" -ForegroundColor Yellow # 调用takeown强制取得所有权,/d y默认确认所有提示 & takeown /f $Item.FullName /a /d y | Out-Null # 夺取后重新获取ACL $Acl = Get-Acl -Path $Item.FullName -ErrorAction Stop } if ($null -ne $Acl) { # 设置所有者 $Acl.SetOwner($Account) # 启用权限继承,清除现有显式权限 $isProtected = $false $preserveInheritance = $false $Acl.SetAccessRuleProtection($isProtected, $preserveInheritance) # 应用ACL try { Set-Acl -Path $Item.FullName -AclObject $Acl -ErrorAction Stop Write-Host "处理完成:$($Item.FullName)" -ForegroundColor Green } catch { Write-Host "处理失败:$($Item.FullName),错误信息:$_" -ForegroundColor Red } } else { Write-Host "跳过无效对象:$($Item.FullName)" -ForegroundColor Red } }
补充说明
- 如果不需要清除现有显式权限,仅需要开启继承,可以把
$preserveInheritance改为$true - 脚本中
takeown的/a参数表示将所有权分配给管理员组,如果需要分配给当前运行用户可以去掉该参数 - 处理超大目录时可以去掉输出日志提升运行速度
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

