Windows AD PowerShell(十四):清理与维护
这是 Windows AD PowerShell 学习记录的第十四节。维护的重点不是“找到就删”,而是先弄清对象是否仍被业务、权限或策略引用。
数据来源说明:2026 年 9 月 28 日通过已有的 ldap3 环境对实验域
qy.net做了只读查询:当前有 12 个 OU,其中 2 个没有直接子对象;查询到 33 个带sAMAccountName的用户对象,未发现重复;本节没有在 VM 的 PowerShell 控制台逐条执行命令。标有“格式示例”的输出按目录查询结果整理,不能当作命令实机直出。本节未删除或修改任何 AD 对象、文件权限。
十四、清理与维护
14.1 查找空 OU
原先大纲的 Get-ADOrganizationalUnit -Filter * -Properties Children 不适合作为“空 OU”判断依据。要判断一个 OU 有没有直接子对象,对每个 OU 做一次 OneLevel 查询即可;子对象可能是用户、组、计算机或子 OU,不应只查子 OU。
# 找出没有任何直接子对象的 OU;只取一个对象就足以判断“非空”Get-ADOrganizationalUnit -Filter * | ForEach-Object { $ou = $_ $child = Get-ADObject -Filter * ` -SearchBase $ou.DistinguishedName ` -SearchScope OneLevel ` -ResultSetSize 1
if (-not $child) { $ou | Select-Object Name, DistinguishedName } }
# 按 VM 目录查询结果整理的格式示例,非 PowerShell 实机直出Name DistinguishedName---- -----------------User OU=User,OU=Development,OU=Organization,DC=qy,DC=netComputer OU=Computer,OU=Development,OU=Organization,DC=qy,DC=net**VM 实测:**当前有 12 个 OU,其中上面 2 个没有直接子对象。OneLevel 只检查紧邻的下一层;如果其中有子 OU,它就不是“空 OU”,哪怕子 OU 内也没有用户。
⚠️ **空 OU 不等于可以删除。**它可能是预留的入域位置,或有 GPO 链接、委派权限与自动化脚本依赖。先核对用途,再考虑清理;OU 可能还启用了“防止意外删除”。
删除前可先查看保护状态及直接链接的 GPO:
Get-ADOrganizationalUnit ` -Identity 'OU=User,OU=Development,OU=Organization,DC=qy,DC=net' ` -Properties ProtectedFromAccidentalDeletion,gPLink | Select-Object Name,ProtectedFromAccidentalDeletion,gPLink
# 查询命令未在 VM PowerShell 中执行;请以现场结果为准gPLink 为空只表示此 OU 没有直接链接 GPO,不代表它不会继承上级策略。相关检查见第十五节:GPO 相关。
14.2 查找需要核实的“裸 SID”
账户被删除后,文件或文件夹的 ACL 里可能还留有该账户的 SID。可以先检查指定共享目录,不要一上来扫描整台服务器:
# 把 D:\Share 换成你要排查的实际目录;把根目录本身也纳入检查$items = @(Get-Item -LiteralPath 'D:\Share') + @(Get-ChildItem -LiteralPath 'D:\Share' -Recurse -Force)
$items | ForEach-Object { $path = $_.FullName (Get-Acl -LiteralPath $path).Access | Where-Object { $_.IdentityReference.Value -match '^S-1-5-21-\d+-\d+-\d+-\d+$' } | Select-Object @{Name='Path';Expression={$path}}, IdentityReference,FileSystemRights,AccessControlType}
# 格式示例:本节未扫描实验环境中的 D:\SharePath IdentityReference FileSystemRights AccessControlType---- ----------------- ---------------- --------------D:\Share\OldProject S-1-5-21-111111111-222222222-333333333-1234 ReadAndExecute AllowGet-ChildItem -Recurse 在大型目录上可能很慢,也可能遇到拒绝访问、重解析点或长路径问题;上面的命令适合小范围学习与排查,不能当作“全盘 ACL 审计工具”。
💡 **裸 SID 只是线索,不是“账户已被删除”的证明。**身份解析也可能因为域控暂时不可达、信任关系异常、外域账户或权限不足而失败。确认账户与资源用途之前,不要批量删除 ACL 项;删除 ACL 也不会删除文件。
如果只想看该目录根节点的 ACL,可以先从最小范围开始:
Get-Acl -LiteralPath 'D:\Share' | Select-Object -ExpandProperty Access | Select-Object IdentityReference,FileSystemRights,AccessControlType
# 查询命令未在 VM 上执行;输出取决于目标目录的实际 ACL14.3 查重复的 sAMAccountName
先复习一下原大纲中的检查:
# 只检查当前查询域中的用户对象Get-ADUser -Filter * | Group-Object SamAccountName | Where-Object { $_.Count -gt 1 } | Select-Object Name,Count
# VM 目录只读查询:33 个带 sAMAccountName 的用户对象,未发现重复;预期无输出sAMAccountName 需要在同一个域的安全主体之间保持唯一,所以正常情况下不应查出重复。这里的 Get-ADUser 只取用户,不覆盖组、计算机,更不是全林查重;不同域出现相同的短登录名也不一定是错误。若真查到同域重复,应先复核查询范围、对象类型和数据来源,不要直接改名。Microsoft 的用户创建说明对此唯一性有明确要求。
日常清理更常用的是找“疑似废弃”的用户或计算机,但不活跃不等于可删除。计算机的候选清单、隔离观察流程见第三节:计算机;误删对象的恢复边界见第十一节:备份与恢复。
14.4 一道小排障题
巡检发现某个 OU 为空,文件共享 ACL 中还有一个裸 SID。能否分别直接删除?
不能。先确认 OU 是否为预留位置、是否有直接或继承的 GPO、是否有委派或脚本依赖;再确认 SID 是否真的无法解析、可能属于哪个域、权限是否仍被业务使用。最后才进入审批、备份、预演与变更窗口。“查出来”只是调查开始,不是删除许可。
参考资料
- Microsoft Learn:Get-ADOrganizationalUnit
- Microsoft Learn:Get-ADObject 与 OneLevel 查询
- Microsoft Learn:Get-Acl
- Microsoft Learn:
sAMAccountName的唯一性
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!













