【问题标题】:Conquering Active Directory's 1000 record limit克服 Active Directory 的 1000 条记录限制
【发布时间】:2018-05-10 08:46:03
【问题描述】:

PowerShell 能够提取 1492 条记录的列表。当我将 Python 与 ldap3 模块一起使用时,我遇到了 1000 条记录的限制。请帮我更改 Python 代码以超出限制。

PowerShell 输入:get-aduser -filter * -SearchBase "OU=SMZ USERS,OU=SMZ,OU=EUR,DC=my_dc,DC=COM" | Measure-Object

输出: 计数:1492 平均的 : 总和: 最大 : 最低限度 : 属性:

import json
from ldap3 import Server, \
Connection, \
AUTO_BIND_NO_TLS, \
SUBTREE, \
ALL_ATTRIBUTES

def get_ldap_info(u):
with Connection(Server('my_server', port=636, use_ssl=True),
                auto_bind=AUTO_BIND_NO_TLS,
                read_only=True,
                check_names=True,
                user='my_login', password='my_password') as c:

    c.search(search_base='OU=SMZ Users,OU=SMZ,OU=EUR,DC=my_dc,DC=com',
             search_filter='(&(samAccountName=' + u + '))',        
             search_scope=SUBTREE,
             attributes=ALL_ATTRIBUTES,
             size_limit = 0,
             paged_criticality = True,                 
             paged_size = None,
             #attributes = ['cn'],
             get_operational_attributes=True)        

    content = c.response_to_json()
result = json.loads(content)
i = 0
for item in result["entries"]:
    i += 1
print(i)  
get_ldap_info('*')

【问题讨论】:

  • Powershell 中的 AD CMDlet 使用 Active Directory Web 服务与 DC 通信,因此与使用 System.DirectoryServices(我也限制为 1000 个对象)相比,它们的行为可能不同
  • Get-Aduser 有一个 -ResultSetSize 参数来设置限制,如果有帮助,请检查 pythoh 代码:novell.com/coolsolutions/tip/18274.html
  • 如果你想分页搜索,似乎你不应该将paged_size设置为None
  • @Bill_Stewart 更改 paged_size 并不能解决问题。如果我将它设置为 10,它会拉出 10 条记录。如果我将其设置为 1500,它会拉动 1000。
  • 我相信你必须同时设置paged_sizesize_limit。但除此之外,我不是该特定模块的专家。

标签: python powershell active-directory ldap


【解决方案1】:

如果您将代码更改为使用 extend.standard 命名空间的 paged_search 方法,您应该能够检索到您正在寻找的所有结果。

请注意,您需要区别对待响应对象。

def get_ldap_info(u):
with Connection(Server('XXX', port=636, use_ssl=True),
                auto_bind=AUTO_BIND_NO_TLS,
                read_only=True,
                check_names=True,
                user='XXX', password='XXX') as c:

    results = c.extend.standard.paged_search(search_base='dc=XXX,dc=XXX,dc=XXX',
             search_filter='(&(samAccountName=' + u + '))',        
             search_scope=SUBTREE,
             attributes=ALL_ATTRIBUTES,
             #attributes = ['cn'],
             get_operational_attributes=True)        


i = 0
for item in results:
    #print(item)
    i += 1
print(i)  
get_ldap_info('*')

【讨论】:

  • 返回1000多条记录。你已经回答了我的问题。谢谢! :D
  • 要从结果生成器中提取数据,您可以使用import pandas as pd;json_ls=[l["tag"] for l in results]; df = pd.DataFrame(json_ls)。它将从生成器中提取 dict 并加载到 pandas 数据帧中。
  • 此建议不断打破 1000k 记录的相同结果。您应该使用 cookie 作为下面的下一个答案重新绑定。
【解决方案2】:

解决方案可在以下link 中找到。

这段代码将逐页获取。

from ldap3 import Server, Connection, SUBTREE
total_entries = 0
server = Server('test-server')
c = Connection(server, user='username', password='password')
c.search(search_base = 'o=test',
         search_filter = '(objectClass=inetOrgPerson)',
         search_scope = SUBTREE,
         attributes = ['cn', 'givenName'],
         paged_size = 5)
total_entries += len(c.response)
for entry in c.response:
    print(entry['dn'], entry['attributes'])
cookie = c.result['controls']['1.2.840.113556.1.4.319']['value']['cookie']
while cookie:
    c.search(search_base = 'o=test',
             search_filter = '(objectClass=inetOrgPerson)',
             search_scope = SUBTREE,
             attributes = ['cn', 'givenName'],
             paged_size = 5,
             paged_cookie = cookie)
    total_entries += len(c.response)
    cookie = c.result['controls']['1.2.840.113556.1.4.319']['value']['cookie']
    for entry in c.response:
        print(entry['dn'], entry['attributes'])
print('Total entries retrieved:', total_entries)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    相关资源
    最近更新 更多