You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过递归LDAP查询获取AD中未过期的临时组成员关系

如何通过递归LDAP查询获取AD中未过期的临时组成员关系

我完全懂你的困扰——当用AD的临时组成员功能(带MemberTimeToLive)时,过期后Get-ADGroup加-ShowMemberTimeToLive参数能正确过滤掉过期成员,但直接用LDAP传递匹配查询用户的递归组时,居然还能看到已经过期的组。这其实是因为LDAP的1.2.840.113556.1.4.1941传递匹配规则默认不会检查临时成员的过期时间,得我们手动加过滤条件才行。

先搞懂背后的原因

AD的临时成员关系是靠给组的成员项添加msDS-MemberExpirationTime属性实现的——这个属性存的是成员关系过期的时间戳(FILETIME格式)。Get-ADGroup的-ShowMemberTimeToLive参数会让PowerShell自动帮你比对这个时间戳,过滤掉过期的成员;但原生LDAP查询不会做这个默认校验,所以传递匹配会把所有历史/过期的递归成员关系都返回。

两种解决方案,按需选择

方法1:PowerShell先拿所有递归组,再逐个过滤(逻辑直观)

先通过LDAP传递查询拿到用户的所有递归组,再对每个组检查用户是否属于未过期成员。好处是逻辑简单,用PowerShell内置参数处理过期校验,缺点是组多的话速度会慢一点。

示例代码:

# 定义目标用户和DC服务器
$userDN = "CN=TEST_user,OU=Guests,OU=Special accounts,DC=TEST,DC=EXAMPLE,DC=nl"
$dcServer = "EXAMPLEdc03"

# 先获取用户的所有递归组
$allRecursiveGroups = Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=$userDN)" -Server $dcServer

# 筛选出用户是未过期成员的组
$activeGroups = foreach ($group in $allRecursiveGroups) {
    $groupDetails = Get-ADGroup $group -Properties Members -ShowMemberTimeToLive -Server $dcServer
    if ($groupDetails.Members -contains $userDN) {
        $group
    }
}

# 输出结果
$activeGroups | Sort-Object Name | Select Name | Format-Table

方法2:构造带过滤的LDAP查询(更高效)

如果想一步到位,直接用LDAP查询同时实现递归匹配和过期时间过滤,需要构造复合查询:既要匹配用户是组的递归成员,又要匹配该成员关系要么是永久的(无过期时间),要么过期时间在当前时间之后。

示例代码:

# 定义目标用户和DC服务器
$userDN = "CN=TEST_user,OU=Guests,OU=Special accounts,DC=TEST,DC=EXAMPLE,DC=nl"
$dcServer = "EXAMPLEdc03"

# 把当前时间转换成AD用的FILETIME格式
$currentFileTime = (Get-Date).ToFileTime()

# 构造复合LDAP过滤器
$ldapFilter = @"
(&
    (member:1.2.840.113556.1.4.1941:=$userDN)
    (|
        (!(msDS-MemberExpirationTime=*))  # 匹配永久成员(无过期时间属性)
        (msDS-MemberExpirationTime>=$currentFileTime)  # 匹配未过期的临时成员
    )
)
"@ -replace "`n|`r", ""  # 移除换行,确保LDAP能识别

# 执行查询并输出
Get-ADGroup -LDAPFilter $ldapFilter -Server $dcServer | Sort-Object Name | Select Name | Format-Table

这个查询会直接返回所有用户是递归成员、且成员关系未过期(或永久)的组,效率比逐个查询高很多。

针对你测试案例的验证

在你的测试中,当TEST_user在TEST_x组的30秒TTL过期后,用这个LDAP查询就不会再返回TEST_x了——因为msDS-MemberExpirationTime已经小于当前时间,会被过滤掉。如果有未过期的嵌套组(比如TEST_y包含TEST_x且TEST_x的成员关系还在有效期内),查询也会正确返回TEST_y。

备注:内容来源于stack exchange,提问作者rrr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:58:12