在學習 AD 時掌握 PowerShell 中的 LDAP 過濾器

在使用 PowerShell 查询 Active Directory 时,最常见的问题之一是如何正确构建筛选语法。对于许多人来说,ActiveDirectory PowerShell 模块 cmdlet 中的 Filter 和 LDAP Filter 参数是一个黑匣子。

在本博客文章中,我们将深入了解如何使用 Active Directory 筛选器。希望通过本文的结束,您将不再尝试使用那个 Where-Object 和正确的筛选器

先决条件

为了使我即将展示的代码正常工作,我将假设一些前提条件:

在使用许多 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 屬性。如果您想查找所有匹配特定名稱的使用者,您可以使用:

PS51> Get-Aduser -Filter "Name -eq 'Adam Bertram'"

屬性名稱可以是使用 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 的上下文中,它意味著更多。許多不同類型的對象都被存儲並通過 LDAP 協議訪問 Active Directory,這是一種訪問該數據的手段。

由於 Active Directory 可以存儲許多不同的數據類型,應用程序和用戶需要一種簡便的方式來查詢該目錄。繼續閱讀以了解 LDAP 過濾器如何幫助篩選該數據!

LDAP 過濾器

Active Directory 實現了 LDAP,即輕量級目錄訪問協定。使用 cmdlet 的 LDAPFilter 參數可以使用 LDAP 過濾器,例如那些在 Active Directory 用戶和計算機中創建的過濾器。

LDAP 過濾器的語法在 RFC 編號 4515 中定義。

每個過濾器規則都由括號括起來。過濾器規則可以通過將組括在括號中並包含以下比較器來進行分組:

Operator Function
& and
| or
! not

LDAP 過濾器還具有特殊的匹配規則對象標識符(OID):

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 "專業服務部門"''(cn=專業服務部門)'

  • 名稱為“專業服務部門”且描述為“Live”的所有組

    '(cn -eq "專業服務部門") -and (description -eq "Live")''(&(cn=專業服務部門)(description=Live))'

  • 名稱為“專業服務部門”或“所有部門共享訪問權限”的所有組

    '(cn -eq "專業服務部門") -or (cn -eq "所有部門共享訪問權限")''(|(cn=專業服務部門)(cn=所有部門共享訪問權限))'

  • 所有沒有“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屬性可以反映這一點;只顯示專業服務部門

PS51> Get-ADUser -Identity Kristin.Diaz -Property memberOf

DistinguishedName : CN=Diaz Kristin,OU=Professional Services,OU=All User Accounts,DC=domain,DC=local
Enabled           : True
GivenName         : Kristin
MemberOf          : {CN=Professional Services Department,OU=All Groups,DC=domain,DC=local}
Name              : Diaz Kristin
ObjectClass       : user
ObjectGUID        : 04fe6336-c541-4e71-b7ed-6fee7db23482
SamAccountName    : Kristin.Diaz
SID               : S-1-5-21-447422785-3715515833-3878445295-1186
Surname           : Diaz
UserPrincipalName :

通過使用匹配規則OID或RecursiveMatch參數,您將發現他們間接是所有部門共享訪問權的成員。這是因為專業服務部門組是所有部門共享訪問權的成員。

PS51> Get-ADGroup -LDAPFilter '(member:1.2.840.113556.1.4.1941:=CN=Diaz Kristin,OU=Professional Services,OU=All User Accounts,DC=domain,DC=local)'
PS51> Get-ADGroup -Filter 'member -RecursiveMatch "CN=Diaz Kristin,OU=Professional Services,OU=All User Accounts,DC=domain,DC=local"'

兩者都返回以下結果:

DistinguishedName : CN=All Departments Share Access,OU=All Groups,DC=domain,DC=local
GroupCategory     : Security
GroupScope        : Universal
Name              : All Departments Share Access
ObjectClass       : group
ObjectGUID        : 8ac0e0b7-9225-40a4-b168-a0330960e182
SamAccountName    : All Departments Share Access
SID               : S-1-5-21-447422785-3715515833-3878445295-1254

DistinguishedName : CN=Professional Services Department,OU=All Groups,DC=domain,DC=local
GroupCategory     : Security
GroupScope        : Universal
Name              : Professional Services Department
ObjectClass       : group
ObjectGUID        : a8432583-7cac-4e8e-8d94-51e1c5bb1989
SamAccountName    : Professional Services Department
SID               : S-1-5-21-447422785-3715515833-3878445295-1255

搜索基礎和搜索範圍參數

在大型環境中,AD可能包含許多千個對象。提高性能並減少任何查詢返回的對象數量的一種方法是對搜索進行範圍限定。

SearchBase參數確定搜索在AD層級結構中的起始位置。在使用cmdlet時,這是一個分別名的字符串表示(默認情況下是域的“頂部”)。還有三個級別的SearchScope

  1. Base–已指定為SearchBase的對象。
  2. OneLevel–搜索立即包含在SearchBase中但不在任何子容器中的對象。
  3. SubTree–搜索包含在SearchBase中的對象和任何子容器中的對象,遞歸地沿著AD層次結構向下進行。
Example OU Structure

在上面的例子中,假如将SearchBase设置为OU=All User Accounts,DC=domain,DC=localSearchScopeBase将尝试查询OU对象本身,SearchScopeOneLevel将仅搜索All User Accounts OU,而SearchScopeSubTree将搜索All User AccountsProfessional Services OU。

摘要

现在您应该对如何使用Active Directory PowerShell cmdlets进行过滤有了很好的了解。您可以看到,制作完美的过滤语法要比使用Where-Object cmdlet更难。

但是花时间学习以正确的方式过滤AD对象,将获得出色的性能和效率的回报!

进一步阅读

Source:
https://adamtheautomator.com/ldap-filter/