繁体   English   中英

尝试从 Active Directory 检索和 OU,然后使用 C# 中的目录条目在 OU 上设置新属性

[英]Trying to Retrieve and OU from Active Directory, then set new properties on an OU using a Directory Entry in C#

此方法试图获取 Center ou 下的所有 OU 目录,一次一个,与我的 Center 对象列表中的名称匹配。

接下来,它尝试为每个属性设置几个属性(之前尚未创建)

它获取 OU,转到 .Add 分支并崩溃。 我有什么误解。

我收到“未指定错误\\n\\n”的异常,具有以下调用堆栈

在 System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.PutEx(Int32 lnControlCode, String bstrName, Object vProp) 在 System.DirectoryServices.PropertyValueCollection.OnInsertComplete(Int32 index, Object value) 在 System.Collections.CollectionBase.System.Collections.IList Add(Object value) at System.DirectoryServices.PropertyValueCollection.Add(Object value) at StudentPortalDevFixTool.Form1.buttonfixCenters_Click(Object sender, EventArgs e) in D:\\TFS\\StudentPortalDevFixTool\\StudentPortalDevFixTool\\Form1.cs:line 599

我以前这样做过,但就像 8 年前一样。 谢谢。

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() );
                }
            }
        }

我能猜到的唯一可能的原因是ctr.ctridnull或者它无法处理的一些奇怪的类型。 但是异常的错误消息将确认这一点,如果您可以分享的话。

但其他一些评论:

Mysearcher.SearchScope = SearchScope.Subtree;

Subtree是默认设置,因此如果您需要,则无需设置它。

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

UserPropertyCache不是 AD 属性。 我认为你正在尝试使用UsePropertyCache (注意,没有“R”)的财产DirectoryEntry ,在这种情况下,你可以这样做:

centerDe.UsePropertyCache = true;

但是true无论如何都是默认值,所以你不需要这样做。

然后这个:

centerDe.RefreshCache();

调用RefreshCache()告诉它去 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 )处引发异常,但在我提供帮助之前,您必须先分享错误消息的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM