27

What I mean is that right now I am using System.DirectoryServices.AccountManagement and if I use UserPrincipal class I only see the Name, Middle Name, etc

so in my codes it like

UserPrincipal myUser = new UserPrincipal(pc);
myUser.Name = "aaaaaa";
myUser.SamAccountName = "aaaaaaa";
.
.
.
.
myUser.Save();

How would I see the attribute like mobile or info?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Mondyak
  • 395
  • 1
  • 5
  • 10

3 Answers3

36

In this case, you need to go one level deeper - back into the bowels of DirectoryEntry - by grabbing it from the user principal:

using (DirectoryEntry de = myUser.GetUnderlyingObject() as DirectoryEntry)
{
    if (de != null)
    {
        // Go for those attributes and do what you need to do...
        var mobile = de.Properties["mobile"].Value as string;
        var info = de.Properties["info"].Value as string;
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • This worked fine as a quick fix, but I am trying to avoid using Directory Entry. Thanks for the help – Mondyak Oct 14 '10 at 19:57
  • 1
    Amazed this got so many upvotes, as it doesn't show how to implement the `de` object to get the properties. – vapcguy Oct 20 '16 at 18:17
  • 2
    Here is an example to get the Common-Name `de.Properties["cn"].Value.ToString();` – Philippe Jan 21 '17 at 03:25
  • 1
    I like this answer much more than the accepted answer. This is a lot less involved and gets you the information you need beautifully. – Brad May 20 '19 at 14:57
  • If I want to pull some fields under "Organization" tab, how do I find the property names? Thanks. – Si8 Dec 10 '20 at 18:08
18

The proper way of doing it is by using PrincipalExtensions where you extend the Principal you are after and use the methods ExtensionSet and ExtensionGet as explained here.

Raymund
  • 7,684
  • 5
  • 45
  • 78
3

up.Mobile would be perfect, but unfortunately, there's no such method in the UserPrincipal class, so you have to switch to DirectoryEntry by calling .GetUnderlyingObject().

static void GetUserMobile(PrincipalContext ctx, string userGuid)
{
    try
    {
        UserPrincipal up = UserPrincipal.FindByIdentity(ctx, IdentityType.Guid, userGuid);
        DirectoryEntry up_de = (DirectoryEntry)up.GetUnderlyingObject();
        DirectorySearcher deSearch = new DirectorySearcher(up_de);
        deSearch.PropertiesToLoad.Add("mobile");
        SearchResultCollection results = deSearch.FindAll();
        if (results != null && results.Count > 0)
        {
            ResultPropertyCollection rpc = results[0].Properties;
            foreach (string rp in rpc.PropertyNames)
            {
                if (rp == "mobile")
                    Console.WriteLine(rpc["mobile"][0].ToString());
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}
vapcguy
  • 7,097
  • 1
  • 56
  • 52
Mitch Stewart
  • 1,253
  • 10
  • 12
  • Unfortunately, if you load a property on `deSearch` that has an empty value in AD, it doesn't come back in the results set and the original code doesn't check for it not being there, so it throws the exception `Object reference not set to an instance of an object` on that `Console.WriteLine` line. I submitted an edit that should do the job. – vapcguy Oct 20 '16 at 14:45
  • Note, too, this should all be wrapped in a `try...catch`. If a user is sent to this function that is no longer in AD, it will also get the exception `Object reference not set to an instance of an object` on the `DirectoryEntry` instantiation - corrected this in my edit, too. – vapcguy Oct 20 '16 at 14:49
  • Also, I don't even see "mobile" in the list of possible PropertyNames in the `rootSearch` of `results`. There is `telephonenumber` that might actually be what the OP is looking for. It is the same as "Phone" in the GUI form for a user in AD, but also, that is the same as `up.VoiceTelephoneNumber`, and so would not even require the `.GetUnderlyingObject()` call. But other properties likely would, so this to me, is the best solution to iterate through them all. – vapcguy Oct 20 '16 at 18:11
  • 1
    Why use `DirectorySearcher`? Using ***de.Properties*** ? `var mobile = de.Properties["mobile"].Value as string;` – Kiquenet Jun 04 '19 at 10:02