如何用LDAP3查询Active Directory账户过期时间并转日期
解决LDAP3查询Active Directory账户过期时间的问题
一、修正搜索过滤器与属性指定
你当前的搜索过滤器不符合需求,需要调整为针对用户对象的筛选规则,同时明确指定要获取存储账户过期时间的accountExpires属性:
修正后的搜索代码:
from ldap3 import Server, Connection, ALL, NTLM, SUBTREE server = Server(server_name, port=636, use_ssl=True, get_info=ALL) conn = Connection(server, user=f'{domain_name}\\{user_name}', password=password, authentication=NTLM, auto_bind=True) # 精准筛选AD中的用户对象,避免包含联系人等非用户条目 search_filter = '(&(objectClass=user)(objectCategory=person))' # 指定需要获取的属性,添加samAccountName方便对应具体账户 attributes = ['samAccountName', 'accountExpires'] conn.search( search_base=f'OU={root_ou},OU={sub_ou},OU={org_ou},DC={domain_name},DC={domain_suffix}', search_filter=search_filter, search_scope=SUBTREE, attributes=attributes )
过滤器说明:
(&(objectClass=user)(objectCategory=person))是更严谨的用户筛选条件,既能确保只返回用户对象,又能排除AD中存在的联系人等非用户条目;如果需求简单,也可以直接使用(objectClass=user)作为过滤器。
二、转换accountExpires为可读日期格式
AD的accountExpires值是自1601年1月1日(UTC)起的100纳秒间隔数,其中0或9223372036854775807(即0x7FFFFFFFFFFFFFFF)代表账户永不过期。以下是转换函数及使用示例:
import datetime def convert_ad_expires_to_readable(expires_value): # 处理永不过期的特殊情况 if expires_value in (0, 9223372036854775807): return "永不过期" # 计算1601年到Unix纪元(1970年)的秒数差 epoch_offset = (datetime.datetime(1970, 1, 1) - datetime.datetime(1601, 1, 1)).total_seconds() # 将100纳秒单位转换为秒,减去偏移量得到标准Unix时间戳 expires_timestamp = int(expires_value) / 10**7 - epoch_offset # 转换为UTC格式的可读日期字符串 return datetime.datetime.utcfromtimestamp(expires_timestamp).strftime('%Y-%m-%d %H:%M:%S UTC') # 遍历查询结果并输出转换后的过期时间 for entry in conn.entries: account_name = entry.samAccountName.value expires_raw = entry.accountExpires.value expires_readable = convert_ad_expires_to_readable(expires_raw) print(f"账户 {account_name} 的过期时间:{expires_readable}")
转换逻辑说明:
- 先判断是否为永不过期的特殊值;
- 计算AD起始时间到Unix纪元的秒数差,作为时间偏移量;
- 将
accountExpires的100纳秒值转换为秒,减去偏移量得到标准Unix时间戳; - 最后将时间戳转换为UTC格式的可读日期字符串。
内容的提问来源于stack exchange,提问作者wishi
相关产品推荐
相关产品推荐

