LDAP 过滤语法是什么
PowerShell 的 AD 模块里,-Filter 用的是 PowerShell 自己的表达式语法,-LDAPFilter 则要求写标准的 LDAP 搜索过滤器。后者表达力更强,尤其是涉及位运算(例如判断账户是否禁用)和复杂嵌套时。语法核心很简单:属性运算符值写在括号里,& 表示与、| 表示或、! 表示非,每一层都要用自己的括号包住。
基本信息
| 适用平台 | Windows Server AD DS 与 RSAT 的 AD 模块 |
|---|---|
| 基本形式 | (属性=值);(objectClass=user);(&(A)(B));(|(A)(B));(!(A)) |
| 通配符 | (sAMAccountName=ops*);(telephoneNumber=*) 表示“有值” |
| 位运算 | (userAccountControl:1.2.840.113556.1.4.803:=2) 表示“禁用位已设置” |
| 常见属性名 | objectClass、objectCategory、cn、sAMAccountName、mail、memberOf |
典型使用场景
- 精确筛选用户:排除计算机账户,只取人员对象
- 查禁用账户:用位运算判断 userAccountControl 的禁用位
- 查缺字段对象:找出没有邮箱或没有电话号码的账号做数据治理
- 嵌套条件:某部门且有邮箱且未禁用的账号清单
- 性能优化:用过滤器在域控侧先筛,而不是把全部对象拉回本地过滤
常用示例
常用示例
# 只取用户对象且有邮箱(分页示例)
Get-ADUser -LDAPFilter '(&(objectClass=user)(objectCategory=person)(mail=*))' -Properties mail |
Select-Object Name, sAMAccountName, mail
# 找出被禁用的用户(UAC 位运算:禁用位 = 2)
Get-ADUser -LDAPFilter '(&(objectClass=user)(objectCategory=person)(userAccountControl:1.2.840.113556.1.4.803:=2))' |
Select-Object Name, sAMAccountName
# 姓氏为张且未禁用的用户
Get-ADUser -LDAPFilter '(&(sn=张*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' | Select-Object Name
# 或用 -Filter 写等价表达式(更易读但不支持位运算)
Get-ADUser -Filter 'Enabled -eq $true -and sn -like "张*"' | Select-Object Name语法要素速记
| 要素 | 写法 | 说明 |
|---|---|---|
| 相等 | (cn=张三) | 精确匹配 |
| 通配 | (mail=*) | 属性存在即匹配 |
| 与 | (&(A)(B)) | 全部条件满足 |
| 或 | (|(A)(B)) | 任一条件满足 |
| 非 | (!(A)) | 取反,注意整体括号 |
| 位与 | (attr:OID:=值) | 用于 UAC 等位标志属性 |
过滤器里每一层都必须有自己的一对括号:(sn=张*) 合法,(&(sn=张*)(mail=*)) 的每一层括号也不能省。少写一层会直接报语法错误,报错信息通常不会指出具体位置。
LDAP 过滤器用的是 LDAP 属性名(sAMAccountName、sn、objectCategory),不是 PowerShell 的显示名(SamAccountName、Surname)。这是从 -Filter 切到 -LDAPFilter 后最常见的失败原因。
查询范围不宜过大:不加过滤地把全部对象拉回来再本地筛选,会给域控和网络都带来压力。能用过滤器表达的筛选尽量放到过滤器中,让域控侧完成。