Generate unique samaccount based on user type

We have use case where generate sAMAccountName values based on the user’s Type, using a fixed alpha prefix and a 5-digit numeric sequence. The numeric portion must continue from the last issued number for that prefix and remain unique.
For E.g.:

Employee → E##### (e.g., E01234)
Contractor → N##### (e.g., N04567)
Vendor → V##### (e.g., V12345)

Since we are performing a migration, the numeric sequence must continue from the last assigned number for each prefix (E, N, or V) and generate the next available unique value.

I am evaluating whether this logic can be implemented using a Username Generator Transform, or if it requires developing a custom AttributeGenerator Cloud Rule.

Hi @Ankit_002 I’m afraid that as far as I know, there is no ISC functionality for an auto-increment when generating Identity or Account Attributes, because of the multi-threaded processing which ISC employs. There are a number of posts on the forum about it.

Is there any feasible approach within ISC to fulfill this requirement?

I haven’t found an “in ISC” way…but if you can have a DB source configured, and in the DB, create table with two columns (Primary ID with auto increment, and an Identity Name column), that could do the trick. You first create an account on the DB source by sending the identity Name across, aggregate the Primary ID back…this then becomes your sequence number of the identity to subsequent sAMAccountName generation.

(And then you configure two roles; one role to apply to everyone so that they get this DB account, the other role applies to people who now have this sequence number, which will now allow you to move forward to provision the AD account)

For strictly sequential, gapless, collision-free numbering, I believe @David_Norris external DB auto-increment approach is genuinely the safer design — the database enforces atomicity natively. The AttributeGenerator rule is best used here for the prefix logic (E/N/V) and to handle migration by scanning existing accounts and finding the next available value during the provisioning window when concurrency is low.

Apologies for the incomplete answer — this is a genuinely tricky ISC limitation worth highlighting for the community.

Hi @terry , i think we can do this without a DB and use a Flat File Connector ?

DB approach works because the database itself guarantees atomic auto-increment — a flat file doesn’t offer that same guarantee natively. That said, if provisioning events are low-concurrency (e.g. a one-time migration batch), a flat file could be a practical workaround worth exploring!

Hi @utkirjonkamiljanov I’m still fascinated by how you intend to generate a sequence within ISC. You mention above “scanning existing accounts and finding the next available value”. Could you please give more info on this?

For this specific requirement—maintaining a global numeric sequence that continues from a last issued value—you must use a custom AttributeGenerator Cloud Rule.

You can implement this by using the idn utility within an Account Profile Attribute Generator Rule:
Logic Steps:
Determine the Prefix (E, N, or V) based on the identity object’s type attribute.
Use idn.countAccountsBySearchableAttribute or similar search methods to find the highest existing number for that specific prefix.
Increment that value by 1.
Format the number to 5 digits using String.format(“%05d”, nextNumber) or a similar Java method.
Verify Uniqueness against the target source (e.g. Active Directory) using the built-in isUnique method provided in the rule context

Hi @Deepak_Chaudhary could you possibly expand on exactly how you use “…search methods to find the highest number for that specific prefix”?

ISC’s generator and rule mechanism is based on start from base / 0…generate → lookup → retry with increment loops…every run.

Jeremy is on track, devil is in the details: “find the highest”…AND in a multi-threaded context is the challenge here.

With a flat file connector, who’s the authority party/component to generate a sequence number?

While I don’t have an “In ISC” way…there’s a NERM way (if we butcher the solution, for this thought experiment). Use NERM profiles instead of a DB for the auto increment…but that’s more complicated than necessary.

Hi @j_place check this Generate unique sAMAccountName even after deletion in AD

Search Delay: There can be a slight delay between an account being created and it appearing in search results. For critical sequences, some organizations maintain a secondary “Last ID” value in a Delimited File source to track the absolute last issued number.

Thanks @Deepak_Chaudhary

WADR, your link is how to check for uniqueness.

The OP wants a sequence, which AFAIK is not possible natively in ISC. That is why this use case comes up on this forum regularly and why it has been widely accepted as a “constraint” on ISC that it is not possible.

@David_Norris Has explained how to do it with a JDBC source, which is the only feasible solution that I know of. Delimited File source has been mentioned a couple of times, but with no implementation details, so it’s hard to determine how feasible that would be.

Planning to put following logic in “AttributeGenerator” cloud rule. But not sure how it will behave in multithreading environment.

public String generateUniqueNativeIdentity(String userType, Application application) throws GeneralException {

        if (userType == null) {
            throw new IllegalArgumentException("userType must not be null");
        }
        String type = userType.trim().toLowerCase();
        String prefix;
        int currentNumber=0;
             switch (type) {
            case "emp":
                prefix = EMP_PREFIX; 
                currentNumber = (int)(application.getAttributeValue("EmpLastUsedSeq"));
                break;
            case "nonemp":
                prefix = NONEMP_PREFIX;
                currentNumber = (int)(application.getAttributeValue("NonEmpLastUsedSeq"));
            case "vendor":
                prefix = VENDOR_PREFIX;  
                currentNumber = (int)(application.getAttributeValue("VendorLastUsedSeq"));
                break;
            default:
                throw new IllegalArgumentException("Unsupported user type: " + userType);
        }

        for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
            String candidate = prefix + currentNumber;
            // isUnique == NOT exists in ISC
            boolean exists = idn.accountExistsByNativeIdentity(application.getName(), candidate);
            if (!exists) {
                // Unique -> return
                return candidate;
            }
            // Not unique -> go to next number
            currentNumber++;
        }
        // If we reach here, we couldn't find a unique value in 500 attempts
        throw new IllegalStateException(
            "Unable to generate unique native identity for type '" + userType +
            "' after " + MAX_ATTEMPTS + " attempts"
        );
    }

Note: Here in source under “connectorAttributes” , added 3 custom attributes which store last used sequence value.

Hi @Ankit_002 Sounds interesting, let us know how you get on. Can I ask: how are you going to write back to application attributes?