1

我以前有这个工作。现在,在平整和重建机器之后,我似乎无法让 pyad 工作。

我的脚本使用 adquery 来获取域的成员。

我已经安装了正确版本的 pyad 和 pywin32。我正在使用 Python 3.6。

我不断收到以下错误:

pywintypes.com_error: (-2147352567, '发生异常。', (0, 'Active Directory', '指定的域不存在或无法联系。\r\n', None, 0, -2147217865),没有任何)

该脚本之前完美运行,所以我假设这是一个安装问题。

这是我写的函数:

from pyad import adquery, aduser, adbase

def call_adquery(domain, debug):

global numRow
log.info('Domain: {}'.format(domain))
df = pd.DataFrame()
z_obj = adquery.ADQuery()
t = datetime.today().strftime('%m/%d/%Y')
i = 0
if domain == 'satyan':
    wc = "mailNickname='satyan'"
    domain = 'redmond'
else:
    wc = """
    objectClass='user'
    and showInAddressBook='*'
    and manager='*'
    and not mailNickname='b-*'
    """
dn = base_dn = 'OU=UserAccounts,DC={0}, DC=corp,DC=microsoft,DC=com'.format(domain)
att = ['name', 'displayName', 'title', 'company', 'msExchHideFromAddressLists',
       'manager', 'mail', 'mailNickname', 'distinguishedName', 'extensionAttribute4',
       'extensionAttribute2','sn','cn','givenName', 'instanceType','userPrincipalName',
       'objectCategory']
z_obj.execute_query(attributes=att, where_clause=wc, base_dn=dn, type='GC')
for row in z_obj.get_results():
    i += 1
    numRow += 1
    n = pd.Series.from_array(row)
    log.info("{0}, {1}, {2}, {3}".format(numRow, i, domain, row['name']))
    n['domain'] = domain
    n['date'] = t
    df = df.append(n, ignore_index=True)
    if (debug==True) and (i == 10): break
log.info('Count for {0}: {1}'.format(domain, i))
return df
4

1 回答 1

2

不知道为什么我因为问一个问题而被骂。也许这就是stackoverflow的工作方式。

我想出了答案,它并不像更改域那么简单。安德鲁,我非常感谢您的回复,因为它让我走上了正确的道路。

我花了很多时间调试这个。我什至尝试使用 ldap3 - 一个不同的 python AD 库。如果您的结果集少于 1000 个,那是错误的,但速度会更快。我永远无法搜索超过 1000 条记录的页面 - AD 限制。最终,我回到 pyad 并找出了问题所在。Pyad 是一个更易于使用的模块——在我看来。

我了解了 LDAP 服务器和 GC 服务器之间的区别。GC 服务器能够为林中的所有域提供大多数属性。我能够使用 powershell 识别网络上的 GC 服务器:

> $GCs = Get-ADForest
> $GCs.GlobalCatalogs

完成后,我在 pyad 中设置了 LDAP 服务器:

z_obj.default_ldap_server='xxxx.corp.microsoft.com'  

我还从查询中删除了一些属性。不确定这是否是一个因素。

最终结果工作得很好,无需将用户名和密码发送到 pyad。这是有效的代码:

def call_adquery(domain, debug=False):
    df = pd.DataFrame()
    z_obj = adquery.ADQuery()
    i = 0
    wc = """
    objectClass='person'
    and SAMAccountType='805306368'
    and userAccountControl='512'
    """
    dn = 'OU=UserAccounts,DC={0},DC=corp,DC=microsoft,DC=com'.format(domain)
    att = ['givenName', 'mail', 'manager',
            'Name',
            'displayName','Title','mailNickName',
            'Department','Company',
            'userPrincipalName','sn','cn', 'DistinguishedName',
            'physicalDeliveryOfficeName']
    z_obj.default_ldap_server='<gc from powershell>' 
    z_obj.execute_query(attributes=att, where_clause=wc, base_dn=dn, type='GC')
    df = pd.DataFrame()
    for row in z_obj.get_results():
         i += 1
         if (debug==True) and (i == 10): 
            break
         if len(df)==0:
            df =pd.DataFrame(row, index=[0])
         else:
            df= df.append(row, ignore_index=True)
     return df

我的猜测是我的默认活动目录服务器已更改,因此导致我脆弱的代码失败。

希望这对其他人有帮助。

于 2017-04-26T00:41:56.820 回答