Попытка Извлечь и OU из Active Directory, затем установить новые свойства для OU, используя Запись в Каталоге в C# - PullRequest
0 голосов
/ 03 марта 2020

Этот метод пытается получить все каталоги OU ниже Center ou, по одному, которые соответствуют именам в моем списке объектов Center.

Далее для каждого из них он пытается установить пару свойств (которые не были созданы ранее)

Получает OU, переходит в ветку .Add и вылетает. Что я недопонимаю.

Я получаю исключение с «Неуказанная ошибка \ n \ n» со следующим стеком вызовов

в System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.PutEx (Int32 lnControlCode, String bstrName, Object vProp) в System.DirectoryServices.PropertyValueCollection.OnInsertComplete (индекс Int32, значение объекта) в System.Collections.CollectionBase.System.Collections.IList.Add (значение объекта) в System.DirectoryServices.PropertyValueCollection.AddT (значение объекта) Student. Form1.buttonfixCenters_Click (Отправитель объекта, EventArgs e) в D: \ TFS \ StudentPortalDevFixTool \ StudentPortalDevFixTool \ Form1.cs: строка 599

Я делал это раньше, но это было около 8 лет go. Спасибо.

private void buttonfixCenters_Click( object sender, EventArgs e )
        {
            string adConnStr = ConfigurationSettings.AppSettings["DeUrl"];
            string adServerUser = ConfigurationSettings.AppSettings["DeAcct"];
            string adServerPassword = ConfigurationSettings.AppSettings["DePwd"];
            string adServerContainer = ConfigurationSettings.AppSettings["AD_DomainOu"];
            // looks like this: "DC=AD,DC=MyDomain,DC=org"

            if( !string.IsNullOrEmpty( adConnStr ) && !string.IsNullOrEmpty(adServerUser) && !string.IsNullOrEmpty(adServerPassword) && !string.IsNullOrEmpty(adServerContainer) )
            {
                string adName = textBox_adname_unlock.Text;

                try
                {
                    DirectoryEntry startSearch = new DirectoryEntry( adConnStr, adServerUser, adServerPassword );
                    foreach ( Center ctr in CenterListFromCdss )
                    {
                        try
                        {
                            DirectorySearcher Mysearcher;

                            if ( startSearch == null )
                            {
                                throw new Exception( "No root in BuildDirectoryEntry(...)" );
                            }

                            Mysearcher = new DirectorySearcher( startSearch );

                            Mysearcher.SearchScope = SearchScope.Subtree;
                            Mysearcher.Filter = "(&(objectCategory=organizationalUnit)(ou=" + ctr.shname + "))";

                            SearchResult result = Mysearcher.FindOne();

                            DirectoryEntry centerDe;

                            if ( result == null)
                            {
                                centerDe = null;
                            }
                            else
                            {
                                centerDe  = result.GetDirectoryEntry();
                            }


                            if ( centerDe != null )
                            {
                                centerDe.Properties[ "UserPropertyCache" ].Value = true; 
                                centerDe.RefreshCache();

                                if ( result.Properties.Contains( "telexNumber" ) )
                                {
                                    centerDe.Properties[ "telexNumber" ].Value = ctr.ctrid;
                                }
                                else
                                {
                                    centerDe.Properties[ "telexNumber" ].Add( ctr.ctrid );// GOES BOOM HERE!
                                }

                                if ( result.Properties.Contains( "centerCode" ) )
                                {
                                    centerDe.Properties[ "centerCode" ].Value = ctr.ctrCode;
                                }
                                else
                                {
                                    centerDe.Properties[ "centerCode" ].Add( ctr.ctrCode );
                                }

                                //centerDe.Properties[ "telexNumber" ].Value = ctr.ctrid;
                                //centerDe.Properties[ "centerCode" ].Value = ctr.ctrCode;

                                centerDe.CommitChanges();
                                centerDe.Close();
                            }
                        }
                        catch ( Exception ex )
                        {
                            throw;
                        }
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show( "Exception: " + ex.ToString() );
                }
            }
        }

1 Ответ

1 голос
/ 04 марта 2020

Единственная возможная причина, по которой я могу догадаться, это то, что ctr.ctrid - это null или какой-то странный тип, с которым он не может справиться. Но сообщение об ошибке исключения подтвердит, что, если вы можете поделиться этим.

Но некоторые другие комментарии:

Mysearcher.SearchScope = SearchScope.Subtree;

Subtree по умолчанию, поэтому вам не нужно установить его, если вы этого хотите.

centerDe.Properties[ "UserPropertyCache" ].Value = true;

UserPropertyCache не является атрибутом AD. Я думаю, что вы пытаетесь использовать UsePropertyCache (обратите внимание, без "r") свойство DirectoryEntry, и в этом случае вы сделаете это:

centerDe.UsePropertyCache = true;

Но true по умолчанию в любом случае, так что вам не нужно это делать.

Тогда это:

centerDe.RefreshCache();

Вызов RefreshCache() сообщает go в AD и получить каждый атрибут для объекта. То же самое происходит, когда вы читаете атрибут, используя Properties в первый раз, и атрибут еще не находится в кэше. Вы можете сказать ему, чтобы он извлекал только те атрибуты, которые вы действительно хотите просмотреть, выполнив следующее:

centerDe.RefreshCache(new [] { "telexNumber", "centerCode" });

Это скажет, что он будет извлекать только эти два атрибута.

Однако вы не ' Т даже нужно сделать это. Все, что вы делаете, это добавляете новое значение, так что вам все равно, что там уже есть.

Я вижу, что вы переключаетесь между .Value = и .Add() в зависимости от того, есть ли значение уже там, но вам не нужно. Вы можете просто использовать .Add(), и это добавит значение, есть ли что-то уже там или нет.

И тогда есть это:

catch ( Exception ex )
{
    throw;
}

Есть ли причина для этого? Как таковой, нет никакого смысла иметь блок try / catch, если вы только собираетесь его сбросить.

Вы также можете немного упростить свой код, используя continue оператор.

Вот ваш код со всеми моими рекомендациями:

private void buttonfixCenters_Click( object sender, EventArgs e )
{
    string adConnStr = ConfigurationSettings.AppSettings["DeUrl"];
    string adServerUser = ConfigurationSettings.AppSettings["DeAcct"];
    string adServerPassword = ConfigurationSettings.AppSettings["DePwd"];
    string adServerContainer = ConfigurationSettings.AppSettings["AD_DomainOu"];
    // looks like this: "DC=AD,DC=MyDomain,DC=org"

    if( !string.IsNullOrEmpty( adConnStr ) && !string.IsNullOrEmpty(adServerUser) && !string.IsNullOrEmpty(adServerPassword) && !string.IsNullOrEmpty(adServerContainer) )
    {
        string adName = textBox_adname_unlock.Text;

        try
        {
            DirectoryEntry startSearch = new DirectoryEntry( adConnStr, adServerUser, adServerPassword );
            foreach ( Center ctr in CenterListFromCdss )
            {
                DirectorySearcher Mysearcher;

                if ( startSearch == null )
                {
                    throw new Exception( "No root in BuildDirectoryEntry(...)" );
                }

                Mysearcher = new DirectorySearcher( startSearch );

                Mysearcher.Filter = "(&(objectCategory=organizationalUnit)(ou=" + ctr.shname + "))";

                SearchResult result = Mysearcher.FindOne();

                if ( result == null) continue;

                DirectoryEntry centerDe  = result.GetDirectoryEntry();

                centerDe.Properties[ "telexNumber" ].Add( ctr.ctrid.ToString() );
                centerDe.Properties[ "centerCode" ].Add( ctr.ctrCode.ToString() );

                centerDe.CommitChanges();
                centerDe.Close();
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show( "Exception: " + ex.ToString() );
        }
    }
}

Это, вероятно, все еще вызовет исключение на .Add( ctr.ctrid ), но вам придется поделиться тем, что ошибка сообщение, прежде чем я могу помочь с этим.

...