在使用 PowerShell 查询 Active Directory 时,最常见的困扰之一是如何正确构建过滤器语法。对许多人来说,所有 ActiveDirectory PowerShell 模块 cmdlet 上的 Filter
和 LDAP Filter 参数都是一个黑盒子。
在本博文中,我们将深入了解如何使用 Active Directory 过滤器。希望在本文结束时,您将不再尝试使用那个 Where-Object
和 正确的过滤器!
先决条件
为了让我即将展示的任何代码都能正常工作,我将假设几件事:
- 您已安装了 PowerShell ActiveDirectory 模块
- 您在一个加入域的计算机上
- 您可以成功 连接并验证到 AD 域控制器
在使用许多 Active Directory cmdlet 进行对象搜索时,有两种不同的过滤器语言可供使用:PowerShell 过滤器和 LDAP 过滤器。
PowerShell 过滤器
PowerShell 过滤器使用标准的 PowerShell 表达式语法。这通常被称为 Active Directory 搜索过滤器语法。
这些过滤器与 Filter
参数一起使用。 Filter
参数的语法
运算符
在构建用于Filter
参数的筛选器时,您需要使用至少一个运算符。这里使用的运算符是您在使用类似于Where-Object
命令时可能已经熟悉的运算符。
在Filter
参数内部,您可以使用以下运算符。
Operator | Explanation |
---|---|
-eq | Equal to |
-le | Less than or equal to |
-ge | Greater than or equal to |
-ne | Not equal to |
-lt | Less than |
-gt | Greater than |
-approx | Approximately equal to |
-bor | Bitwise OR |
-band | Bitwise AND |
-recursivematch | Recursive match |
-like | Like |
-notlike | Not like |
-and | Boolean AND |
-or | Boolean OR |
-not | Boolean NOT |
参考AD对象属性
在筛选器内部,您将使用运算符比较各种AD对象属性。例如,Get-AdUser
cmdlet返回一个Name
属性。如果您想查找所有匹配特定名称的用户,您可以使用:
属性名称可以是通过AD cmdlet返回的属性的名称或LDAP筛选器名称。
属性值通常用单引号或双引号括起来。接受的唯一通配符是星号(*)。您可以看到上面的筛选器被双引号包围,但Adam Bertram被单引号包围。
在使用筛选器时,必须“转义”某些字符。这些字符包括:
Character | Escaped As | Notes |
---|---|---|
“ | `” | Only required if the data is enclosed in double quotes. |
‘ | \’ | Only required if the data is enclosed in single quotes. |
NUL | \00 | This is a standard LDAP escape sequence. |
\ | \5c | This is a standard LDAP escape sequence. |
* | \2a | Automatically escaped. Only in -eq and -ne comparisons. You should use -like and -notlike operators for wildcard comparison. |
( | /28 | Automatically escaped. |
) | /29 | Automatically escaped. |
/ | /2f | Automatically escaped. |
什么是Active Directory LDAP?
LDAP,或轻量级目录访问协议,是用于访问和修改目录数据的厂商中立协议。在听到目录这个词时,您可能会想到电话簿,但在Active Directory的上下文中,它意味着更多。许多不同类型的对象由Active Directory存储并通过LDAP协议提供访问。
由于Active Directory可以存储许多不同类型的数据,应用程序和用户需要一种方便查询该目录的方式。继续阅读以了解LDAP过滤器如何帮助过滤数据!
LDAP过滤器
Active Directory实现了LDAP,即轻量级目录访问协议。使用cmdlets的LDAPFilter
参数允许您使用LDAP过滤器,例如在Active Directory用户和计算机中创建的那些。
LDAP过滤器的语法在RFC编号4515中定义。
每个过滤规则都被括在圆括号( )
中。过滤规则可以通过将组括在括号中并包含以下比较器来进行分组:
Operator | Function |
---|---|
& | and |
| | or |
! | not |
LDAP过滤器还具有特殊的匹配规则对象标识符(OIDs):
OID | Purpose |
---|---|
1.2.840.113556.1.4.803 | Bitwise AND |
1.2.840.113556.1.4.804 | Bitwise OR |
1.2.840.113556.1.4.1941 | Chain matching (for distinguished name attributes) |
有四种过滤器类型:
Operator | Explanation |
---|---|
= | Equal to |
~= | Approximately equal to |
>= | Greater than or equal to |
<= | Less than or equal to |
有四种项目类型:
Type | Explanation |
---|---|
= | Simple |
=* | Present |
=something* | Substring |
Extensible | varies depending on type |
LDAP过滤规则必须与属性的LDAP名称一起使用,并且如果在LDAP过滤器中使用,某些字符值必须被’转义’。这些是:assistant:
Character | Escaped As |
---|---|
* | \2a |
( | \28 |
) | \29 |
\ | \5c |
NUL | \00 |
属性比较的数值通常不需要用引号括起来。
LDAP过滤器示例
构建LDAP过滤器可能会具有挑战性。以下是一些使用Active Directory组过滤器的示例,您可以以此为基础开始创建自己的过滤器。
- 所有名称(cn)为‘专业服务部’的组
'cn -eq "Professional Services Department"'
或 `'(cn=Professional Services Department)'
- 所有名称为‘专业服务部’且描述为‘Live’的组
'(cn -eq "Professional Services Department") -and (description -eq "Live")'
或'(&(cn=Professional Services Department)(description=Live))'
- 所有名称为‘专业服务部’或‘所有部门共享访问’的组
'(cn -eq "Professional Services Department") -or (cn -eq "All Departments Share Access")'
或'(|(cn=Professional Services Department)(cn=All Departments Share Access))'
- 所有没有“Live”描述的组。包括那些根本没有描述字段的组
'(!(description=Live))'
- 所有没有“Live”描述的组。排除那些根本没有描述字段的组
'description -ne "Live"'
- 所有具有“Live”描述但没有“专业服务部”名称的组
'(description -eq "Live") -and (cn -ne "Professional Services Department")'
或'(&(description=Live)(!(cn=Professional Services Department)))'
- 所有描述为‘\\fileserver1\fileshare’的组
'description -eq "\5c\5cfileserver1\5cfileshare"'
或'(description=\5c\5cfileserver1\5cfileshare)'
使用 RecursiveMatch 或 Chain Matching
使用匹配规则 OID,或者 RecursiveMatch
参数是解决关于查询 AD 的一个经常提出的问题的强大方式:‘我如何知道用户直接和间接是成员的所有组?’ 您可以使用 Active Directory 搜索过滤器 memberOf
属性来查找。
使用简单的LDAP匹配规则可能比大型脚本效率更高。以我们的示例域domain.local为例,Kristin Diaz是专业服务部门安全组的直接成员。查看她在AD中的memberOf
属性可以反映这一点;只显示专业服务部门。
通过使用匹配规则OID或RecursiveMatch
参数,您将发现他们间接是所有部门共享访问权限的成员。这是因为专业服务部门组是所有部门共享访问权限的成员。
两者都返回以下内容:
搜索基础和搜索范围参数
在大型环境中,AD可能包含成千上万的对象。改善性能并减少任何查询返回的对象数量的一种方法是限定搜索范围。
SearchBase
参数确定搜索在AD层次结构中的起始位置。在使用cmdlet时,这是一个区分名称的字符串表示(默认为域的“顶部”)。还有三个级别的SearchScope
:
- Base – 已指定为SearchBase的对象。
- OneLevel – 搜索立即包含在SearchBase中但不在任何子容器中的对象。
- SubTree – 递归地搜索包含在SearchBase中以及任何子容器中的对象,沿着AD层次结构向下。

在上述示例中,如果将 SearchBase 设置为 OU=All User Accounts,DC=domain,DC=local,则 SearchScope
设置为 Base
将尝试查询 OU 对象本身,SearchScope
设置为 OneLevel
将仅搜索 All User Accounts OU,而 SearchScope
设置为 SubTree
将同时搜索 All User Accounts 和 Professional Services OU。
总结
现在,您应该对如何使用 Active Directory PowerShell 命令进行过滤有了很好的理解。您可以看到,编写完美的过滤器语法要比使用 Where-Object
命令要困难得多。
但是花时间学习以“正确”的方式过滤 AD 对象,您将收获出色的性能和效率!