Active Directoryを学びながらPowerShellでLDAPフィルターをマスターする

Active DirectoryをPowerShellでクエリする際の最も一般的な問題は、フィルター構文を適切に構築する方法です。すべてのActiveDirectory PowerShellモジュールのcmdletにおけるFilterおよびLDAPフィルターパラメータは、多くの人々にとってブラックボックスです。

このブログ記事では、Active Directoryフィルタの使い方を深く理解するために深掘りしていきます。この記事の終わりまでには、もうWhere-Objectフィルタリングの正しい方法に挑戦する必要はないでしょう!

前提条件

これから示すコードが動作するためには、以下のいくつかの前提を想定しています:

Active Directoryのcmdletを使用してオブジェクトを検索する際に使用できるフィルタ言語は2つあります:PowerShellフィルタとLDAPフィルタ。

PowerShellフィルタ

PowerShellフィルタは、標準のPowerShell式構文を使用します。これは一般的にActive Directory検索フィルタ構文と呼ばれています。

これらのフィルタはFilterパラメータとともに使用されます。Filterパラメータの構文

オペレータ

Filterパラメーターのフィルターを作成する際には、少なくとも1つの演算子を使用する必要があります。ここで使用される演算子は、おそらく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コマンドレットはNameプロパティを返します。特定の名前に一致するすべてのユーザーを検索したい場合、次のようにします:

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

プロパティ名は、ADコマンドレットで返されるプロパティの名前または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、またはLightweight Directory Access Protocol(軽量ディレクトリアクセスプロトコル)は、ディレクトリデータにアクセスして変更するためのベンダーニュートラルなプロトコルです。”ディレクトリ”という言葉を聞くと、電話帳を思い浮かべるかもしれませんが、Active Directoryの文脈ではこれはさらに多くの意味を持ちます。さまざまなオブジェクトタイプがActive Directoryによって保存され、LDAPプロトコルがそのデータへのアクセス手段として機能しています。

Active Directoryはさまざまなデータ型を保存できるため、アプリケーションやユーザーはそのディレクトリを簡単にクエリする方法が必要です。LDAPフィルターがデータのフィルタリングにどのように役立つかを学ぶには、続けて読んでください!

LDAPフィルターActive DirectoryはLDAP、つまりLightweight Directory Access Protocol(軽量ディレクトリアクセスプロトコル)を実装しています。コマンドレットと一緒にLDAPFilterパラメータを使用すると、Active Directory Users and Computersで作成されたLDAPフィルターなどを使用できます。

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)

フィルタータイプには4つあります:

Operator Explanation
= Equal to
~= Approximately equal to
>= Greater than or equal to
<= Less than or equal to

アイテムタイプにも4つあります:

Type Explanation
= Simple
=* Present
=something* Substring
Extensible varies depending on type

LDAPフィルタールールはLDAP属性の名前とともに使用する必要があり、LDAPフィルターで使用される場合、特定の文字値は「エスケープ」する必要があります。これには以下が含まれます:

Character Escaped As
* \2a
( \28
) \29
\ \5c
NUL \00

プロパティの比較のための値は通常、引用符で囲む必要はありません。

LDAPフィルタの例

LDAPフィルタを構築することは挑戦的です。以下は、アクティブディレクトリグループフィルタを使用した例です。これらは、独自のフィルタを作成するための基盤として使用できます。

  • 名前(cn)が「Professional Services Department」のすべてのグループ

    'cn -eq "Professional Services Department"'または'(cn=Professional Services Department)'

  • 名前が「Professional Services Department」で説明が「Live」のすべてのグループ

    '(cn -eq "Professional Services Department") -and (description -eq "Live")'または'(&(cn=Professional Services Department)(description=Live))'

  • 名前が「Professional Services Department」または「All Departments Share Access」のいずれかのすべてのグループ

    '(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’の説明があるが、名前が ‘Professional Services Department’ ではないすべてのグループ

    '(description -eq "Live") -and (cn -ne "Professional Services Department")' or '(&(description=Live)(!(cn=Professional Services Department)))'

  • 説明が ‘\\fileserver1\fileshare’ のすべてのグループ

    'description -eq "\5c\5cfileserver1\5cfileshare"' or '(description=\5c\5cfileserver1\5cfileshare)'

RecursiveMatchまたはChain Matchingを使用して

マッチングルールOID、またはRecursiveMatchパラメーターを使用すると、よく問われる質問を解決する強力な方法となります: ‘ユーザーが直接および間接的にメンバーであるすべてのグループをどのように知ることができますか?’ 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

SearchBaseおよびSearchScopeパラメーター

大規模な環境では、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=localに設定されている場合、SearchScopeBaseの場合、OUオブジェクト自体をクエリし、SearchScopeOneLevelの場合はAll User Accounts OUのみを検索し、SearchScopeSubTreeの場合はAll User AccountsおよびProfessional Services OUの両方を検索します。

概要

これで、Active Directory PowerShell cmdletを使用してフィルタリングする方法について良い理解が得られたはずです。完璧なフィルタ構文を作成することは、Where-Object cmdletを使用するよりもはるかに難しいです。

しかし、ADオブジェクトをフィルタリングする ‘正しい’方法を学ぶ時間を費やし、優れたパフォーマンスと効率の利益を得てください!

さらなる読み込み

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