I'm hoping to make a breakthrough regarding updating Active Directory custom attributes using .NET (C#) using the normal DirectoryEntry.
I have an ages-old AD integration that regularly updates numerous out-of-the-box attributes with no problem. Recently, the AD team added two new custom attributes (a nullable boolean type, and a datetime type) to the AD user record which need to be updated with appropriate values. These attributes have no initial value and are "not set" when looking at them with MS AD Admin Center. I can manually modify the new attributes using that tool without issue.
In the solution, we do a DirectorySearcher call to get the desired SearchResult, loading the desired properties. Everything is there, including the custom attributes with their current values.
Next, we grab the DirectoryEntry with SearchResult.GetDirectoryEntry(). From here, I can update all the normal attributes, but while I can see the new custom attributes in the DirectoryEntry.Properties.PropertyNames collection, I cannot access them in any way to read their values or perform the required updates.
If I add a watch to the DirectoryEntry.Properties.Values collection, it errors out with:
Unknown error (0x8000500c)
It's like they don't exist.
When I try to get the value, I get the error:
'entryToChange.Properties["TheCustomAttributeName"]' threw an exception of type 'System.Runtime.InteropServices.COMException'
However, as I mentioned, if I access something like
entryToChange.Properties["SamAccountName"][0]
I see the value as expected and can update it without issue.
Next, I went into Powershell and was able to use set-AdUser to update one of the new custom attributes without any issue at all. My brain exploded... eyes rolled back... etc.
What am I missing with regard to updating new custom attributes in AD using .NET and the typical DirectoryEntry class? Thanks in advance for any insight.
Here's a simplified snippet of the code:
using (DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry, adQueryFilter, adAttributesToLoad)))
{
SearchResult searchResult = directorySearcher.FindOne();
if (searchResult != null)
{
using (DirectoryEntry entryToChange = searchResult.GetDirectoryEntry())
{
// BOOM! The error throws right here, when I try to look at the custom attribute
if (entryToChange.Properties["TheCustomAttribute"] != null &&
entryToChange.Properties["TheCustomAttribute"].Count > 0)
{
// We never get down here to do the update...
entryToChange.Properties["TheCustomAttribute"][0] = "The new value";
}
}
}
}
My guess is that it doesn't like the use of
.Any(). I can't even get it to compile with.Any()(even if I haveusing System.Linq).You can use
.Contains()to check if the attribute has a value. If it doesn't have a value, then it will returnfalse.You can also use
.Valueto set the value if it's a single-value attribute.If there is still an exception, look at the properties of the
COMExceptionto see if there's an error code.