AD - Active Directory Contact Object Creation for Manager

Which IIQ version are you inquiring about?

Version 8.2

Share all details related to your problem, including any error messages you may have received.

Hi Team,

We have a requirement to create a contact object in Active Directory for managers via SailPoint Identity IQ. We have a total of 4 Active Directories in SailPoint IIQ, resulting in 4 different AD domains. When we execute the joiner feature, if a manager belongs to a different domain from the user, the manager field remains empty in Active Directory during provisioning. Thus, we aim to address this by implementing a check: if the manager’s domain differs from the user’s domain, we will create a contact object for the manager within the user’s domain and link the manager’s details with the user’s profile in AD.

For example, considering the following 4 AD domains:

OU=adtechnologies.com,DC=lab,DC=ad”
“OU=mrl.vlt.intra,DC=lab,DC=ad”
“OU=Network.Local,DC=lab,DC=ad”
“OU=Mexichem,DC=mexqas,DC=com”
If the user’s domain belongs to “OU=adtechnologies.com,DC=lab,DC=ad” and the manager’s domain belongs to “OU=mrl.vlt.intra,DC=lab,DC=ad,” then we will create a contact object for the manager as follows: “CN=Manager Firstname LastName, OU=Contacts,OU=adtechnologies.com,DC=lab,DC=ad.” Additionally, we will include the manager’s first name, last name, and email address in the contact object.

Follow the below link if you have not already gone through
Solved: Contact Object Creation in 7.2p2 - Compass (sailpoint.com)

Now during the joiner check if the contact object is already present, directly update that as manager if not create a contact object using code in above link and set that as manager.

Hi @iamksatish Thank you for your prompt response. However, we aim to establish a custom rule that runs daily via a custom task. This rule should verify whether the manager’s domain differs from the user’s domain and if the manager field is empty in the user’s Active Directory profile. If these conditions are met, the rule will create a manager contact object in the user’s domain. If a manager contact object already exists, it will link that manager to the user’s profile in AD. If not, it will create a new manager contact object. Thank you!!

1 Like

Your approach seems good( if you don’t bother about a immediate manager update during joiner, but I still would prefer doing this during joiner ) and anyhow with the approach you mentioned you can utilise the above code for creating the contact objects and adding the object type contact in your schema and aggregating the same to Sailpoint will provide the contact details within Sailpoint itself for validating the presence or you can use JNDI code to check against AD for presence and create the contact object if not present

Can I know what is the challenge or where exactly need the help in this approach to assist further

Hi @iamksatish if i will doing this during joiner then where I need to write that rule in Before Provisioning or After Provisioning or some where else? Thank you!!

You can do it in either of the place , it doesn’t matter , but preferably during before provisioning rule so that during account creation itself
You will have the right manager in place
If it’s during create you just have to update the existing attribute request of plan

If you want to do during after provisioning rule you have to call a workflow or another process and provisioning plan to modify the account

But please go with before provisioning rule

Hi @iamksatish For POC, I have wrote below code to run via custom task but the code is failing and error is “Failed to submit contact object creation request for Active Directory: Missing identity”
Can you please check and suggest what I am missing?

import sailpoint.object.Identity;
import sailpoint.object.QueryOptions;
import sailpoint.object.Application;
import sailpoint.object.Attributes;
import sailpoint.api.SailPointContext;
import sailpoint.api.SailPointFactory;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.tools.GeneralException;
import sailpoint.api.Provisioner;
import sailpoint.api.IdentityService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// Define the log
//Log log = LogFactory.getLog("rule.Log");

// Get the SailPoint context
SailPointContext context = SailPointFactory.getCurrentContext();

// Replace with actual identity name to be provisioned
String identityName = "ct252525";
Identity identity = context.getObjectByName(Identity.class, identityName);

if (identity == null) {
    log.error("Identity '" + identityName + "' not found.");
} else {
    // Replace with actual manager ID
    String managerId = "gj256565";
    Identity manager = context.getObjectByName(Identity.class, managerId);

    if (manager == null) {
        log.error("Manager identity '" + managerId + "' not found.");
    } else {
        String userDN = identity.getAttribute("adDn");
        String managerDN = manager.getAttribute("adDn");
        String managerFN = manager.getAttribute("firstname");
        String managerLN = manager.getAttribute("lastname");
        String managerEmail = manager.getAttribute("emailAzure");

        log.error("userDN: " + userDN);
        log.error("managerDN: " + managerDN);
        log.error("managerFN: " + managerFN);
        log.error("managerLN: " + managerLN);
        log.error("managerEmail: " + managerEmail);

        // Check if manager's DN does not contain "OU=Network.Local"
        if (managerDN != null && !managerDN.contains("OU=Network.Local")) {
            // Construct DN for contact object
            String contactDN = "cn=" + managerFN + " " + managerLN + ",OU=Contacts,OU=_Central_services,OU=Network.Local,DC=lab,DC=ad";
            log.error("contactDN: " + contactDN);

            // Create attributes for contact object
            Attributes contactAttributes = new Attributes();
            contactAttributes.put("objectClass", "contact");
            contactAttributes.put("cn", managerFN + " " + managerLN);
            contactAttributes.put("sn", managerLN);
            contactAttributes.put("givenName", managerFN);
            contactAttributes.put("mail", managerEmail);
            log.error("contactAttributes: " + contactAttributes);

            // Fetch the AD application
            Application adApp = context.getObjectByName(Application.class, "Wavin-Application-ActiveDirectory");
            log.error("adApp: " + adApp);

            if (adApp != null) {
                try {
                    // Create a new AccountRequest
                    AccountRequest accountRequest = new AccountRequest();
                    accountRequest.setOperation(AccountRequest.Operation.Create);
                    accountRequest.setApplication(adApp.getName());
                    accountRequest.setNativeIdentity(contactDN);

                    // Create and add AttributeRequests to the AccountRequest
                    accountRequest.add(new AttributeRequest("objectClass", ProvisioningPlan.Operation.Set, "contact"));
                    accountRequest.add(new AttributeRequest("cn", ProvisioningPlan.Operation.Set, managerFN + " " + managerLN));
                    accountRequest.add(new AttributeRequest("sn", ProvisioningPlan.Operation.Set, managerLN));
                    accountRequest.add(new AttributeRequest("givenName", ProvisioningPlan.Operation.Set, managerFN));
                    accountRequest.add(new AttributeRequest("mail", ProvisioningPlan.Operation.Set, managerEmail));
                    log.error("Added attributes to accountRequest");

                    // Create a new ProvisioningPlan
                    ProvisioningPlan provisioningPlan = new ProvisioningPlan();
                    provisioningPlan.add(accountRequest);
                    log.error("provisioningPlan: " + provisioningPlan);

                    // Use Provisioner to execute the provisioning plan
                    Provisioner provisioner = new Provisioner(context);
                    provisioner.execute(provisioningPlan);
                    context.commitTransaction();

                    log.info("Contact object creation request submitted successfully for Active Directory.");
                } catch (GeneralException e) {
                    context.rollbackTransaction();
                    log.error("Failed to submit contact object creation request for Active Directory: " + e.getMessage());
                }
            } else {
                log.error("Active Directory application 'Wavin-Application-ActiveDirectory' not found.");
            }
        } else {
            log.warn("Manager's DN contains 'OU=Network.Local'.");
        }
    }
}

Hi @gopalmca1,

in your provisioningPlan variable you forget to set nativeIdentity wich must be your identityId

 ProvisioningPlan provisioningPlan = new ProvisioningPlan();
 provisioningPlan.add(accountRequest);
 provisioningPlan.setNativeIdentity(managerId)
...

@gopalmca1
Your provisioning Plan should contain a identity Object Set

use below line of code

provisioningPlan.setIdentity(manager);

Hi @iamksatish I tried the above line and now it’s not throwing the error. But getting provisioning failed error. Also, it’s creating manager identity as user objectClass instead of contact. Additionally it’s not linking manager with identity as well.

image

Hi @baoussounda Thanks for your response. But error gone with below code
provisioningPlan.setIdentity(manager);. Thank you!!

Please follow this

accountRequest.add(new AttributeRequest(“objectType”,ProvisioningPlan.Operation.Add,“contact”));

Instead of accountRequest.add(new AttributeRequest(“objectClass”, ProvisioningPlan.Operation.Set, “contact”));

try and let me know once

Hi @iamksatish getting below error.

Hi @iamksatish any idea, what I am missing here?

Please share your rule xml

Hi @iamksatish Please find code below. Thank you!!

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule created="" id="" language="beanshell" modified="" name="POC2-Manager-Contact" type="FieldValue">
  <Description>This rule can be used to generate a field value (eg - an account name) using data from the given Identity. If this rule is run in the context of a workflow step then the arguments passed into the step will also be available. Also, any field values that have been processed so far from the policy related to the Application/Role will be available.</Description>
  <Signature returnType="String">
    <Inputs>
      <Argument name="log" type="org.apache.commons.logging.Log">
        <Description>
          The log object associated with the SailPointContext.
        </Description>
      </Argument>
      <Argument name="context" type="sailpoint.api.SailPointContext">
        <Description>
          A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
        </Description>
      </Argument>
      <Argument name="identity" type="Identity">
        <Description>
          The Identity object that represents the user needing the field value.
        </Description>
      </Argument>
      <Argument name="link" type="Link">
        <Description>
          The sailpoint.object.Link that is being acted upon. If the link is not applicable,
          this value will be null.
        </Description>
      </Argument>
      <Argument name="group" type="AccountGroupDTO">
        <Description>
          The sailpoint.web.group.AccountGroupDTO that is being acted upon. If the AccountGroupDTO
          is not applicable, the value will be null.
        </Description>
      </Argument>
      <Argument name="project" type="ProvisioningProject">
        <Description>
          The provisioning project being acted upon. If a provisioning project is not applicable,
          the value will be null.
        </Description>
      </Argument>
      <Argument name="accountRequest" type="ProvisioningPlan.AccountRequest">
        <Description>
          The account request. If an account request is not applicable, the value will be null.
        </Description>
      </Argument>
      <Argument name="objectRequest" type="ProvisioningPlan.ObjectRequest">
        <Description>
          The object request. If an object request is not applicable, the value will be null.
        </Description>
      </Argument>
      <Argument name="role" type="Bundle">
        <Description>
          The role with the template we are compiling. If the role is
          not applicable, the value will be null.
        </Description>
      </Argument>
      <Argument name="application" type="Application">
        <Description>
          The sailpont.object.Application with the template we are compiling. If the application
          is not applicable, the value will be null.
        </Description>
      </Argument>
      <Argument name="template" type="Template">
        <Description>
          The Template that contains this field.
        </Description>
      </Argument>
      <Argument name="field" type="Field">
        <Description>
          The current field being computed.
        </Description>
      </Argument>
      <Argument name="current" type="Object">
        <Description>
          The current value corresponding to the identity or account attribute that the field represents.
          If no current value is set, this value will be null.
        </Description>
      </Argument>
      <Argument name="operation" type="ProvisioningPlan.Operation">
        <Description>
          The operation being performed.
        </Description>
      </Argument>
    </Inputs>
    <Returns>
      <Argument name="value">
        <Description>
          The string value created.
        </Description>
      </Argument>
    </Returns>
  </Signature>
  <Source>import sailpoint.object.Identity;
  import sailpoint.object.Application;
  import sailpoint.object.Attributes;
  import sailpoint.api.SailPointContext;
  import sailpoint.api.SailPointFactory;
  import sailpoint.object.ProvisioningPlan;
  import sailpoint.object.ProvisioningPlan.AccountRequest;
  import sailpoint.object.ProvisioningPlan.AttributeRequest;
  import sailpoint.tools.GeneralException;
  import sailpoint.api.Provisioner;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;


  try {
    // Get the SailPoint context
    SailPointContext context = SailPointFactory.getCurrentContext();

    // Replace with actual identity name to be provisioned
    String identityName = "22222224";
    Identity identity = context.getObjectByName(Identity.class, identityName);

    if (identity == null) {
      log.error("Identity '" + identityName + "' not found.");
    } else {
      // Replace with actual manager ID
      String managerId = "11111119";
      Identity manager = context.getObjectByName(Identity.class, managerId);

      if (manager == null) {
        log.error("Manager identity '" + managerId + "' not found.");
      } else {
        String userDN = (String) identity.getAttribute("adDn");
        String managerDN = (String) manager.getAttribute("adDn");
        String managerFN = (String) manager.getAttribute("firstname");
        String managerLN = (String) manager.getAttribute("lastname");
        String managerEmail = (String) manager.getAttribute("emailAzure");

        log.error("userDN: " + userDN);
        log.error("managerDN: " + managerDN);
        log.error("managerFN: " + managerFN);
        log.error("managerLN: " + managerLN);
        log.error("managerEmail: " + managerEmail);

        // Check if manager's DN does not contain "DC=mexqas"
        if (managerDN != null &amp;&amp; !managerDN.contains("DC=mexqas")) {
          // Construct DN for contact object
          String contactDN = "cn=" + managerFN + " " + managerLN + ",OU=Contacts,DC=mexqas,DC=com";
          log.error("contactDN: " + contactDN);

          // Fetch the AD application
          Application adApp = context.getObjectByName(Application.class, "Mexichem-Application-ActiveDirectory");
          log.error("adApp: " + adApp);

          if (adApp != null) {
            try {
              // Create a new AccountRequest
              ProvisioningPlan provisioningPlan = new ProvisioningPlan();
              AccountRequest accountRequest = new AccountRequest();
              accountRequest.setOperation(AccountRequest.Operation.Create);
              accountRequest.setApplication(adApp.getName());
              accountRequest.setNativeIdentity(contactDN);

              // Create and add AttributeRequests to the AccountRequest
              //accountRequest.add(new AttributeRequest("objectClass","contact"));
              accountRequest.add(new AttributeRequest("objectType", "contact"));
              accountRequest.add(new AttributeRequest("cn", managerFN + " " + managerLN));
              accountRequest.add(new AttributeRequest("sn", managerLN));
              accountRequest.add(new AttributeRequest("givenName", managerFN));
              accountRequest.add(new AttributeRequest("mail", managerEmail));
              log.error("Added attributes to accountRequest: " + accountRequest.toXml());

              // Create a new ProvisioningPlan

              provisioningPlan.add(accountRequest);
              provisioningPlan.setIdentity(manager);
              log.error("provisioningPlan: " + provisioningPlan.toXml());
              //return provisioningPlan;

              // Use Provisioner to execute the provisioning plan
              Provisioner provisioner = new Provisioner(context);
              provisioner.execute(provisioningPlan);
              log.error("provisioner: " + provisioner);
              context.commitTransaction();
              log.info("Contact object creation request submitted successfully for Active Directory.");
            } catch (GeneralException e) {
              context.rollbackTransaction();
              log.error("Failed to submit contact object creation request for Active Directory: " + e.getMessage());
            }
          } else {
            log.error("Active Directory application 'Mexichem-Application-ActiveDirectory' not found.");
          }
        } else {
          log.warn("Manager's DN contains 'OU=Network.Local'.");
        }
      }
    }
  } catch (GeneralException e) {
    log.error("GeneralException: " + e.getMessage());
  }

  </Source>
</Rule>

Looks like a single value allowed at AD is passed as a List or multi valued, can you paste the plan from logs and also logs of IQService side along with all details

Code wise I don’t see any Multi value being passed
Also share the provisioning transaction xml as well

Hi @iamksatish thanks for your response.

Below is the logs from IQService.

<entry key="Request">
        <value>
          <AccountRequest application="Mexichem-Application-ActiveDirectory" nativeIdentity="cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com" op="Create">
            <AttributeRequest name="sn" op="Set" value="Testtt7"/>
            <AttributeRequest name="givenName" op="Set" value="Emal7"/>
            <AttributeRequest name="mail" op="Set">
              <Value>
                <List>
                  <String>[email protected]</String>
                  <String>[email protected]</String>
                </List>
              </Value>
            </AttributeRequest>
            <AttributeRequest name="objectType" op="Set">
              <Value>
                <List>
                  <String>contact</String>
                  <String>User</String>
                </List>
              </Value>
            </AttributeRequest>
            <AttributeRequest name="userPrincipalName" op="Set" value="[email protected]"/>
            <AttributeRequest name="sAMAccountName" op="Set" value="et024586"/>
            <AttributeRequest name="displayName" op="Set" value="Emal7 Testtt7 | Orbia (Wavin)"/>
            <AttributeRequest name="IIQDisabled" op="Set">
              <Value>
                <Boolean></Boolean>
              </Value>
            </AttributeRequest>
            <AttributeRequest name="password" op="Set" value="**********"/>
            <AttributeRequest name="pwdLastSet" op="Set">
              <Value>
                <Boolean>true</Boolean>
              </Value>
            </AttributeRequest>
            <AttributeRequest name="department" op="Set" value="DE Hardware and IT Infrastructure"/>
            <AttributeRequest name="co" op="Set" value="India"/>
            <AttributeRequest name="c" op="Set" value="IN"/>
            <AttributeRequest name="division" op="Set" value="DV Wavin"/>
            <AttributeRequest name="employeeType" op="Set" value="employee"/>
            <AttributeRequest name="physicalDeliveryOfficeName" op="Set" value="Bangalore"/>
            <AttributeRequest name="company" op="Set" value="Wavin B.V."/>
            <AttributeRequest name="employeeNumber" op="Set" value="111119"/>
            <AttributeRequest name="mpeopleID" op="Set" value="email7.Testtt7"/>
            <AttributeRequest name="msNPAllowDialin" op="Set" value="Not Set"/>
          </AccountRequest>
        </value>
      </entry>
    </Map>
  </Arguments>
</RpcRequest>
"
05/27/2024 02:54:40 : RpcHandler [ Thread-7 ] DEBUG : "Initiating the serviceState for 63c1c747-07f7-46b3-9af7-c2538ae24144"
05/27/2024 02:54:40 : RpcHandler [ Thread-7 ] INFO : "Calling Service [ADConnector] and method[provision] "
05/27/2024 02:54:40 : AbstractConnector [ Thread-7 ] DEBUG : "ENTER AbstractConnector"
05/27/2024 02:54:40 : AbstractConnector [ Thread-7 ] DEBUG : "EXIT AbstractConnector"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER prepare"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT prepare"
05/27/2024 02:54:40 : AbstractConnector [ Thread-7 ] DEBUG : "ENTER Provision"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER doProvision"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] INFO : "Operation requested is: Create"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER preProcessExchangeRequests"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER isExchangeEnabled"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT isExchangeEnabled"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] INFO : "Exchange environment is not configured for the forest setting for - cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "There are no requests to update the exchange configuration for - cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT preProcessExchangeRequests"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER CreateADObject"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER Create"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] INFO : "Start Adding identity : cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER bind"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ENTER buildURLFromIdentity"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] INFO : "Server [MXTLAW0702.mexqas.com] DN [OU=Contacts,DC=mexqas,DC=com]"
05/27/2024 02:54:40 : Util [ Thread-7 ] DEBUG : "FQDN for MXTLAW0702.mexqas.com: MXTLAW0702.mexqas.com"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "Derived URL[LDAP://MXTLAW0702.mexqas.com/OU=Contacts,DC=mexqas,DC=com] original [OU=Contacts,DC=mexqas,DC=com]"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT buildURLFromIdentity"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] INFO : "Bind with User new DirectoryEntry(LDAP://MXTLAW0702.mexqas.com/OU=Contacts,DC=mexqas,DC=com, [email protected] authType=ServerBind)"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT bind"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] ERROR : "Exception caught in Create for identity: cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com - System.InvalidCastException: Unable to cast object of type 'System.Collections.ArrayList' to type 'System.String'.
   at sailpoint.services.ADConnectorServices.Create(Boolean processExchangeAttributeUpdate)"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT Create"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "ADObject creation complete"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT CreateADObject"
05/27/2024 02:54:40 : ADConnectorServices [ Thread-7 ] DEBUG : "EXIT doProvision"
05/27/2024 02:54:40 : AbstractConnector [ Thread-7 ] DEBUG : "EXIT Provision"
05/27/2024 02:54:40 : RpcHandler [ Thread-7 ] INFO : "OutgoingResponse:
<?xml version="1.0" encoding="utf-8"?>
<RpcResponse version="1.0" requestId="63c1c747-07f7-46b3-9af7-c2538ae24144" complete="true">
  <RpcErrors>
    <List>
      <String>Unable to cast object of type 'System.Collections.ArrayList' to type 'System.String'.. HRESULT:[0x80004002]</String>
    </List>
  </RpcErrors>
  <ResultAttributes>
    <Map>
      <entry key="requestProcessedOn" value="27/05/2024 02:54:40 a. m." />
      <entry key="returnRequest">
        <value>
          <AccountRequest application="Mexichem-Application-ActiveDirectory" op="Create" nativeIdentity="cn=Emal7 Testtt7,OU=Contacts,DC=mexqas,DC=com">
            <AttributeRequest op="Set" name="sn" value="Testtt7" />
            <AttributeRequest op="Set" name="givenName" value="Emal7" />
            <AttributeRequest op="Set" name="mail">
              <Value>
                <List>
                  <String>[email protected]</String>
                  <String>[email protected]</String>
                </List>
              </Value>
            </AttributeRequest>
            <AttributeRequest op="Set" name="objectType">
              <Value>
                <List>
                  <String>contact</String>
                  <String>User</String>
                </List>
              </Value>
            </AttributeRequest>
            <AttributeRequest op="Set" name="userPrincipalName" value="[email protected]" />
            <AttributeRequest op="Set" name="sAMAccountName" value="et024586" />
            <AttributeRequest op="Set" name="displayName" value="Emal7 Testtt7 | Orbia (Wavin)" />
            <AttributeRequest op="Set" name="IIQDisabled">
              <Value>
                <Boolean>false</Boolean>
              </Value>
            </AttributeRequest>
            <AttributeRequest op="Set" name="password" value="**********" />
            <AttributeRequest op="Set" name="pwdLastSet">
              <Value>
                <Boolean>true</Boolean>
              </Value>
            </AttributeRequest>
            <AttributeRequest op="Set" name="department" value="DE Hardware and IT Infrastructure" />
            <AttributeRequest op="Set" name="co" value="India" />
            <AttributeRequest op="Set" name="c" value="IN" />
            <AttributeRequest op="Set" name="division" value="DV Wavin" />
            <AttributeRequest op="Set" name="employeeType" value="employee" />
            <AttributeRequest op="Set" name="physicalDeliveryOfficeName" value="Bangalore" />
            <AttributeRequest op="Set" name="company" value="Wavin B.V." />
            <AttributeRequest op="Set" name="employeeNumber" value="111119" />
            <AttributeRequest op="Set" name="mpeopleID" value="email7.Testtt7" />
            <AttributeRequest op="Set" name="msNPAllowDialin" value="Not Set" />
          </AccountRequest>
        </value>
      </entry>
    </Map>
  </ResultAttributes>
</RpcResponse>"
05/27/2024 02:54:40 : RpcHandler [ Thread-7 ] DEBUG : "ENTER Close"
05/27/2024 02:54:40 : RpcHandler [ Thread-7 ] DEBUG : "EXIT Close"

Here is plan logs.
PlanLog.txt (43.4 KB)

Try Set Operation instead of Add

Old
accountRequest.add(new AttributeRequest(“objectType”,ProvisioningPlan.Operation.Add,“contact”));

new

accountRequest.add(new AttributeRequest(“objectType”,ProvisioningPlan.Operation.Set,“contact”));

Also Set mail also using set operation

          accountRequest.add(new AttributeRequest("mail",ProvisioningPlan.Operation.Set, managerEmail));

and make sure managerEmail is a String

Please test and let me know if still same issue