获取与文件夹权限关联的双层AD组的PowerShell脚本需求
获取与文件夹权限关联的双层AD组的PowerShell脚本需求
嘿Ian,这问题问得很实在!先直接给你划重点:没办法完全脱离文件夹只靠AD组来搞定这件事——因为你得先搞清楚「哪些AD组直接拥有这个文件夹的权限」,这一步的信息只能从文件夹的ACL(访问控制列表)里拿,AD本身根本不知道哪个组和哪个文件夹的权限挂钩。不过别担心,我们可以用PowerShell把整个流程串起来,一步到位拿到你要的「双层关联组」(文件夹→直接权限组→嵌套成员组)。
完整思路和脚本示例
下面是一套可以直接用的脚本,我会拆开来给你讲清楚每一步:
第一步:定义目标文件夹并获取直接有权限的AD组
首先我们得先定位到目标文件夹,然后从它的权限列表里筛选出真正的AD组(排除本地账号、内置用户这些):
# 替换成你的目标文件夹路径 $targetFolder = "D:\Your\Important\Folder" # 获取文件夹的访问控制列表 $folderAcl = Get-Acl -Path $targetFolder # 过滤出拥有权限的AD组(这里的YOURDOMAIN要替换成你的域名) $directPermissionGroups = $folderAcl.Access | Where-Object { # 只保留域名前缀的身份,并且验证确实是AD组 $_.IdentityReference.Value -match "^YOURDOMAIN\.*" -and (Get-ADGroup -Filter {SamAccountName -eq $_.IdentityReference.Value.Split("\")[1]} -ErrorAction SilentlyContinue) } | Select-Object -ExpandProperty IdentityReference | ForEach-Object { # 提取组名(去掉域名前缀) $_.Value.Split("\")[1] } # 输出直接有权限的AD组,方便你确认起点 Write-Host "直接拥有文件夹权限的AD组:" -ForegroundColor Cyan $directPermissionGroups
第二步:从直接权限组回溯第二层嵌套组
拿到直接有权限的组之后,我们就可以去AD里查这些组的成员,并且只筛选其中的组账号(排除用户),这就是你要的「两次移除」的关联组:
# 用来存储最终结果的数组 $doubleRemovedGroups = @() foreach ($group in $directPermissionGroups) { try { # 获取当前组的直接成员(注意这里用-Recursive:$false,只取直接嵌套的组,不深入多层) $groupMembers = Get-ADGroupMember -Identity $group -Recursive:$false | Where-Object { $_.objectClass -eq "group" } # 把结果整理成易读的格式 foreach ($nestedGroup in $groupMembers) { $doubleRemovedGroups += [PSCustomObject]@{ 直接权限组 = $group 嵌套关联组 = $nestedGroup.Name 关联组账号名 = $nestedGroup.SamAccountName } } } catch { Write-Warning "查询组 $group 的成员时出错:$_" } } # 输出最终的双层关联组列表 Write-Host "`n与文件夹权限关联的双层AD组:" -ForegroundColor Green $doubleRemovedGroups | Format-Table -AutoSize
关键注意事项
- 你需要先安装RSAT-AD-PowerShell模块(Windows Server默认有,客户端需要在「可选功能」里添加);
- 运行脚本的账号需要同时具备:读取目标文件夹ACL的权限,以及读取AD组信息的权限;
- 脚本里的
YOURDOMAIN要替换成你的实际域名,比如CONTOSO; - 如果需要深入多层嵌套(不止两层),可以把
-Recursive:$false改成-Recursive:$true,但你要的是「twice-removed」,所以保持$false就好。
再回到你的核心问题
为什么不能只靠AD组?因为AD只记录组的成员关系,根本不知道哪个组被赋予了哪个文件夹的权限——权限是存储在文件系统的ACL里的,所以必须从文件夹入手找到起点组,再回溯AD里的嵌套关系。不过整个流程已经被脚本自动化了,你只需要填个文件夹路径就能拿到结果~
备注:内容来源于stack exchange,提问作者manitoba_RDC




