hi currently we are generating saamaccount name using rule if there firstname and lastname changes we need to update their saamaccount name also how to acheive it ?
Hi @roopa189 ,
If sAMAccountName is generated using a username generation rule, it is typically set only during account creation. Any subsequent changes to the user’s first name or last name will not automatically update the existing sAMAccountName.
To keep it in sync, you’ll need a process to detect changes to firstname or lastname, recalculate the new sAMAccountName, and trigger an account update in Active Directory. This can be achieved using an ISC workflow, provisioning policy, or a rule.
One important consideration is that updating sAMAccountName is effectively an account rename operation in AD, so it’s worth assessing any downstream application dependencies before implementing it.
Thanks
Hi Roopa,
When the name changes, the sAMAcountName can be updated as well. The approach depends on how the value was originally generated. If custom logic is involved, a Before Provisioning Rule can be used to update the value.
However, there must be a trigger that generates a Modify plan. Depending on the use case, it can be achieved through Attribute sync or LCS change actions or other event-driven processes.
Hi @roopa189 Assuming that you are using attribute sync on first and last names, then an account modify will be generated.
2 Options:
- An UPDATE Provisioning policy. Bear in mind, though, that you are not wanting to generate it every time an update occurs and that uniqueness checks can get tricky. For instance John Smith changing name to Jane Smith, may still want to generate JSMITH, but that already exists, so may generate JSMITH1.
- An After Modify Connector Rule and put all your logic into Powershell.
However, I have to say, that I would never recommend automatic updates to a sAMAccountName, as the end user may not have knowledge of when the change is happening and will not know what the generated sAMAccountName is, so may impact ability to log on. Because of this, I would keep AD as authoritative for sAMAccountName. If you have workflows I would generate an email to the Service Desk in these circumstances.
Hi @roopa189
I have faced the same use case in my previous project, so written sample Before provisioning rule that will trigger at the time of attribute sync, just take below rule and implement your samaccount name logic inside the code and try to exxecute it.
Note:
1.Use the SAMAccountName logic based on your use case
2.After adding your logic test with rule validator to avoid errors, mentioned rule is cloud rule.
import sailpoint.object.*;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import java.text.DecimalFormat;
import java.util.;
if (plan == null || plan.getAccountRequests() == null) {
return null;
}
public String generateUniqueSAMAccountName(String identityName, String appName,
String firstName, String lastName) {
String base = (lastName + firstName.substring(0, 1)).toLowerCase();
if (base.length() > 18) {
base = base.substring(0, 18);
}
DecimalFormat df = new DecimalFormat(“00”);
for (int i = 0; i <= 99; i++) {
String candidate = (i == 0) ? base : base + df.format(i);
if (idn.isUniqueLDAPValue(identityName, appName, “sAMAccountName”, candidate)) {
return candidate;
}
}
return null;
}
// Get IDENTITY ATTRIBUTES
Identity identity = plan.getIdentity();
String identityName = identity.getName();
String applicationName = application.getName();
String currentFirstName = identity.getFirstname().replaceAll(“[^a-zA-Z0-9]”, “”);
String currentLastName = identity.getLastname().replaceAll(“[^a-zA-Z0-9]”, “”);
for (AccountRequest accountRequest : plan.getAccountRequests()) {
if (!applicationName.equals(accountRequest.getApplicationName())) {
continue;
}
if (!AccountRequest.Operation.Modify.equals(accountRequest.getOperation())) {
continue;
}
if (accountRequest.getAttributeRequests() == null) {
continue;
}
boolean firstNameChanged = false;
boolean lastNameChanged = false;
String NewFirst = null;
String NewLast = null;
for (AttributeRequest ar : accountRequest.getAttributeRequests()) {
if ("firstname".equalsIgnoreCase(ar.getName()) && ar.getValue() != null) {
firstNameChanged = true;
NewFirst = ar.getValue().toString().replaceAll("[^a-zA-Z0-9]", "");
}
if ("lastname".equalsIgnoreCase(ar.getName()) && ar.getValue() != null) {
lastNameChanged = true;
NewLast = ar.getValue().toString().replaceAll("[^a-zA-Z0-9]", "");
}
}
if (!firstNameChanged && !lastNameChanged) {
continue;
}
//Resolve final first/last name
String finalFirst = (NewFirst != null) ? NewFirst : currentFirstName;
String finalLast = (NewLast != null) ? NewLast : currentLastName;
if (NewFirst.isEmpty() || NewLast.isEmpty()) {
continue;
}
// Generate new unique sAMAccountName
String newSAM = generateUniqueSAMAccountName(identityName, applicationName, finalFirst, finalLast);
if (newSAM != null) {
accountRequest.add(new AttributeRequest("sAMAccountName", ProvisioningPlan.Operation.Set, newSAM));
} else {
}
}
return null;
if you are not yet implemented sAMAccountName username generation rule, then just take below attribute generator rule as reference and modify the rule based on your use case, I hope this will work for your use case.
Attribute Generator RULE for SAMAccountName generation:
import sailpoint.object.Identity;
import sailpoint.server.IdnRuleUtil;
import sailpoint.object.*;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import java.text.DecimalFormat;
import java.util.*;
String identityName = identity.getName();
String applicationId = “”; // All domains connected source - applicationID
// Get the values
String FirstName = identity.getFirstname();
String LastName = identity.getLastName();
// Null Checks
if (FirstName == null || FirstName.trim().isEmpty()) {
return null;
}
if (LastName == null || LastName.trim().isEmpty()) {
// Do NOT return null here, handle missing last name case later
// For now, just continue with empty LastName
LastName = “”;
}
// Remove all non-alphanumeric characters
String firstName = FirstName.replaceAll(“[^a-zA-Z0-9]”, “”);
String lastName = LastName.replaceAll(“[^a-zA-Z0-9]”, “”);
if (firstName.isEmpty()) {
return null;
}
// Determine if last name is missing after sanitization
boolean isLastNameMissing = (lastName == null || lastName.isEmpty());
int maxLength = 20;
String baseSAM;
if (isLastNameMissing) {
//FirstName.FirstInitial
baseSAM = firstName + "." + firstName.substring(0, 1);
//If more than 20, trim FirstName to 18 characters
if (baseSAM.length() > maxLength) {
String trimmedFirstName = firstName.length() > 18
? firstName.substring(0, 18)
: firstName;
baseSAM = trimmedFirstName + "." + firstName.substring(0, 1);
}
} else {
//FirstName.LastName
baseSAM = firstName + "." + lastName;
//If more than 20, use FirstName.LastInitial
if (baseSAM.length() > maxLength) {
baseSAM = firstName + "." + lastName.substring(0, 1);
}
//If still more than 20, trim FirstName to 18 characters
if (baseSAM.length() > maxLength) {
String trimmedFirstName = firstName.length() > 18
? firstName.substring(0, 18)
: firstName;
baseSAM = trimmedFirstName + "." + lastName.substring(0, 1);
}
}
// Generate unique sAMAccountName
String sAMAccountName = baseSAM;
int counter = 1;
while (!idn.isUniqueLDAPValue(identityName, applicationId, “sAMAccountName”, sAMAccountName)) {
// uniqueness check increment value from 1 to increment by sequence
String suffix = String.valueOf(counter);
int allowedLength = maxLength - suffix.length();
if (allowedLength <= 0) {
return null;
}
sAMAccountName =
baseSAM.substring(0, Math.min(baseSAM.length(), allowedLength)) + suffix;
counter++;
// Safety break to avoid infinite loop
if (counter > 9999) {
return null;
}
}
return sAMAccountName;
while creating an account we are greeting sespray error ?
Do you have any suggestions on this
Hi @PraneethGaddam_1207 Please open a new topic for a new problem.
@prasadm I have same user case and this code helped me one of the implementation. Thank you for the sharing.
Hi @PraneethGaddam_1207 Please open a new case for this question, I will assist you on this issue.
if phone number updated then also update policy is triggering how to handle those scenarios we have before provisioning rule also in place
Hi @roopa189 Like I say above, you are not going to want to change the sAMAccountName every time the account is updated. Also, as I say above, I can’t recommend automatic sAMAccountName update, so I’ll step back from the discussion.
Hi @roopa189
You need a Before Provisioning Rule (or Attribute Sync logic) on the AD source that recalculates sAMAccountName when first/last name changes, plus a rule/transform attached to the sAMAccountName schema attribute on the Identity Profile so refreshes regenerate it.
Two pieces to get right:
- Recalculate the value when name changes
If sAMAccountName is generated via a Rule-type transform or Attribute Generator rule on the Identity Profile’s identity attribute mapping, it should already recompute on every aggregation/refresh.
- Actually push the change to AD
Just recalculating the identity attribute won’t rename the AD account unless:
sAMAccountName is mapped in the Create Account on the AD source as an attribute that syncs from identity to account (Attribute Sync), and the AD source’s provisioning policy/account attribute mapping includes sAMAccountName so ISC issues a Modify Account request with the new value on refresh.
Refer this best practice reference guide: Best Practices: Active Directory Account Moves - Compass
Hi @roopa189 Any progress on this so far?