0 votes

I have modified the "Rename the user if the Full Name is not unique within the OU" and the "Automatically add a digit to the username if it is not unique" script into one. I only removed the unique check from the "Rename the user if the Full Name is not unique within the OU" script.

The rename user is working but the "Rename the user if the Full Name is not unique within the OU" does not seem to change the DN. I have Business Rule set to before user create with the following PS script. I have enter some verbose logging to see if I could tell what was happening. Any ideas would be appreciated.

Import-Module Adaxes
Add-PSSnapin Quest.ActiveRoles.ADManagement

#Check if UPN exists
function IsUserNameUnique($userLogonName)
{
   $user = Get-QADUser -Identity $userLogonName -erroraction silentlycontinue
   return $user -eq $Null
}

# Get the user name info
$username = $Context.GetModifiedPropertyValue("samAccountName")
$sn = $Context.GetModifiedPropertyValue("sn")
$givenName = $Context.GetModifiedPropertyValue("givenName")
$userLogonName = $Context.GetModifiedPropertyValue("userPrincipalName")
$upnSuffix = "domain.com"

$Context.LogMessage("The username entered was " + $username `
  + ".", "Information")
$Context.LogMessage("The userLogonName entered was " + $userLogonName `
  + ".", "Information")

# Get the object DN
$objectDN = $Context.TargetObject.ObjectInfo.DN;

$Context.LogMessage("The target DN is " + $objectDN `
  + ".", "Information")

# Check if the username is unique
if (IsUserNameUnique($userLogonName))
{
    return
}
# If the username is not unique, generate a unique one
$uniqueUsername = $Null
$uniqueUserLogonName = $Null
$uniqueName = $Null

for ($i = 2; $True; $i++)
{
    $uniqueUsername = $username + $i
    # Build new UPN
    $uniqueUserLogonName = $givenName + "." + $sn + $i + "@" + $upnSuffix

    if (IsUserNameUnique($uniqueUserLogonName))
    {
        break
    }
}

# Build new distinguished name (DN)
$objectLeaf = $objectDN.Leaf;

$Context.LogMessage("The Leaf value " + $objectLeaf `
  + ".", "Information")

$objectName = $objectLeaf.Value + $i;

$Context.LogMessage("The name value " + $objectName `
  + ".", "Information")

$objectRdn = New-Object "Softerra.Adaxes.Ldap.Rdn" $objectLeaf.Type,$objectName;

$Context.LogMessage("The RDN value " + $objectRdn `
  + ".", "Information")

$objectDN = $objectDN.Parent;

$Context.LogMessage("The parent DN value " + $objectDn `
  + ".", "Information")

$objectDN.AddLeaf($objectRdn);

$Context.LogMessage("The parent DN + Leaf value " + $objectDn `
  + ".", "Information")

# Update User Logon Name (pre-Windows 2000)
$Context.SetModifiedPropertyValue("samAccountName", $uniqueUsername)

# Update User Logon Name
$Context.SetModifiedPropertyValue("userPrincipalName", $uniqueUserLogonName)

#Update name for Unique DN
$Context.SetModifiedPropertyValue("name", $objectName)

$modifiedDN = $Context.TargetObject.ObjectInfo.DN;
$modifiedName = $Context.GetModifiedPropertyValue("name")

$Context.LogMessage("The UPN has been changed to " + $uniqueUserLogonName `
  + ".", "Information")
$Context.LogMessage("The username has been changed to " + $uniqueUsername `
  + ".", "Information")
$Context.LogMessage("The name has been changed to " + $modifiedName `
  + ".", "Information")
$Context.LogMessage("The DN has been changed to " + $modifiedDN `
  + ".", "Information")
by (590 points)
0

Hello,

We are not quite clear here on what the script should do. Can you describe your requirements to the script in as much detail as possible?

0

Sorry I have been trying to figure this out for a bit and forget sometimes that it’s out of context on a forum. I will first explain my end goal then let you know what this script is doing currently with a detailed breakdown.

End goal:
I would like to test User account “User Principal Name” uniqueness for the Forest before creating the user.
Or policy is to test the middle initial first then if that’s not unique add a 2... until its unique.
sn.givenName@domain.com, sn.initials.givenName@domain.com, sn.givenname2@domain.com...

The script below only adds the number currently. I was going to start with this then add the middle initial when the number was working.
I would also like to rename the Distinguished Name of the account if it’s not unique in case the duplicate account is in the same OU or eventually gets moved there. I do not wish to test every time the account is moved.

The script below only test the current Domain for UPN uniqueness and works except for renaming the DN. Which I assume is done by renaming the "Name" attribute before the user is created.

I am using Quest PowerShell snippets because "Get-AdmUser" did not seem to like using the "userPrincipalName" attribute.

Add-PSSnapin Quest.ActiveRoles.ADManagement

The function is from your tutorial Validate/Modify User Input Using a Script
Half of the code is from "Example 2: Automatically add a digit to the username if it is not unique"

function IsUserNameUnique($userLogonName)
{
   $user = Get-QADUser -Identity $userLogonName -erroraction silentlycontinue
   return $user -eq $Null
}

Here I need to collect information entered from the new user form to reconstruct user account attributes.

$username = $Context.GetModifiedPropertyValue("samAccountName")

Since we use a Property Pattern for the User Logon Name to assign a static UPN Suffix I need to collect these 2 attributes.
Instead of manipulating the UPN string I chose to recreate it.

$sn = $Context.GetModifiedPropertyValue("sn") 
$givenName = $Context.GetModifiedPropertyValue("givenName") 

What I am test for here is current domain uniqueness. A later version of the script will test a crossed the forest.

 $userLogonName = $Context.GetModifiedPropertyValue("userPrincipalName") 

We are not using our default domain UPN Suffix so I assign it statically here.

 $upnSuffix = "domain.com" 

I have several of these throughout the script to debug most will be removed. I have removed most in this description for clarity.

 $Context.LogMessage("The username entered was " + $username `
  + ".", "Information") 

The other half of the code is from "Example 3: Rename the user if the Full Name is not unique within the OU"
Here I am getting the DN for testing purposes. I do not think I need most of this since if the UPN is not unique I am going to just rename the "Name" attribute anyway.
This is in case the duplicate user account is in the same OU or later gets moved to the same OU. I do not wish to test every time.

 $objectDN = $Context.TargetObject.ObjectInfo.DN; 

Calling the function to test UPM

if (IsUserNameUnique($userLogonName))
{
    return
} 

Continuing on if UPN is not unique.

$uniqueUsername = $Null
$uniqueUserLogonName = $Null
$uniqueName = $Null

Generating new user attributes to make them unique. Here I am just adding a number.
I would like to try the middle initial first then add a number but was planning on adding that when this was working.

for ($i = 2; $True; $i++)
{
    $uniqueUsername = $username + $i
    # Build new UPN 
    $uniqueUserLogonName = $givenName + "." + $sn + $i + "@" + $upnSuffix

    if (IsUserNameUnique($uniqueUserLogonName))
    {
        break
    }
}

I do not think this part is needed either. It seems to be constructing a new DN for testing purposes only. I assume this since the script on your site just renames the "Name" attribute if not unique.
Please let me know if that's the case. I have included it here for testing.

objectLeaf = $objectDN.Leaf;
$objectName = $objectLeaf.Value + $i;
$objectRdn = New-Object "Softerra.Adaxes.Ldap.Rdn" $objectLeaf.Type,$objectName;
$objectDN = $objectDN.Parent;
$objectDN.AddLeaf($objectRdn);

Updating all the account properties that need to be unique.

 Update User Logon Name (pre-Windows 2000)
$Context.SetModifiedPropertyValue("samAccountName", $uniqueUsername)
# Update User Logon Name
$Context.SetModifiedPropertyValue("userPrincipalName", $uniqueUserLogonName)
#Update name for Unique DN
$Context.SetModifiedPropertyValue("name", $objectName)
0

OK, we've passed the info to our script guys. We'll update this topic as soon as they come up with something.

1 Answer

0 votes
by (18.0k points)

Hello,

Here's the script that meets your requirements. It does the following:

  1. It checks whether the UPN is unique accross all domains managed by Adaxes.
  2. If the UPN is not unique, add initials (sn.initials.givenName@domain.com)
  3. If it still not unique, try to add 2 and then increase the number until a unique UPN is achieved.
  4. Checks whether the Name property of ghe user is unique within the domain where the user is created.
  5. If it is not unique, add a digit to the end.

In the script, $upnSuffix is the custom UPN suffix that should be assigned to each new user. Modify it to your requirements.

Import-Module Adaxes
$upnSuffix = "domain.com" # TODO: modify me

#Check if UPN exists
function IsUPNUnique($userLogonName)
{
    if ($userLogonName -eq $NULL)
    {
         return $False
    }

    # Search users in all managed domain with specific UPN
    $searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
    $searcher.SearchParameters.PageSize = 500
    $searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.SearchParameters.Filter = "(&(objectCategory=user)(userPrincipalName=$userLogonName))"
    $searcher.VirtualRoot = $True

    $result = $searcher.ExecuteSearch()
    $users = $result.FetchAll()
    $result.Dispose()

    if ($users.Count -eq 0)
    {
        return $True
    }

    return $False
}

function IsPropertyNameUnique($objectName, $domainName)
{
    $user = Get-AdmUser -Filter {name -eq $objectName} -erroraction silentlycontinue -AdaxesService "localhost" -Server $domainName
    return $user -eq $Null
}

# Get the user name info
$username = $Context.GetModifiedPropertyValue("samAccountName")
$userLogonName = $Context.GetModifiedPropertyValue("userPrincipalName")
$sn = $Context.GetModifiedPropertyValue("sn")
$givenName = $Context.GetModifiedPropertyValue("givenName")

# Check if the username is unique
if (!(IsUPNUnique $userLogonName))
{
    # Add Initials and check for uniqueness
    $initals = $Context.GetModifiedPropertyValue("initials")
    if ($initals -ne $NULL)
    {
        $uniqueUserLogonName = "$sn.$initals.$givenName@$upnSuffix"
        $uniqueUsername = "$sn.$initals.$givenName"
    }

    # If the username is not unique, generate a unique one
    for ($i = 2; $True; $i++)
    {
        if (IsUPNUnique $uniqueUserLogonName)
        {
            break
        }

        $uniqueUsername = $username + $i
        # Build new UPN
        $uniqueUserLogonName = "$sn.$givenName$i@$upnSuffix"
    }

    # Update User Logon Name (pre-Windows 2000)
    $Context.SetModifiedPropertyValue("samAccountName", $uniqueUsername)
    $Context.LogMessage("The username has been changed to " + $uniqueUsername `
      + ".", "Information")

    # Update User Logon Name
    $Context.SetModifiedPropertyValue("userPrincipalName", $uniqueUserLogonName)
    $Context.LogMessage("The UPN has been changed to " + $uniqueUserLogonName `
      + ".", "Information")
}

# Get the object DN
$objectDN = $Context.TargetObject.ObjectInfo.DN;

$domainName = $Context.GetObjectDomain($objectDN.ToString())
$objectLeaf = $objectDN.Leaf
if (!(IsPropertyNameUnique $objectLeaf.Value $domainName))
{
    for ($i = 1; $True; $i++)
    {
        $objectName = $objectLeaf.Value + $i
        if (IsPropertyNameUnique $objectName $domainName)
        {
            break
        }
    }

    # Rename the object
    $Context.SetModifiedPropertyValue("name", $objectName)
    $Context.LogMessage("The name has been changed to " + $objectName `
      + ".", "Information")
}
0

I am still seeing an error when creating a second user in the same OU. I am doing a check before the user is created and my guess is that its not changing the DN. How can I catch a more detailed error from the script?

0

Hello,

What is the error that you get? Can you post a screenshot of it here?

Also, how do you create the users? Do you create them in the Administration Console, in the Web Interface or do you import them somehow?

0

We are creating the users through the web interface. With a pre-flight script in this post.

0

Hello,

We've updated the script with a check for duplicate usernames (SAMAccountNames). Replace the script that you have with the one posted here and try creating the same user. Then, post a screenshot of the Execution Log here.

Import-Module Adaxes
$upnSuffix = "domain.com" # TODO: modify me

#Check if UPN exists
function IsUPNUnique($userLogonName)
{
    if ($userLogonName -eq $NULL)
    {
         return $False
    }

    # Search users in all managed domain with specific UPN
    $searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
    $searcher.SearchParameters.PageSize = 500
    $searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.SearchParameters.Filter = "(&(objectCategory=user)(userPrincipalName=$userLogonName))"
    $searcher.VirtualRoot = $True

    $result = $searcher.ExecuteSearch()
    $users = $result.FetchAll()
    $result.Dispose()

    if ($users.Count -eq 0)
    {
        return $True
    }

    return $False
}

function IsPropertyNameUnique($objectName, $domainName)
{
    $user = Get-AdmUser -Filter {name -eq $objectName} -erroraction silentlycontinue -AdaxesService "localhost" -Server $domainName
    return $user -eq $Null
}

function IsUserNameUnique($username, $domainName)
{
   $user = Get-AdmUser $username -erroraction silentlycontinue -AdaxesService localhost -Server $domainName
   return $user -eq $Null
}

# Get the user name info
$username = $Context.GetModifiedPropertyValue("samAccountName")
$userLogonName = $Context.GetModifiedPropertyValue("userPrincipalName")
$sn = $Context.GetModifiedPropertyValue("sn")
$givenName = $Context.GetModifiedPropertyValue("givenName")
$domainName = $Context.GetObjectDomain("%distinguishedName%")

# Check if the username is unique
if (!(IsUPNUnique $userLogonName))
{
    # Add Initials and check for uniqueness
    $initals = $Context.GetModifiedPropertyValue("initials")
    if ($initals -ne $NULL)
    {
        $uniqueUserLogonName = "$sn.$initals.$givenName@$upnSuffix"
        $uniqueUsername = "$sn.$initals.$givenName"
    }

    # If the username is not unique, generate a unique one
    for ($i = 2; $True; $i++)
    {
        if (IsUPNUnique $uniqueUserLogonName)
        {
            break
        }

        $uniqueUsername = $username + $i
        # Build new UPN
        $uniqueUserLogonName = "$sn.$givenName$i@$upnSuffix"
    }

    # Check sAMAccountName
    if (!(IsUserNameUnique $uniqueUsername $domainName))
    {
        $Context.Cancel("The username (SAMAccountName property) is not unique.")
        return
    }

    # Update User Logon Name (pre-Windows 2000)
    $Context.SetModifiedPropertyValue("samAccountName", $uniqueUsername)
    $Context.LogMessage("The username has been changed to " + $uniqueUsername `
      + ".", "Information")

    # Update User Logon Name
    $Context.SetModifiedPropertyValue("userPrincipalName", $uniqueUserLogonName)
    $Context.LogMessage("The UPN has been changed to " + $uniqueUserLogonName `
      + ".", "Information")
}

# Get the object DN
$objectDN = $Context.TargetObject.ObjectInfo.DN;
$objectLeaf = $objectDN.Leaf
if (!(IsPropertyNameUnique $objectLeaf.Value $domainName))
{
    for ($i = 1; $True; $i++)
    {
        $objectName = $objectLeaf.Value + $i
        if (IsPropertyNameUnique $objectName $domainName)
        {
            break
        }
    }

    # Rename the object
    $Context.SetModifiedPropertyValue("name", $objectName)
    $Context.LogMessage("The name has been changed to " + $objectName `
      + ".", "Information")
}

Related questions

0 votes
0 answers

Hi We try to achieve a script where Adaxes replaces all umlauts in the username and mail adress and also checks for duplicate usernames. ... $email Context.SetModifiedPropertyValue("mailNickname", $username) $Context.SetModifiedPropertyValue("mail", $email)

asked Nov 11, 2020 by maca (100 points)
0 votes
0 answers

When the UPN being created is the same as an existing one except for the case. For instance, the new UPN is sally.fields but there's an existing Sally.Fields. The ... but then fails to create the AD account indicating that the UPN is not unique forestwide.

asked Jul 13, 2022 by sandramnc (870 points)
0 votes
1 answer

Hi, I want to change the default UPN suffix for user creation. We only have a single UPN suffix we use at our organization however when we create a user using the web ... We only ever want to use the @mycompany.com so a list of options isn't requried.

asked Jun 29, 2022 by PeterG (40 points)
0 votes
1 answer

When we create a user account we need our domain user account identity values (email, logon name, and UPN logon name) to be in lower case. Currently, our email, logon name, ... are in upper case. Where do we make the change so that all letters are lowercase?

asked Apr 6, 2022 by Tfarmer (160 points)
3,549 questions
3,240 answers
8,232 comments
547,814 users