[C#] DirectorySearcherで複数フィルターを適用する方法
C#のDirectorySearcher
で複数のフィルターを適用するには、LDAPクエリを使用してフィルターを組み合わせます。
フィルターはAND条件やOR条件で結合できます。
AND条件の場合は各条件を括弧で囲み、全体を(&(...)(...))
の形式で記述します。
OR条件の場合は(|(...)(...))
の形式を使用します。
例えば、ユーザー名が”John”で、かつ部門が”Sales”の条件をANDで結合する場合、フィルターは"(&(cn=John)(department=Sales))"
となります。
これをDirectorySearcher.Filter
プロパティに設定することで、複数の条件を適用できます。
フィルターの適用方法
単一フィルターの設定
DirectorySearcher
を使用して、単一のフィルターを設定する方法を説明します。
以下のサンプルコードでは、特定のユーザー名を持つエントリを検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(sAMAccountName=ユーザー名)"; // ユーザー名でフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、sAMAccountName
属性を使用して、指定したユーザー名のエントリを検索しています。
FindOneメソッド
を使用して、最初の一致する結果を取得します。
複数フィルターのAND条件
複数のフィルターをAND条件で組み合わせる場合、フィルターを次のように設定します。
以下のサンプルコードでは、ユーザー名と部門を条件に検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(&(sAMAccountName=ユーザー名)(department=部門名))"; // AND条件でフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、&
を使用して、ユーザー名と部門名の両方が一致するエントリを検索しています。
複数フィルターのOR条件
OR条件でフィルターを設定する場合、次のように記述します。
以下のサンプルコードでは、ユーザー名または部門名で検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(|(sAMAccountName=ユーザー名)(department=部門名))"; // OR条件でフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、|
を使用して、ユーザー名または部門名のいずれかが一致するエントリを検索しています。
複数フィルターの組み合わせ
AND条件とOR条件を組み合わせて、より複雑なフィルターを作成することも可能です。
以下のサンプルコードでは、ユーザー名が一致し、かつ部門名が一致するか、または役職が一致するエントリを検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(&(sAMAccountName=ユーザー名)(|(department=部門名)(title=役職名)))"; // 複合条件でフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、&
と|
を組み合わせて、複数の条件を同時に適用しています。
これにより、より柔軟な検索が可能になります。
実践例
ユーザー名とメールアドレスのフィルター
ユーザー名とメールアドレスを条件にフィルターを設定する方法を示します。
以下のサンプルコードでは、特定のユーザー名とメールアドレスを持つエントリを検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(&(sAMAccountName=ユーザー名)(mail=メールアドレス))"; // ユーザー名とメールアドレスでフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、sAMAccountName
とmail
属性を使用して、指定したユーザー名とメールアドレスの両方が一致するエントリを検索しています。
部門と役職のフィルター
部門と役職を条件にフィルターを設定する方法を示します。
以下のサンプルコードでは、特定の部門と役職を持つエントリを検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(&(department=部門名)(title=役職名))"; // 部門と役職でフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、department
とtitle
属性を使用して、指定した部門名と役職名の両方が一致するエントリを検索しています。
アカウントの有効期限とステータスのフィルター
アカウントの有効期限とステータスを条件にフィルターを設定する方法を示します。
以下のサンプルコードでは、特定の有効期限とアカウントのステータスを持つエントリを検索します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(&(accountExpires=有効期限)(userAccountControl=ステータス))"; // 有効期限とステータスでフィルター
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、accountExpires
とuserAccountControl
属性を使用して、指定した有効期限とアカウントのステータスが一致するエントリを検索しています。
これにより、特定の条件を満たすアカウントを効率的に見つけることができます。
応用例
フィルターの動的生成
フィルターを動的に生成することで、ユーザーの入力や条件に応じた柔軟な検索が可能になります。
以下のサンプルコードでは、ユーザーが指定した条件に基づいてフィルターを生成します。
using System.DirectoryServices;
using System.Text;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
string userName = "ユーザー名"; // ユーザー名の取得
string department = "部門名"; // 部門名の取得
StringBuilder filterBuilder = new StringBuilder();
filterBuilder.Append("(&"); // AND条件の開始
if (!string.IsNullOrEmpty(userName))
{
filterBuilder.Append($"(sAMAccountName={userName})"); // ユーザー名の条件追加
}
if (!string.IsNullOrEmpty(department))
{
filterBuilder.Append($"(department={department})"); // 部門名の条件追加
}
filterBuilder.Append(")"); // AND条件の終了
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = filterBuilder.ToString(); // 動的に生成したフィルターを設定
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、StringBuilder
を使用してフィルターを動的に生成しています。
ユーザーが入力した条件に応じて、フィルターが構築されます。
フィルターのパフォーマンス最適化
フィルターのパフォーマンスを最適化するためには、検索条件を適切に設定することが重要です。
以下のポイントに注意してフィルターを作成します。
- 必要な属性のみを取得:
DirectorySearcher
のPropertiesToLoad
プロパティを使用して、必要な属性だけを指定します。 - フィルターを簡潔に保つ: 複雑なフィルターはパフォーマンスに影響を与えるため、できるだけシンプルに保ちます。
- インデックスを利用: LDAPサーバーのインデックスを利用することで、検索速度を向上させることができます。
以下のサンプルコードでは、必要な属性のみを取得する方法を示します。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = "(sAMAccountName=ユーザー名)"; // シンプルなフィルター
searcher.PropertiesToLoad.Add("mail"); // 必要な属性を指定
searcher.PropertiesToLoad.Add("department"); // 必要な属性を指定
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
}
このコードでは、PropertiesToLoad
を使用して、必要な属性だけを取得するように設定しています。
これにより、パフォーマンスが向上します。
フィルターのデバッグ方法
フィルターのデバッグを行うことで、検索結果が期待通りでない場合の原因を特定できます。
以下の方法を用いてフィルターをデバッグします。
- フィルターの出力: フィルターを実行する前に、生成されたフィルター文字列をコンソールに出力します。
これにより、フィルターが正しく構築されているか確認できます。
- 例外処理:
try-catch
ブロックを使用して、検索中に発生する可能性のある例外をキャッチし、エラーメッセージを表示します。 - 検索結果の確認: 検索結果が期待通りでない場合、フィルターを簡素化して再度実行し、どの条件が問題かを特定します。
以下のサンプルコードでは、フィルターの出力と例外処理を行っています。
using System.DirectoryServices;
partial class MyForm
{
public MyForm()
{
InitializeComponent(); // フォームの初期化
string filter = "(sAMAccountName=ユーザー名)"; // フィルターの設定
Console.WriteLine($"使用するフィルター: {filter}"); // フィルターの出力
try
{
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.Filter = filter; // フィルターを設定
SearchResult result = searcher.FindOne(); // 検索実行
// 検索結果の処理
if (result != null)
{
// 結果が見つかった場合の処理
}
}
}
catch (Exception ex)
{
Console.WriteLine($"エラーが発生しました: {ex.Message}"); // エラーメッセージの出力
}
}
}
このコードでは、フィルターを出力し、例外が発生した場合にエラーメッセージを表示しています。
これにより、デバッグが容易になります。
まとめ
この記事では、C#のDirectorySearcher
を使用して複数のフィルターを適用する方法について詳しく解説しました。
特に、単一フィルターの設定から複数フィルターのAND条件やOR条件、さらには動的生成やパフォーマンス最適化のテクニックまで幅広く取り上げました。
これらの知識を活用して、実際のアプリケーションでの検索機能を向上させることができるでしょう。
ぜひ、実際のプロジェクトにおいてこれらのテクニックを試してみてください。