Hey @ethompson, I misunderstood the situation when I wrote my first reply. I didn’t realize the AC_NewParent and AC_NewName were different components of IDN functionality for distinguishedName modifications. This was a great discovery for me, and I am able to use it as a better method for appropriate OU placement.
I have built this functionality into my clients’ functionality, and it’s working well. Through this implementation, I found that the method described in this thread is outside best practices. The article that explains what can be done vs. should be done is here: Article Link.
It looks like the reason you are having these errors and the updates taking place is because the AC_NewName and AC_NewParent attributes aren’t actually attributes that can be verified, but when they are updated through the UPDATE provisioning policy, an automatic check for the updated value is executed, which returns as a failure, since the value doesn’t actually exist in AD, nor is it verifiable.
This can be implemented into a Before Provisioning rule. I modified the example to fit the needs that my client has, but Rules have to be vetted, approved, and created by Expert Services, which is a billable service. I may be wrong about this process, but that’s my current understanding.
Below is the script for the rule, which has 3 “use cases”: Enable (previously disabled), Move, Disable.
import sailpoint.object.Identity;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
List accountRequests = plan.getAccountRequests();
if (accountRequests != null) {
for (AccountRequest accountRequest: accountRequests) {
AccountRequest.Operation op = accountRequest.getOperation();
if(op == null) continue;
String nativeIdentity = accountRequest.getNativeIdentity();
Identity identity = plan.getIdentity();
String currentLCS = null;
String activeOU = null;
String disabledOU = null;
if(identity != null){
currentLCS = identity.getAttribute("cloudLifecycleState");
activeOU = identity.getAttribute("parentOu");
disabledOU = "OU=Disabled Users,DC=xxx,DC=com";
}
boolean departmentChanged = false;
if(op.equals(AccountRequest.Operation.Modify)){
List dAttrReqs = accountRequest.getAttributeRequests("department");
if(dAttrReqs != null && !dAttrReqs.isEmpty()){
departmentChanged = true;
}
}
String newOU = null;
if ("active".equals(currentLCS) && op.equals(AccountRequest.Operation.Enable)
&& disabledOU != null && activeOU != null && nativeIdentity.endsWith(disabledOU)){
//Account is disabled and needs to be re-enabled.
newOU = activeOU;
}
else if ("active".equals(currentLCS) && departmentChanged && activeOU != null){
//Department has changed--move user to appropriate OU.
newOU = activeOU;
}
else if("terminated".equals(currentLCS) && op.equals(AccountRequest.Operation.Disable)){
//User has been terminated, move to disabled OU.
newOU = disabledOU;
}
if(newOU != null && !nativeIdentity.endsWith(newOU)){
//If changes have been identified, adjust OU for the user.
accountRequest.add(new AttributeRequest("AC_NewParent", ProvisioningPlan.Operation.Set, newOU));
}
}
}
Hope this helps. This discussion with you has absolutely helped me.