Extracting, via Rule, Inactive Identities with Active Application Account in SailPoint

Which IIQ version are you inquiring about?

8.3

Hi, I need to extract inactive identities that have accounts on applications that are still active.

I am using this rule which works except for the highlighted line:

  >>>>>>>>>>>>>>>>>>>> ERRORE HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  qo.addFilter(Filter.ne("links.disabled", "true"));
  >>>>>>>>>>>>>>>>>>>> ERRORE HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Do you have any suggestions on how to put the filter on the link status?

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Test - Extraction of Inactive Identities with Active Accounts">
  <Source>
  import sailpoint.object.QueryOptions;
  import sailpoint.object.Filter;
  import sailpoint.object.Identity;
  import java.util.Iterator;
  import java.util.ArrayList;
  import java.util.List;
  import java.time.Duration;
  import java.time.Instant;

  System.out.println("\n========================== LIST OF INACTIVE IDENTITIES with Profiled Accounts - START =========================");  
  Instant start = Instant.now();
  
  // Check if the SailPoint context is available
  if (context == null) {
    throw new IllegalArgumentException("SailPoint context is not available.");
  }

  // List to store the filtered identities
  List filtered_identities = new ArrayList();

  // Create a QueryOptions object to set the filters
  QueryOptions qo = new QueryOptions();
  
  // Add filter for inactive identities only
  qo.addFilter(Filter.eq("inactive", true)); // Retrieves only inactive users
  
  // Search only for those with a non-null name (unnecessary precaution)
  qo.addFilter(Filter.notnull("name"));
  
  // They must have at least one link
  qo.addFilter(Filter.notnull("links.application.name"));
  qo.addFilter(Filter.ne("links.application.name", ""));
  
  
  >>>>>>>>>>>>>>>>>>>> ERRORE HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  qo.addFilter(Filter.ne("links.disabled", "true"));
  >>>>>>>>>>>>>>>>>>>> ERRORE HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
  // The link must not be that of Active Directory
  qo.addFilter(Filter.ne("links.application.name", "CMS-ActiveDirectory"));
  
  // Create a list with only the necessary attributes
  List attributes = new ArrayList();
  attributes.add("name");         // row[0]
  attributes.add("displayName");  // row[1]

  // Execute the query with the selection filter and extract the specific attributes 
  Iterator it = context.search(Identity.class, qo, attributes);

  while (it.hasNext()) {
    Object[] row = it.next();
    String name = (row[0] != null) ? row[0].toString() : "Unknown";         // If the name is null, assign "Unknown"
    String displayName = (row[1] != null) ? row[1].toString() : "Unknown";   // If the displayName is null, assign "Unknown"

    String dispName = name + " (" + displayName + ")";
    System.out.println("dispName : " + dispName);

    filtered_identities.add(dispName);
  }

  Instant end = Instant.now();
  Duration duration = Duration.between(start, end);
  System.out.println("=============================================================================================================");
  System.out.println("Processing duration: " + duration.toMillis() + " milliseconds");
  System.out.println("Number of extracted identities: " + filtered_identities.size());
  //System.out.println("filteredIdentities : " + filtered_identities);
  System.out.println("========================== LIST OF INACTIVE IDENTITIES with Profiled Accounts - END  =========================");
  </Source>
</Rule>

@adolfotrinca

use `qo.addFilter(Filter.ne(“links.iiqDisabled”,true));

Please mark the solution if this helps you

Hi @adolfotrinca,

Simply replace

qo.addFilter(Filter.ne("links.disabled", "true"));

with

qo.addFilter(Filter.ne("links.iiqDisabled", true));

If you ever need to check SailPoint object attributes for QueryOptions, you can refer to this manual, which is where I found the solution.

Hope that helps!

1 Like

Thank you so Much.

Here the actual Rule:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule created="1738918407678" id="0a01295994a81c748194df9d2dfe626a" language="beanshell" modified="1739174563682" name="Test - Estrazione Identities cessate con account profilati">
  <Source>
  import sailpoint.object.QueryOptions;
  import sailpoint.object.Filter;
  import sailpoint.object.Identity;
  import java.util.Iterator;
  import java.util.ArrayList;
  import java.util.List;
  import java.time.Duration;
  import java.time.Instant;

  System.out.println("\n========================== LISTA IDENTITA' NON ATTIVE con Account profilati - START =========================");  
  Instant start = Instant.now();
  
  // Verifica se il contesto è disponibile
  if (context == null) {
    throw new IllegalArgumentException("Il contesto SailPoint non è disponibile.");
  }

  // Lista per memorizzare le identità filtrate
  List&lt;String> filtered_identities = new ArrayList();

  // Creazione di un oggetto QueryOptions per impostare i filtri
  QueryOptions qo = new QueryOptions();
  
  // Aggiunge filtro per le sole Identità NON attive
  qo.addFilter(Filter.eq("inactive", true)); // Recupera solo utenti attivi 
  // Cerca solo quelle con il name non nullo, scrupolo inutile
  qo.addFilter(Filter.notnull("name"));
  // Devono avere almeno un link profilato
  qo.addFilter(Filter.notnull("links.application.name"));
  qo.addFilter(Filter.ne("links.application.name", ""));
  // Devono avere almeno un link NON disabilitato (iiqDisabled = false)
  qo.addFilter(Filter.ne("links.iiqDisabled",true));
 
  // Creazione di un lista con i soli attributi necessari
  List attributes = new ArrayList();
  attributes.add("name"); // row[0]
  attributes.add("displayName"); // row[1]

  // Esecuzione della query con il filtro di selezione 'go' e gli attributi specifici da estrarre 
  Iterator it = context.search(Identity.class, qo, attributes);

  while (it.hasNext()) {
    Object[] row = it.next();
    String name = (row[0] != null) ? row[0].toString() : "Sconosciuto"; 				// Se il name è nullo, assegna "Sconosciuto"
    String displayName = (row[1] != null) ? row[1].toString() : "Sconosciuto"; 	// Se il displayNAme è nullo, assegna "Sconosciuto"

    String dispName = name + " (" + displayName + ")";
    System.out.println("dispName : " + dispName);

    filtered_identities.add(dispName);
  }

  Instant end = Instant.now();
  Duration duration = Duration.between(start, end);
  System.out.println("=============================================================================================================");
  System.out.println("Durata dell'elaborazione: " + duration.toMillis() + " millisecondi");
  System.out.println("Numero Identita estratte: " + filtered_identities.size());
  //System.out.println("filteredIdentities : " + filtered_identities);
  System.out.println("========================== LISTA IDENTITA' NON ATTIVE con Account profilati - END  ==========================");
  </Source>
</Rule>


1 Like

Thank you too for your kind reply.
You are fantastic.

1 Like

Again, thank you for your reply.
One question, I am having a hard time figuring out how to do it so I am asking you who are so kind.
In the above code I extract the name and displayName while I would also need to extract the information regarding the entitlements still active on that deactivated identity.

The question above is also for you if you still have the patience to answer me :slight_smile:

Can you pleas provide the problem statement more clear , what exactly you are looking for?

Yes, sorry, I will try to be clearer.

With the Rule above I was able to extract all the no longer active identities that still have active accounts (links) on some applications.

For example the one in the image above, despite being inactive=true contains an active link on the ActiveDirectory application.

With the Rule I made and corrected thanks to you I get the following information:
dispName : MBDOM\CUTEST1012 (null null)
Application : CMS-ActiveDirectory
Native Identity : CN=Name102…

To this information I would also like to add the list of Entitlements, those always present in the image, which for your convenience I reproduce below.

Thank you again for your availability.

Hi @adolfotrinca,

With the following code you can extract all the entitlements a user has:

  Identity iden = context.getObjectByName(Identity.class, "SU1234");

  //Extract entitlements from a user
  List accesos = new ArrayList();

  if(iden.getExceptions() != null){		
    for(exc : iden.getExceptions()){						//EntitlementGroup
      if(exc.getAttributes() != null &amp;&amp; exc.getAttributes().values() != null){
        for(elem : exc.getAttributes().values()){
          if(elem.getClass() == String.class){
            accesos.add(elem);
          }else{
            for(elem2 : elem){
              accesos.add(elem2);
            }
          }
        }
      }
    }
  }

  if(iden.getRoleDetections() != null){
    for(rol : iden.getRoleDetections()){				//RoleDetection
      if(rol.getTargets() != null){
        for(tg : rol.getTargets()){							//RoleTarget
          if(tg.getItems() != null){
            for(item : tg.getItems()){					//AccountItem
              if(item.getValue() != null){
                if(item.getValue().getClass() == String.class){
                  accesos.add(item.getValue());
                }else{
                  for(item2 : item.getValue()){
                    accesos.add(item2);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  
  //Remove duplicated entitlements
  List entitlements = new ArrayList(new HashSet(accesos));
  
  return entitlements;

In case you need anything else I’ll be glad to help.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.