【问题标题】:How to find a UserPrincipal where a property is not set using a PrincipalSearcher?如何使用 PrincipalSearcher 查找未设置属性的 UserPrincipal?
【发布时间】:2012-11-25 23:46:05
【问题描述】:

我正在尝试在未设置属性的 AD LDS (ADAM) 实例中搜索用户,例如未将“公司”属性设置为 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);
        }
    }
}

【问题讨论】:

    标签: c# .net active-directory adam account-management


    【解决方案1】:

    尝试将其用作您的查询:

    (&(objectClass=user)(!(company=*)))
    

    文档:http://msdn.microsoft.com/en-gb/library/windows/desktop/aa746475(v=vs.85).aspx 大约在页面的一半处显示“获取所有没有电子邮件属性的条目:”

    【讨论】:

    • 我认为您适合使用 DirectorySearcher 的方法,但由于我需要通过 AccountManagement 对象执行此操作,因此不直接适用。
    • 用 AccountManagement 对象试试这个 PrincipalSearcher ps = new PrincipalSearcher(user); ((DirectorySearcher)ps.GetUnderlyingSearcher()).Filter = "(&(objectClass=user)(!(company=*)))";/
    【解决方案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中值部分的“*”

    感谢 Sean 引导正确的线索来提出适合 AccountManagement 对象的答案。

    【讨论】:

      猜你喜欢
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 2023-03-15
      • 1970-01-01
      • 2012-09-07
      • 2021-11-10
      • 1970-01-01
      相关资源
      最近更新 更多