[英]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.ctrid
是null
或者它无法处理的一些奇怪的类型。 但是异常的错误消息将确认这一点,如果您可以分享的话。
但其他一些评论:
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.