Filter to get duplicate accounts

Which IIQ version are you inquiring about?

Version 8.4

Share all details related to your problem, including any error messages you may have received.

I need to write a rule delete duplicate accounts for one of our AD apps. I was thinking about getting the identities from the link, adding it to a list and then fetch the duplicates. Is there a way to write a filter to get duplicate accounts directly? what do you guys suggest would be the most efficient solution for my requirement? Thank you!

Hi Diwas,
How can you determine if account is duplicate or not? Do they have any common attribute? How do you plan to determine which one should be deleted?

If an identity has more than one link for the same app, I need to keep the one with the latest refresh date and remove the other.

So I think the easiest way would be to create query options to get all identities who’s got at least one AD application link and then iterate over this list to check if the identity has one or more links then you can just check which one should be removed build provisioning plan and execute it.

You can actually also use search method in context to execute SQL or HQL query to find only identities which you need

hi @kjakubiak , thanks for your reply. this is what I have. I cant quite figure out a way to get the lastRefresh date without any xml parsing. Is there any other way to get that?

	QueryOptions qo = new QueryOptions();
	qo.addFilter(Filter.eq("","Active Directory"));
	Iterator it =,qo);
	HashMap m = new HashMap();
  HashMap atts = new HashMap();
	List duplicates = new ArrayList();
  log.error("before loop");
	while (it.hasNext()){
		Link link =;
		//Date lastRefresh = link.getAttribute("modified");
    atts = link.getAttributes();
      for (String key : atts.keySet()) {
    Date d = atts.get("lastRefresh");
   /* if (lastRefresh != null){
			log.error("refresh date: " + lastRefresh.toString());
     log.error("null value");
		if (!m.containsKey(link.getDisplayName())) 
			m.put(link.getDisplayName(), link);
		else { // duplicate scenario
			Link curVal = m.get(link.getDisplayName());
			if (link.lastRefresh > curVal.lastRefresh) 
				m.put(link.getDisplayName(), link);

On the link object you have getLastRefresh method which returns you a date object

1 Like

I would say the best would be this cleanup need to be done of AD itself before you start managing those users accounts from sailpoint .

Hi @dk0200 ,

Maybe this piece of code will help:

import sailpoint.object.*;
import sailpoint.api.IncrementalObjectIterator;

String appName = "Active Directory";

QueryOptions queryOptions = new QueryOptions();
queryOptions.addFilter(Filter.eq("", appName));

IncrementalObjectIterator links = new IncrementalObjectIterator(context, Link.class, queryOptions);
int recordCounter = 0;

while (links.hasNext()) {

    Link link = (Link);
    //log.error("link=" + link.getNativeIdentity());
    Identity identity = link.getIdentity();
    List identitytLinks = identity.getLinks();
    List identityAppLinks = new ArrayList();
    for (Link il : identitytLinks) {
      if (appName.equals(il.getApplicationName())) {
    if (identityAppLinks.size() > 1) {
      for (Link il : identityAppLinks) {
        log.error("Do something with " + il.getNativeIdentity() + " for identity " + identity.getName());
    // Commit every few records.
    if (0 == (recordCounter % 10)) {
      //  context.commitTransaction();

It depends on where you run it in IdentityIQ, you might need to turn on the context.commitTransaction. I tested the above with the RuleRunner-plugin which does not require the commitTransaction.

– Remold

1 Like

lol, not sure how I did not see this method in javadocs.

it is on the Link class