Уведомление об изменении в Active Directory (выборочные атрибуты) C#

Подскажите пожалуйста, пытаюсь реализовать получение уведомлений из AD методом который описан Райана Данна. Немного его доработав для своих нужд. Вопросов будет 2.

  1. Как сделать чтоб уведомления приходили об изменениях не от всех атрибутах? Так как при авторизации клиента на рабочей машине так же приводит к изменениям атрибутов. Хотелось бы отслеживать только определенный массив атрибутов.
  2. Так же вопрос по поводу notifier.Register("OU=Home, DC=home, DC=local", SearchScope.Subtree);, а именно SearchScope.Subtree, Subtree - приводит к получения всех изменений, Base - изменения только в базовом OU, OneLevel - в базовом и дочернем OU. Но работает только Subtree, а это очень много уведомлений. Примерная реализация AD

Код программы:

static void Main(string[] args)
    {
        try
        {
            LdapDirectoryIdentifier idi = new LdapDirectoryIdentifier("192.168.0.11");

            using (LdapConnection connect = new LdapConnection(idi))
            {
                connect.SessionOptions.ProtocolVersion = 3;
                NetworkCredential nc = new NetworkCredential(@"Admin", "Q150+150");
                connect.Bind(nc);
                Console.WriteLine(nc);

                using (ChangeNotifier notifier = new ChangeNotifier(connect))
                {
                    //register some objects for notifications (limit 5)
                    notifier.Register("DC=home, DC=local", SearchScope.Subtree);
                    //notifier.Register("OU=Home, DC=home, DC=local", SearchScope.OneLevel);

                    notifier.ObjectChanged += new EventHandler<ObjectChangedEventArgs>(notifier_ObjectChanged);

                    Console.WriteLine("Waiting for changes...");
                    Console.WriteLine();
                    Console.ReadLine();
                }
            }
        }
        catch (LdapException e)
        {
            Console.WriteLine("\r\nUnable to login:\r\n\t" + e.Message);
            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine("\r\nUnexpected exception occured:\r\n\t" + e.GetType() + ":" + e.Message);
            Console.ReadLine();
        }
    }

    static void notifier_ObjectChanged(object sender, ObjectChangedEventArgs e)
    {
        Console.WriteLine(e.Result.DistinguishedName);
        foreach (string attrib in e.Result.Attributes.AttributeNames)
        {
            foreach (var item in e.Result.Attributes[attrib].GetValues(typeof(string)))
            {
                Console.WriteLine("\t{0}: {1}", attrib, item);
            }
        }
        Console.WriteLine();
        Console.WriteLine("====================");
        Console.WriteLine();
    }

    public class ChangeNotifier : IDisposable
    {
        LdapConnection _connection;
        HashSet<IAsyncResult> _results = new HashSet<IAsyncResult>();

        public ChangeNotifier(LdapConnection connection)
        {
            _connection = connection;
            _connection.AutoBind = true;
        }

        public void Register(string dn, SearchScope scope)
        {

            string[] attribs = new string[]{
            "distinguishedName",
            "sAMAccountName",
            "name",
            "mail",
            "mobile"};

            SearchRequest request = new SearchRequest(
        dn, //root the search here
        "(objectClass=*)", //very inclusive
        scope, //any scope works
        attribs //we are interested in all attributes
        );

            //register our search
            request.Controls.Add(new DirectoryNotificationControl());

            //we will send this async and register our callback
            //note how we would like to have partial results
            IAsyncResult result = _connection.BeginSendRequest(
                request,
                TimeSpan.FromDays(1), //set timeout to a day...
                PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
                Notify,
                request
                );

            //store the hash for disposal later
            _results.Add(result);
        }

        private void Notify(IAsyncResult result)
        {
            //since our search is long running, we don't want to use EndSendRequest
            PartialResultsCollection prc = _connection.GetPartialResults(result);

            foreach (SearchResultEntry entry in prc)
            {
                OnObjectChanged(new ObjectChangedEventArgs(entry));
            }
        }

        private void OnObjectChanged(ObjectChangedEventArgs args)
        {
            if (ObjectChanged != null)
            {
                ObjectChanged(this, args);
            }
        }

        public event EventHandler<ObjectChangedEventArgs> ObjectChanged;

        #region IDisposable Members

        public void Dispose()
        {
            foreach (var result in _results)
            {
                //end each async search
                _connection.Abort(result);
            }
        }

        #endregion
    }

    public class ObjectChangedEventArgs : EventArgs
    {
        public ObjectChangedEventArgs(SearchResultEntry entry)
        {
            Result = entry;
        }

        public SearchResultEntry Result { get; set; }
    }
}

Ответы (0 шт):