-1

Can anyone help me to find out how to add custom attributes/classes to Active Directory schema using C#? I can add manually by using MMC /a. But now I want to do it using C# code. Can anyone provide me the sample for this?

Thanks in advance!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Aswad
  • 29
  • 2
  • 5
  • 1
    [does this help you to do anything? maybe an approach](https://stackoverflow.com/questions/8927309/retrieving-custom-active-directory-properties-of-users) – Foo Bar Jun 13 '17 at 10:11

2 Answers2

3

This is a very big HOW TO:

https://www.codeproject.com/Articles/18102/Howto-Almost-Everything-In-Active-Directory-via-C#6

Target Specific Domain Controllers or Credentials

Everywhere in the code that you see: LDAP:// you can replace with LDAP://MyDomainControllerNameOrIpAddress as well as everywhere you see a DirectoryEntry class being constructed you can send in specific credentials as well. This is especially helpful if you need to work on an Active Directory for which your machine is not a member of it's forest or domain or you want to target a DC to make the changes to.

//Rename an object and specify the domain controller and credentials directly

public static void Rename(string server,
    string userName, string password, string objectDn, string newName)
{
    DirectoryEntry child = new DirectoryEntry("LDAP://" + server + "/" + 
        objectDn, userName, password);
    child.Rename("CN=" + newName);
}

Managing local accounts with DirectoryEntry

It is important to note that you can execute some of these methods against a local machine as opposed to an Active Directory if needed by simply replacing the LDAP:// string with WinNT:// as demonstrated below

//create new local account

DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + 
    Environment.MachineName);
DirectoryEntry newUser = localMachine.Children.Add("localuser", "user");
newUser.Invoke("SetPassword", new object[] { "3l!teP@$$w0RDz" });
newUser.CommitChanges();
Console.WriteLine(newUser.Guid.ToString());
localMachine.Close();
newUser.Close();

Managing local groups with DirectoryEntry

A few configuration changes need to be made to the code but it's pretty straightforward. Below you can see an example of using DirectoryEntry to enumerate the members of the local "administrator" group.

DirectoryEntry localMachine = new DirectoryEntry
    ("WinNT://" + Environment.MachineName + ",Computer");
DirectoryEntry admGroup = localMachine.Children.Find
    ("administrators", "group");
object members = admGroup.Invoke("members", null);

foreach (object groupMember in (IEnumerable)members)
{
    DirectoryEntry member = new DirectoryEntry(groupMember);
    Console.WriteLine(member.Name);
}

Managing IIS with DirectoryEntry

In addition to managing local & directory services accounts, the versatile DirectoryEntry object can manage other network providers as well, such as IIS. Below is an example of how you can use DirectoryEntry to provision a new virtual directory in IIS.

//Create New Virtual Directory in IIS with DirectoryEntry()

string wwwroot = "c:\\Inetpub\\wwwroot";
string virtualDirectoryName = "myNewApp";
string sitepath = "IIS://localhost/W3SVC/1/ROOT";

DirectoryEntry vRoot = new DirectoryEntry(sitepath);
DirectoryWntry vDir = vRoot.Children.Add(virtualDirectoryName, 
                            "IIsWebVirtualDir");
vDir.CommitChanges();

vDir.Properties["Path"].Value = wwwroot + "\\" + virtualDirectoryName;
vDir.Properties["DefaultDoc"].Value = "Default.aspx";
vDir.Properties["DirBrowseFlags"].Value = 2147483648;
vDir.Commitchanges();
vRoot.CommitChanges();

NOW Active Directory Objects:

Enumerate Multi-String Attribute Values of an Object

This method includes a recursive flag in case you want to recursively dig up properties of properties such as enumerating all the member values of a group and then getting each member group's groups all the way up the tree.

public ArrayList AttributeValuesMultiString(string attributeName,
     string objectDn, ArrayList valuesCollection, bool recursive)
{
    DirectoryEntry ent = new DirectoryEntry(objectDn);
    PropertyValueCollection ValueCollection = ent.Properties[attributeName];
    IEnumerator en = ValueCollection.GetEnumerator();

    while (en.MoveNext())
    {
        if (en.Current != null)
        {
            if (!valuesCollection.Contains(en.Current.ToString()))
            {
                valuesCollection.Add(en.Current.ToString());
                if (recursive)
                {
                    AttributeValuesMultiString(attributeName, "LDAP://" +
                    en.Current.ToString(), valuesCollection, true);
                }
            }
        }
    }
    ent.Close();
    ent.Dispose();
    return valuesCollection;
}

Enumerate Single String Attribute Values of an Object

public string AttributeValuesSingleString
    (string attributeName, string objectDn)
{
    string strValue;
    DirectoryEntry ent = new DirectoryEntry(objectDn);
    strValue = ent.Properties[attributeName].Value.ToString();
    ent.Close();
    ent.Dispose();
    return strValue;
}

Enumerate an Object's Properties: The Ones with Values

public static ArrayList GetUsedAttributes(string objectDn)
{
    DirectoryEntry objRootDSE = new DirectoryEntry("LDAP://" + objectDn);
    ArrayList props = new ArrayList();

    foreach (string strAttrName in objRootDSE.Properties.PropertyNames)
    {
        props.Add(strAttrName);
    }
    return props;
}
Foo Bar
  • 165
  • 2
  • 14
  • I have already tried the above approach , but how to add a custom attribute is not mentioned here . I want to add new attribute to the existing list of attribute. – Aswad Jun 14 '17 at 05:10
  • I have written following code for creating new user, Now i want to add some custom properties string connectionPrefix = "LDAP://" + ldapPath; DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix); DirectoryEntry newUser = dirEntry.Children.Add("CN=" + "user", userName); newUser.Properties["samAccountName"].Value = userName; newUser.CommitChanges(); oGUID = newUser.Guid.ToString(); newUser.Invoke("SetPassword", new object[] { userPassword }); newUser.CommitChanges(); – Aswad Jun 14 '17 at 09:45
  • That code was already in the link I posted, under **create user account**, I´m asking you for your code creating those custom attributes. – Foo Bar Jun 14 '17 at 10:19
  • And at least copy it correctly: **DirectoryEntry newUser = dirEntry.Children.Add("CN=" + userName, "user");** NOT **Children.Add("CN=" + "user", userName);** – Foo Bar Jun 14 '17 at 10:26
3

Interesting that neither the proposed answer nor the example there by the question author really answer the original question:

How to add custom attributes/classes to Active Directory schema in C#?

By this question, I understand, adding an attribute which is NOT YET present in the AD Schema. I doubt it is supported via C# code when you see that adding an attributes actually means updating the AD schema: https://social.technet.microsoft.com/wiki/contents/articles/20319.how-to-create-a-custom-attribute-in-active-directory.aspx

EricBDev
  • 1,279
  • 13
  • 21