Активный каталог: извлечения всех членов группы, используя каталог


Я написал функцию, которая будет извлекать все активные каталог членов группы через DirectoryServices. Я использую DirectoryServices потому что это примерно от 1 до 2 порядков быстрее, чем через AccountManagement. Мне подтвердили, что результаты функции являются правильными.

Я сейчас делаю код очистки и убедитесь, что этот код должен быть чистым и использование try/catch/finally блоки являются правильными. Идея в том, чтобы изолировать извлечения данных из AD с процесс добавления данных в список, который будет возвращен функцией. Если это не подходящий способ делать вещи, или если вы имеете любые рекомендации приветствуются.

private List<string> GetGroupMemberList(string strPropertyValue, string strActiveDirectoryHost, int intActiveDirectoryPageSize, string strObjectRid)
{
    // Variable declaration(s).
    DirectoryEntry directoryEntryGroup = null;
    SearchResultCollection searchResultCollection = null;
    DirectorySearcher directorySearcher = null;
    List<string> listGroupMemberDn = null;
    string strPath = null;
    const int intIncrement = 1500; // https://msdn.microsoft.com/en-us/library/windows/desktop/ms676302(v=vs.85).aspx
    bool bolCancel = false;

    // https://gallery.technet.microsoft.com/scriptcenter/fa4ccf4f-712e-459c-88b4-aacdb03a08d0
    // The member attribute of the groups is a collection of the Distinguished Names of all direct memberships, but does not reveal the "Primary Group" membership. 
    // So, get all of the members within the group first and then search for all users that have a primaryGroupID that is set to the current group that we are 
    // retrieving members from. For the latter step, we will need to use the DirectoryEntry to search for all users that have an RID that includes the PrimaryGroupId.

    // Step 1.) Get all direct group members.
    // Note: Per the weblink above in the variable declaration(s), group members are extracted in batches of 1500 members. 
    //       So, we will need to loop through all members in increments of 1500 until there are no more left.

    try
    {
        // Create a new list.
        listGroupMemberDn = new List<string>();

        // Set the string path of the current group so that it can be bound to DirectoryEntry.
        strPath = strActiveDirectoryHost + "/<GUID=" + strPropertyValue + ">";

        // Get the current group infromation, which will include the first batch of group members.
        directoryEntryGroup = new DirectoryEntry(strPath, null, null, AuthenticationTypes.Secure);
    }
    catch (Exception ex)
    {
        // Something went wrong. Throw an error.
        bolCancel = false;
        ComponentMetaData.FireError(0, ComponentMetaData.Name, ex.Message, string.Empty, 0, out bolCancel);
        throw;
    }

    try
    {
        while (true)
        {
            // Isolate all members that are listed in the current batch of group members.
            var varGroupMemberDns = directoryEntryGroup.Properties["member"];

            // Loop through the members that have been isolated and add each one into the list.
            foreach (string strMemberDn in varGroupMemberDns)
            {
                listGroupMemberDn.Add(strMemberDn.ToString().Replace("\"", ""));
            }

            // Check to see if the current batch is the last batch of group members by checking the count of members that are contained in the current batch.
            // If the number of members is less than the 1500 member batch limit, then this is the last batch of users. So, break the loop.
            if (varGroupMemberDns.Count < intIncrement)
            {
                break;
            }

            // The current batch is not the last batch of group members. So, get the next batch of group members.
            // Note: We must use string.Format() to avoid string interpolation: { $"member;range={listGroupMemberDn.Count}-*" }
            //      Using string interpolation prevents the debugger from starting.
            //      directoryEntryGroup.RefreshCache(new[] { $"member;range={listGroupMemberDn.Count}-*" });
            directoryEntryGroup.RefreshCache(new[] { string.Format("member;range={0}-*", listGroupMemberDn.Count) });

        }
    }
    catch (Exception ex)
    {
        // Something went wrong. Throw an error.
        bolCancel = false;
        ComponentMetaData.FireError(0, ComponentMetaData.Name, ex.Message, string.Empty, 0, out bolCancel);
        throw;
    }

    // Step 2.) Get all group members by searching DirectoryEntry for users that have their primaryGroupId set to the current group.
    try
    {
        // Set directorySearcher and initialize certain properties.
        directorySearcher = new DirectorySearcher(strActiveDirectoryHost)
        {
            // Set the Filter criteria that is used to constrain the search within AD.
            Filter = string.Format("(primaryGroupID={0})", strObjectRid),

            // Set the SearchScope for how the AD tree is searched (Default = Subtree).
            SearchScope = SearchScope.Subtree,

            // The PageSize value should be set equal to the PageSize that is set by the AD administrator (Server default = 1000, PageSize default = 0).
            PageSize = intActiveDirectoryPageSize,

            // Set the value indicating which node in the Active Directory Domain Services hierarchy to start the search.
            SearchRoot = new DirectoryEntry(strActiveDirectoryHost),

            PropertiesToLoad = { "distinguishedName" }
        };
    }
    catch (Exception ex)
    {
        // Something went wrong. Throw an error.
        bolCancel = false;
        ComponentMetaData.FireError(0, ComponentMetaData.Name, ex.Message, string.Empty, 0, out bolCancel);
        throw;
    }

    try
    {
        // Populate the searchResultCollection with all AD records that match the Filter criteria.
        searchResultCollection = directorySearcher.FindAll();

        // For each record object in the searchResultCollection, retrieve the distinguishedName and add it to the list.
        foreach (SearchResult searchResult in searchResultCollection)
        {
            listGroupMemberDn.Add(searchResult.Properties["distinguishedName"][0].ToString().Replace("\"", ""));
        }

        // Return the list.
        return listGroupMemberDn;
    }
    catch (Exception ex)
    {
        // Something went wrong. Throw an error.
        bolCancel = false;
        ComponentMetaData.FireError(0, ComponentMetaData.Name, ex.Message, string.Empty, 0, out bolCancel);
        throw;
    }
    finally
    {
        // Cleanup objects.
        listGroupMemberDn = null;
        strPath = null;
        strObjectRid = null;
        directoryEntryGroup.Close();
        if (directoryEntryGroup != null) directoryEntryGroup.Dispose();
        if (directorySearcher != null) directorySearcher.Dispose();
        if (searchResultCollection != null) searchResultCollection.Dispose();
    }
}


2245
2
задан 6 апреля 2018 в 05:04 Источник Поделиться
Комментарии