Как найти UserPrincipal, где свойство не установлено с использованием PrincipalSearcher?
Я пытаюсь найти пользователей в экземпляре AD LDS (ADAM), где свойство не задано, например, когда для свойства "company" не установлено значение в хранилище ADAM (или в этом отношении AD).
Когда я использую PrincipalSearcher
и обычай UserPrincipal
с обычаем AdvancedSearchFilters
объект, я получаю ошибку:
An unhandled exception of type 'System.ArgumentException' occurred in System.DirectoryServices.dll Additional information: The (&(objectClass=user)(!(company=))) search filter is invalid.
Вот мой пример кода:
using System;
using System.DirectoryServices.AccountManagement;
using System.Security.Permissions;
using System.Linq;
namespace AdamDump
{
class Program
{
static void Main(string[] args)
{
PrincipalContext context = new PrincipalContext(ContextType.ApplicationDirectory, "MyAdamInstance:50000", "OU=Adam Users,dc=apps01,dc=mydomain", "queryaccount", "password");
// initialize a Query By Example
using (MyUserPrincipal myUserPrincipal = new MyUserPrincipal(context))
{
myUserPrincipal.MyAdvancedFilters.WhereCompanyNotSet();
PrincipalSearchResult<Principal> principals = null;
// do the search...
using (PrincipalSearcher principalSearcher = new PrincipalSearcher(myUserPrincipal))
{
principals = principalSearcher.FindAll();
}
var myUsers = principals.Select(principal => principal as MyUserPrincipal).ToList();
foreach (var user in myUsers)
Console.WriteLine("Name: {0}, Account{1}", user.DisplayName, user.SamAccountName);
Console.WriteLine("Total found: {0}", myUsers.Count);
}
}
}
[DirectoryObjectClass("user")]
[DirectoryRdnPrefix("CN")]
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
public class MyUserPrincipal : UserPrincipal
{
private MyAdvancedFilters _myAdvancedFilters;
/// <summary>
/// Initializes a new instance of the <see cref="MyUserPrincipal"/> class.
/// </summary>
/// <param name="context">A <see cref="PrincipalContext"/> to associate this instance with.</param>
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
public MyUserPrincipal(PrincipalContext context)
: base(context) { }
public MyAdvancedFilters MyAdvancedFilters
{
get
{
return this.AdvancedSearchFilter as MyAdvancedFilters;
}
}
public override AdvancedFilters AdvancedSearchFilter
{
get
{
if (_myAdvancedFilters == null)
{
_myAdvancedFilters = new MyAdvancedFilters(this);
}
return _myAdvancedFilters;
}
}
}
public class MyAdvancedFilters : AdvancedFilters
{
/// <summary>
/// Initializes a new instance of the <see cref="MyAdvancedFilters"/> class.
/// </summary>
/// <param name="principal">The source <see cref="Principal"/></param>
public MyAdvancedFilters(Principal principal) : base(principal) { }
public void WhereCompanyNotSet()
{
this.AdvancedFilterSet("company", "", typeof(string), MatchType.NotEquals);
}
}
}
2 ответа
Модификация моего класса AdvanceFilters следующим образом дает нужные мне результаты.
public class MyAdvancedFilters : AdvancedFilters
{
/// <summary>
/// Initializes a new instance of the <see cref="MyAdvancedFilters"/> class.
/// </summary>
/// <param name="principal">The source <see cref="Principal"/></param>
public MyAdvancedFilters(Principal principal) : base(principal) { }
public void WhereCompanyNotSet()
{
this.AdvancedFilterSet("company", "*", typeof(string), MatchType.NotEquals);
}
}
Это "*" для части значения в AdvancedFilterSet.
Спасибо Шону за то, что он направился по правильному пути, чтобы найти ответ, подходящий для объектов AccountManagement.
Попробуйте использовать это как ваш запрос:
(&(objectClass=user)(!(company=*)))
Документы: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa746475(v=vs.85).aspx примерно на половине пути вниз на странице с надписью "Получить все записи без атрибута электронной почты:"