---
title: Checking Active Directory Field Uniqueness During Create User
slug: checking-active-directory-field-uniqueness-during-create-user
createdAt: 2026-01-21T20:53:39.321Z
---

When creating users in environments with multiple Active Directory domains or forests, it is often necessary to ensure that key directory attributes are unique across all target directories. This article describes an approach for validating and generating unique values during the Create User process in Activate.

Please note the script examples provided may need tweaking to work on later versions of Activate, they are provided as-is as guides or inspiration.

# Overview

In multi-domain or multi-forest environments, user creation can fail or cause conflicts if attributes such as login names or email addresses already exist elsewhere. To prevent this, Activate can be configured to validate uniqueness across multiple directories before the user is created.

This approach:

- Collects multiple OU references across domains and forests
- Uses a PreCreate script to build a directory collection
- Calls custom utility methods to validate uniqueness
- Automatically generates the next available value when conflicts are detected

# Scenario

This approach is suitable when:

- Users may be created in different domains or forests
- A single naming standard is enforced across the organisation
- Attributes must be unique beyond the target OU

The validation OUs do not need to match the final user placement. They are used solely for checking existing objects.

# High-level Process

1. Configure OU references for each domain or forest to be checked
2. Collect those OUs during the PreCreate phase
3. Pass the OU collection into custom utility methods
4. Validate uniqueness for common identity attributes

# Configure OU References

Add a UserOU parameter to the Create User task. Configure this parameter with OU references for every domain or forest that must be checked for existing users.

# Collect OUs in the PreCreate Script

In the PreCreate script, load all configured UserOU values into a collection that can be passed to utility methods.

:::BlockQuote
// Load all OUs to check
foreach (Parameter parameter in Job.Task.GetLocalParameters("UserOU"))
\{
&#x20;   OUReference ouRef = parameter.ValueObject as OUReference;

&#x20;   if (ouRef != null && ouRef.OU != null)
&#x20;       OUS.Add(ouRef.OU);
}
:::

# Generate a Unique Login Name

To generate a unique samAccountName across multiple domains, a NameGenerator can be combined with a custom validation method.

:::BlockQuote
public static string GetNextUniqueLoginName(Job j, string loginName, ProvisioningDirectoryCollection OUs)
\{
&#x20;   j.LogAudit("GetNextUniqueLoginName: &#x7B;0}", loginName);
&#x20;   NameGenerator g = new NameGenerator(loginName, NameGenerator.ValidCharacters.LoginName);
&#x20;   string result = null;

&#x20;   for (int i = 0; i \< 100; i++)
&#x20;   \{
&#x20;       string s = g.GetNextUserName(j).Replace("-", "");
&#x20;       j.LogTrace("S: &#x7B;0}", s);

&#x20;       if (CheckLoginName(j, DSUtilities.EscapeFilterElement(s), OUs))
&#x20;           continue;

&#x20;       result = s;
&#x20;       break;
&#x20;   }

&#x20;   if (result == null)
&#x20;       throw new Exception("Unable to generate unique name");

&#x20;   return result;
}
:::

This method iterates through generated values until a unique login name is found across all configured OUs.

# Generate a Unique UPN and Email Address

User principal name, email address, and alias values can be generated and validated together to ensure global uniqueness.

:::BlockQuote
public static void GetNextUniqueUPNAndMailName(
&#x20;   Job j,
&#x20;   string emailUpnExpression,
&#x20;   string samAccountName,
&#x20;   OUDirectoryEntry userOU,
&#x20;   ProvisioningDirectoryCollection OUs,
&#x20;   out string email,
&#x20;   out string upn,
&#x20;   out string alias)
\{
&#x20;   NameGenerator e = new NameGenerator(emailUpnExpression, NameGenerator.ValidCharacters.Email);
&#x20;   int i = 0;

&#x20;   while (true)
&#x20;   \{
&#x20;       i++;
&#x20;       if (i > 20)
&#x20;           throw new Exception("Unable to generate unique email or UPN name");

&#x20;       string emailGen = e.GetUniqueUPNAndMailAddress(j, j.Arguments.Root, userOU, null);

&#x20;       if (IsUniqueAcrossDomains(j, samAccountName, emailGen, emailGen, OUs))
&#x20;       \{
&#x20;           upn = emailGen;
&#x20;           email = emailGen;
&#x20;           alias = samAccountName;
&#x20;           break;
&#x20;       }
&#x20;   }
}
:::

# Validate Uniqueness Across Domains

Each generated value is validated against every configured OU to ensure no conflicts exist.

:::BlockQuote
public static bool IsUniqueAcrossDomains(
&#x20;   Job j,
&#x20;   string samAccountName,
&#x20;   string emailAddress,
&#x20;   string UPN,
&#x20;   ProvisioningDirectoryCollection OUs)
\{
&#x20;   foreach (OUDirectoryEntry OUToCheck in OUs)
&#x20;   \{
&#x20;       if (!IsUnique(j, samAccountName, emailAddress, UPN, OUToCheck))
&#x20;           return false;
&#x20;   }
&#x20;   return true;
}
:::

The underlying checks validate the following attributes:

- samAccountName
- mailNickname
- mail
- userPrincipalName
- proxyAddresses (SMTP and SIP)
- targetAddress

# Import the Utility Class

To make the utility methods available during user creation, import the class at the top of the PreCreate script.

:::BlockQuote
//@import=//Resources/Custom/Utilities/UserUtilities
:::

# Example NameGenerator Expressions

The following examples show NameGenerator expressions commonly used with this approach.

Login name expression:

:::BlockQuote
\<loginName>#data/lastName:6|data/firstName:1|\{#}loginName>
:::

User principal name expression:

:::BlockQuote
\<userPrincipalName>#\{data/firstName}\:AN|"."|\{data/lastName}\:AN|\{#}|"@%=/data/roles/type/DefaultEmailDomain%"userPrincipalName>
:::

These expressions can be adjusted to align with organisational naming standards and domain structures.
