Получить должность с помощью System.DirectoryServices.AccountManagement - PullRequest
18 голосов
/ 03 марта 2012

Я успешно использовал код AccountManagement для получения основной информации AD, но он возвращает только очень ограниченный набор информации о возвращенном объекте. Как я могу получить расширенную информацию от AD, используя функциональность AccountManagement. В частности, название должности или название, как мне кажется, в моем экземпляре AD.

Я знаю, как это сделать, используя более старые службы каталогов, но я хотел бы знать, как это сделать, используя новое пространство имен.

Ответы [ 3 ]

33 голосов
/ 03 марта 2012

Да, набор свойств по умолчанию для UserPrincipal довольно ограничен - но самое главное: есть замечательная история расширения!

Вам нужно определить класс по убыванию с UserPrincipal, и тогда вы сможете очень легко получить доступ к гораздо большему количеству свойств, если это необходимо.

Скелет будет выглядеть примерно так:

namespace ADExtended
{
    [DirectoryRdnPrefix("CN")]
    [DirectoryObjectClass("User")]
    public class UserPrincipalEx : UserPrincipal
    {
        // Inplement the constructor using the base class constructor. 
        public UserPrincipalEx(PrincipalContext context) : base(context)
        { }

        // Implement the constructor with initialization parameters.    
        public UserPrincipalEx(PrincipalContext context,
                             string samAccountName,
                             string password,
                             bool enabled) : base(context, samAccountName, password, enabled)
        {} 

        UserPrincipalExSearchFilter searchFilter;

        new public UserPrincipalExSearchFilter AdvancedSearchFilter
        {
            get
            {
                if (null == searchFilter)
                    searchFilter = new UserPrincipalExSearchFilter(this);

                return searchFilter;
            }
        }

        // Create the "Title" property.    
        [DirectoryProperty("title")]
        public string Title
        {
            get
            {
                if (ExtensionGet("title").Length != 1)
                    return string.Empty;

                return (string)ExtensionGet("title")[0];
            }
            set { ExtensionSet("title", value); }
        }

        // Implement the overloaded search method FindByIdentity.
        public static new UserPrincipalEx FindByIdentity(PrincipalContext context, string identityValue)
        {
            return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityValue);
        }

        // Implement the overloaded search method FindByIdentity. 
        public static new UserPrincipalEx FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
        {
            return (UserPrincipalEx)FindByIdentityWithType(context, typeof(UserPrincipalEx), identityType, identityValue);
        }
    }
}

И это действительно почти все, что есть! Методы ExtensionGet и ExtensionSet позволяют вам "добраться" вниз до базовой записи каталога и извлечь все атрибуты, которые могут вас заинтересовать ....

Теперь в своем коде используйте новый класс UserPrincipalEx вместо UserPrincipal:

using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
    // Search the directory for the new object. 
    UserPrincipalEx myUser = UserPrincipalEx.FindByIdentity(ctx, "someUserName");

    if(myUser != null)
    { 
        // get the title which is now available on your "myUser" object!
        string title = myUser.Title;
    }
}

Узнайте все о пространстве имен System.DirectoryServices.AccountManagement и его истории расширения здесь:

Обновление: извините - вот класс UserPrincipalExSearchFilter - пропустил этот класс в оригинальном сообщении. Это просто показывает возможность расширять поисковые фильтры, если это необходимо:

public class UserPrincipalExSearchFilter : AdvancedFilters
{
    public UserPrincipalExSearchFilter(Principal p) : base(p) { }

    public void LogonCount(int value, MatchType mt)
    {
        this.AdvancedFilterSet("LogonCount", value, typeof(int), mt);
    }
}
8 голосов
/ 12 июля 2012

Чтобы дополнить вышесказанное, я выбрал метод расширения для вызова ExtensionGet.Он использует отражение, чтобы получить защищенный метод, который иначе вы бы унаследовали.Возможно, вам придется использовать это, если вы возвращаете UserPrincipalObjects из Groups.Members, например

public static class AccountManagmentExtensions
{
    public static string ExtensionGet(this UserPrincipal up, string key)
    {
        string value = null;
        MethodInfo mi = up.GetType()
            .GetMethod("ExtensionGet", BindingFlags.NonPublic | BindingFlags.Instance);

        Func<UserPrincipal, string, object[]> extensionGet = (k,v) => 
            ((object[])mi.Invoke(k, new object[] { v }));

        if (extensionGet(up,key).Length > 0)
        {
            value = (string)extensionGet(up, key)[0]; 
        }

        return value;
    }
}
1 голос
/ 20 июня 2019

Есть более простые способы получить эту информацию. Вот как я добрался до должности в VB.NET:

Dim yourDomain As New PrincipalContext(ContextType.Domain, "yourcompany.local")
Dim user1 As UserPrincipal = UserPrincipal.FindByIdentity(yourDomain, principal.Identity.Name)
Dim Entry As DirectoryServices.DirectoryEntry = user1.GetUnderlyingObject()

Dim JobTitle As String = Entry.Properties.Item("Title").Value.ToString
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...