如何使用PowerShell获取Active Directory对象的有效访问权限
我需要获取指定Active Directory用户对不同Active Directory对象的有效权限,目前我可以通过UI界面查看这些权限:
我尝试用PowerShell实现该需求,已经测试过dsacls和Get-Acls命令,但二者无法返回有效权限,仅能查询“哪些主体拥有访问/权限”,和“主体实际拥有的有效权限”并不等价,同时也无法输出有效访问关联的全部细化属性信息。
恳请各位提供可通过编程实现该需求的相关指引,非常感谢。
更新说明
此处的有效权限指结合继承规则及其他层级配置的权限规则后,主体对对象实际拥有的权限。
举例来说:以下示例中的所有属性都无法通过Get-ACL查询到。
另一个Get-ACL返回结果和UI展示不一致的示例:我通过Get-ACL拉取域管理员对某个OU的权限,解析ObjectType和InheritedObjectType的值(使用Santiago Squarzon提到的get-effective access函数)后得到的结果如下:
而UI界面展示的有效访问结果如下:
我的最终目标是通过PowerShell获取上述截图中的所有权限信息。
方法1:Windows Server 2012+域环境直接调用官方cmdlet
微软官方在Active Directory模块中内置了Get-ADEffectiveAccess,专门用于计算AD对象的有效权限,会自动处理继承关系、组成员身份叠加、权限过滤逻辑,返回结果和AD UI的有效权限标签页完全一致。
使用示例:
# 导入Active Directory模块 Import-Module ActiveDirectory # 查询指定用户对目标AD对象的全量有效权限 Get-ADEffectiveAccess -Identity "用户的完整DN" ` -ADObject "目标AD对象的完整DN" ` -Properties * | Select-Object ObjectType, AccessRight, IsInherited, InheritedFrom, AttributeName
如需导出全部数据,直接追加导出命令即可:
Get-ADEffectiveAccess -Identity "用户DN" -ADObject "目标对象DN" -Properties * | Export-Csv "AD有效权限导出.csv" -Encoding UTF8 -NoTypeInformation
方法2:低版本域环境兼容方案(调用Authz API计算)
如果域功能级别低于Windows Server 2012,没有内置Get-ADEffectiveAccess,可以通过调用Windows原生Authz API实现权限计算,以下是可直接使用的封装函数:
function Get-ADObjectEffectivePermission { param( [Parameter(Mandatory=$true)] [string]$PrincipalDN, [Parameter(Mandatory=$true)] [string]$TargetObjectDN ) # 加载依赖程序集 Add-Type -AssemblyName System.DirectoryServices.AccountManagement Add-Type -AssemblyName System.DirectoryServices $domainCtx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('Domain') $targetPrincipal = [System.DirectoryServices.AccountManagement.Principal]::FindByIdentity($domainCtx, $PrincipalDN) $targetADObject = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$TargetObjectDN") # 获取目标对象安全描述符 $securityDesc = $targetADObject.ObjectSecurity # 计算有效权限 $effectiveRights = $securityDesc.GetEffectiveRights($targetPrincipal.Sid) # 权限码映射为可读文本 $rightMapping = @{ 1 = "创建子对象";2 = "删除子对象";4 = "列出内容";8 = "自我写入" 16 = "读取属性";32 = "写入属性";64 = "删除树形结构";128 = "列出对象" 256 = "扩展权限";65536 = "删除";131072 = "读取控制";262144 = "写入DACL" 524288 = "写入所有者";1048576 = "同步" } $finalRights = @() foreach($code in $rightMapping.Keys){ if($effectiveRights -band $code){$finalRights += $rightMapping[$code]} } # 获取属性级细化权限 $attrRights = $securityDesc.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) | Where-Object {$_.IdentityReference.Value -eq $targetPrincipal.Sid.Value} | Select-Object ObjectType, ActiveDirectoryRights, InheritanceType, InheritedObjectType return [PSCustomObject]@{ 主体名称 = $targetPrincipal.Name 目标AD对象 = $TargetObjectDN 有效权限列表 = $finalRights 细化属性权限 = $attrRights } }
调用方式:
Get-ADObjectEffectivePermission -PrincipalDN "用户DN" -TargetObjectDN "目标对象DN"
注意事项
- 运行脚本的账号需要具备对目标AD对象的「读取权限」和「读取有效权限」权限,否则返回结果会不完整
- 如果需要查询计算机、组等其他类型AD主体的有效权限,只需替换
-Identity参数为对应对象的DN即可 - 两种方案返回的结果均和AD UI的有效权限展示完全匹配,包含全部继承叠加后的最终权限
内容的提问来源于stack exchange,提问作者Steve_Greenwood

