Active Directory, Free Tools

Pre Server 2016 Group Membership Expiration Tool

IntroductionLink to this section

Group membership expiration gives the ability to add a user to a group with the notion of a membership expiration.

This means you can add a user to a group and the user will automatically be removed from the group when the configured timespan has passed.

Unfortunately, some environments do not yet run at an Active Directory 2016 functional level.

For those, I developed the GroupMembershipExpiration tool.

Download: GroupMembershipExpiration.zip

SetupLink to this section

  1. Download the GroupMembershipExpiration tool and extract its contents to a folder on the computer you plan to install it on. I recommend extracting to C:\Program Files\GroupMembershipExpiration.
  2. Run Configurator.exe (Configurator Editor).

a) On the Encrypt tab, enter the password for the account that will be performing the cleanup task. Encrypt it with key aubXjiUZhyl6XnfBVQ920Y9rOWaEWSre and record the encrypted password.

Configurator Encrypt tab with the password encrypted

b) On the Settings tab, enter the distinguished name, fully qualified domain name, NetBIOS name, username and the encrypted password recorded in step 2a.

Specify a location where the tool can save a history file, the interval in seconds the task should be performed and the allowed number of minutes a member may be part of a group.

Configurator Settings tab with domain, account, history file, interval and allowed minutes

c) On the Groups tab, specify the groups the tool should manage the members for (+ or INS to add, - or DEL to delete, Enter or double-click to edit).

Configurator Groups tab listing the managed groups

d) Although you can run the tool by executing GroupMembershipExpiration.WindowsService.exe, I recommend you install it as a service by running GroupMembershipExpiration.WindowsService.exe INSTALL from an elevated command prompt. You may need to start the service manually the first time.

The CodeLink to this section

private void ProcessGroup(string groupName)
{
    List<Models.GroupMember> historicalyGroupMembers = new List<Models.GroupMember>();

    // Read previous history file if it exists
    if (File.Exists(_historyFile))
    {
        historicalyGroupMembers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.GroupMember>>(File.ReadAllText(_historyFile));
    }

    // Get current members of group
    List<ITtelligence.Models.GenericGroupMember> genericGroupMembers = new List<ITtelligence.Models.GenericGroupMember>();
    genericGroupMembers = ActiveDirectory.GenericGetGroupMembers(_domainInfo, groupName);

    List<Models.GroupMember> groupMembers = new List<Models.GroupMember>();

    // Compare history file with current members
    foreach (var genericGroupMember in genericGroupMembers)
    {
        Models.GroupMember historicalyGroupMember = historicalyGroupMembers.Where(g => g.DistinguishedName == genericGroupMember.DistinguishedName).FirstOrDefault();

        // If group member not in history, add it with current date and time as FirstDateObserved
        if (historicalyGroupMember == null)
        {
            // Add to history
            groupMembers.Add(new Models.GroupMember() { GroupName = genericGroupMember.GroupName, DistinguishedName = genericGroupMember.DistinguishedName, sAMAccountName = genericGroupMember.sAMAccountName, FirstDateObserved = DateTime.Now });
        }
        else
        {
            // If group member in history and it is past the maximum allowed timespan, remove it
            if ((DateTime.Now - historicalyGroupMember.FirstDateObserved).TotalMinutes > _allowedNumberOfMinutes)
            {
                // Remove from AD group and group history
                groupMembers.Remove(historicalyGroupMember);
                ActiveDirectory.GenericRemoveGroupMember(_domainInfo, groupName, genericGroupMember.DistinguishedName);
            }
            // If group member in history and it has not passed the maximum allowed timespan, ignore it
            else
            {
                // Ignored
                groupMembers.Add(historicalyGroupMember);
            }
        }
    }

    // Save current members to new history file
    File.WriteAllText(_historyFile, Newtonsoft.Json.JsonConvert.SerializeObject(groupMembers));
}

ConclusionLink to this section

There you have it. Every time the timer triggers in the Windows service, the process reads the history file and uses it to determine whether a member's membership has expired.

Note: membership is timed from when the tool first sees a member, not from when they were added to the group. Members already in a group when the tool starts are given the full allowed time from that point.

Originally published on Experts Exchange.

Posted on

Tagged C#, Tools

No comments yet

Comments are moderated and appear once approved.