Share all details related to your problem, including any error messages you may have received.
Hello,
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?
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.
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("application.name","Active Directory"));
Iterator it = context.search(Link.class,qo);
HashMap m = new HashMap();
HashMap atts = new HashMap();
List duplicates = new ArrayList();
log.error("before loop");
while (it.hasNext()){
log.error("here");
Link link = it.next();
//log.error("link.getDisplayName());
//log.error(link.toXml());
//Date lastRefresh = link.getAttribute("modified");
atts = link.getAttributes();
for (String key : atts.keySet()) {
System.out.println(key);
}
Date d = atts.get("lastRefresh");
log.error(d);
/* if (lastRefresh != null){
log.error("refresh date: " + lastRefresh.toString());
}else{
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);
duplicates.add(curVal);
}
}
}
import sailpoint.object.*;
import sailpoint.api.IncrementalObjectIterator;
String appName = "Active Directory";
QueryOptions queryOptions = new QueryOptions();
queryOptions.addFilter(Filter.eq("application.name", appName));
IncrementalObjectIterator links = new IncrementalObjectIterator(context, Link.class, queryOptions);
int recordCounter = 0;
while (links.hasNext()) {
Link link = (Link) links.next();
recordCounter++;
//log.error("link=" + link.getNativeIdentity());
Identity identity = link.getIdentity();
//log.error(identity.getName());
List identitytLinks = identity.getLinks();
List identityAppLinks = new ArrayList();
for (Link il : identitytLinks) {
if (appName.equals(il.getApplicationName())) {
identityAppLinks.add(il);
}
}
if (identityAppLinks.size() > 1) {
for (Link il : identityAppLinks) {
log.error("Do something with " + il.getNativeIdentity() + " for identity " + identity.getName());
}
context.saveObject(identity);
}
// Commit every few records.
if (0 == (recordCounter % 10)) {
// context.commitTransaction();
context.decache();
}
}
//context.commitTransaction();
context.decache();
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.