python查询AD域信息的方法总结
很多公司都在使用AD域来管理用户及组织架构,我们可以使用Python来进行自动化运维。网上很多资料不全而且都很古老,特地根据最近的代码编写经历,编写了如下通过python查询AD域信息方法总结:
环境: OS: Windows Python Version: 3.10.2 使用的库:ldap3 - 2.9.1
原理汇总:
通过LDAP协议来连接及访问AD域服务,可以把AD域理解成某种类型数据库,我们通过AD账号和密码来访问其中存储数据库字段信息。为了更好地了解其中字段及含义,建议下载一个ADExplorer.exe绿色工具软件,直接去微软官网下载免费的绿色软件,以下是下载链接(查看左边的菜单Networking Utilities中包含的Active Directory Explorer):
https://docs.microsoft.com/en-us/sysinternals/
通过这个软件,我们可以很方便地查看各种字段信息,为后面的连接获取足够的前提信息 。
#建立和关闭域连接 #域连接: from ldap3 import Server, Connection,SUBTREE #导入所需用到的ldap3库 import getpass #安全输入密码使用 #定义变量 ldap_url="xxx.com" #域控的dns名称 uid="your AD Account" #查询所用的域账号 pwd=getpass.getpass("Input your password: ") #输入所用的域密码,为了安全,避免保存 #定义连接函数 def ad_conn(): try: global conn #定义连接公共变量 m_tmp=[] #处理group member临时数组 server = Server(ldap_url, use_ssl=False, get_info="ALL") conn = Connection(server, auto_bind=True, user=uid,password=pwd,authentication="SIMPLE") except Exception as e: print(e) print("连接AD错误!") exit #关闭连接,为节约资源,显式关闭连接 def ad_unbind(): conn.unbind()
以上代码把连接和关闭连接分开,是为了避免在一个程序中需要频繁调用连接时,避免经常关闭,可以节省大量的资源和时间,可以在程序开头建立连接,在程序退出时才关闭即可
#模糊查询组信息 #模糊查询组成员,定义好查询范围,可以查找符合规则的组成员 base_dn="dc=ad,dc=xxx,dc=com" #根据实际的域信息更改,此为查找范围 def adgroup_s(gname): #gname为要模糊查询的组名称,可以为组名称其中的一部分 condition=f"(&(objectclass=group)(cn=*{gname}*))" #查找条件,注意两个查找条件是and关系 att_list=["name","member"] #为需要查询到的信息字段名称,需根据之前介绍的软件来查看 res=conn.search( base_dn,search_scope=SUBTREE, search_filter=condition, attributes=att_list) # #查找无记录 if not res: print(f"未找到{gname}的相关信息") ad_unbind() for ent in conn.entries: #通配符查询时,需用entries,以下取值可以根据自己所需实际情况来编写 n_tmp=json.loads(ent.entry_to_json())["attributes"]["name"] m_tmp=[x.split(",")[0] for x in json.loads(ent.entry_to_json())["attributes"]["member"]] for m in m_tmp: members.append([n_tmp[0],m.split("=")[1]]) return members
备注:查询条件规则参考如下:
(
&
(objectclass=group) #第一个条件
(cn=*{gname}*) #第二个条件
)
具体的规则可参考微软官方文档:
https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax
#模糊查询域中的workstation信息 #adou,如ou=workstations,ou=xxxx,ou=xxxx base_dn="dc=ad,dc=xxx,dc=com" #定义查找范围 def adou_computers(adou): computers_t=[] base_dn=",".join([adou,baseDN]) #查找范围 print(base_dn) condition=f"(objectclass=computer)" att_list=["name","whenchanged"] #为需要查询到的信息字段名称,需根据之前介绍的软件来查看 res=conn.search( base_dn,search_scope=SUBTREE, search_filter=condition, attributes=att_list) #如果查找无记录 if not res: print(f"未找到") ad_unbind() for r in conn.response: computers_t.append([",".join([r["dn"].split(",")[1],r["dn"].split(",")[2]]),r["attributes"]["name"],datetime.strftime(r["attributes"]["whenchanged"],"%Y/%m/%d")]) return computers_t
查询到所需信息以后,还可以直接调用pandas,保存为excel文件