Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.

Include Page

Table of Contents


 This topic is discussed in the "Grouper API - Part 2" training video.


Code Block
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both
# Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop

me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true);
session = GrouperSession.start(me);
// OR: session = GrouperSession.startRootSession(True)

group = GroupFinder.findByName(session, "tmp:my:group", true);

effectiveMembers = group.getEffectiveMembers();
immediateMembers = group.getImmediateMembers();

System.out.println(String.join("\t", "id", "name", "Effective", "Immediate"));

for (Member m: group.getMembers()) {
    System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getName() + "\t");
    System.out.print(effectiveMembers.contains(m).toString() + "\t");
    System.out.println(immediateMembers.contains(m).toString() + "\t");

# (2) Get the immediate and effective members for a specific source ("pid" in this example), intersect them to find the redundant ones
# This has a dryRun flag, so you can test first

sources = new HashSet<Source>()

effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null)
immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null)

# use retainAll() to find the intersection; i.e., users both as effective and immediate member

System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships");

dryRun = true

for (Member m: immediateUsers) {
    if (dryRun) {
        System.out.println("Ok to delete " + m.getSubject().getId());
    } else {
        System.out.println("Deleting " + m.getSubject().getId());
        group.deleteMember(m, false);

# (3) Get the groups this subject is a member of. Note that a group is a kind of subject, and has a toSubject() method to convert it.

import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer

GrouperSession grouperSession = GrouperSession.startRootSession();

Group group = GroupFinder.findByName(grouperSession, "test:testGroup", true);
Subject subject = g.toSubject();

Set<MembershipSubjectContainer> msc = new MembershipFinder().addSubject(subject).findMembershipResult().getMembershipSubjectContainers();

for (MembershipSubjectContainer membershipSubjectContainer : msc) { println(membershipSubjectContainer.getGroupOwner().getName());}

//Note there are a few other options for the search. Add these to the MembershipFinder method chain before calling findMembershipResult():
//  - search immediate, effective, etc. (needs to import MembershipType)
import edu.internet2.middleware.grouper.membership.MembershipType
membershipFinder.assignMembershipType(MembershipType.IMMEDIATE) // options are IMMEDIATE|NONIMMEDIATE|EFFECTIVE|COMPOSITE
//  - retrieve specific groups based on pattern
//  - Enabled status -- true means enabled only, false, means disabled only, and null means all
// For other methods, refer to the Javadoc at


Note: you cannot encrypt passwords with GSH since the passwords end up in the GSH history.  To encrypt passwords, issue the command: