Generating UPN

My history with PowerShell started with creation of new users in Active Directory. Not only is it time consuming to create users manually, but it also tends to create new support tasks because of a typo. Synchronization errors because “there’s an error” when synchronizing AD with AzureAD.

My first script was plain and simple and I added email address manually. The script then stripped out the name before @company.com and added it as both samaccountname,userprincipalname and proxyaddresses. This led to new errors where the name already was taken.

So what I did was that I wanted to create an UPN that checked Active Directory if it was already in use and if so, by logic try another combination.

I will show you an example where username is created based on GivenName, MiddleName and SurName logic and checks if available.

Function Get-EmailSafe is my way of handling special characters and normalize the email address. Örjan becoms orjan and Ågrén becomes agren.

function Get-EmailSafe([string]$str) {
    $result = $str.Trim().ToLower()
    $result = $result -replace "[åäæ]", 'a'
    $result = $result -replace "[öø]", 'o'
    $result = $result -replace "\s+", '.'
    return $result.Normalize([System.Text.NormalizationForm]::FormD) -replace '[^a-z.-]', ''
}

Function Test-AvailableIdentity runs a check in Active Directory for UserPrincipalName and ProxyAddress and returns a true or false

function Test-AvailableIdentity {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [string]$Identity

    )
 
    if ($null -eq (Get-adobject  -Ldapfilter "(|(UserPrincipalname=$identity@*)(proxyaddresses=*:$identity@*))")) {


        return $true
    }
    return $false
}

function New-UPN have three parameters GivenName, MiddleName and SurName. In this scenario users can have more than one GivenName or Surname. The scrip takes the input and saves the names splited into new variables.

The UPN is first created with 1st name in GivenName and last name in SurName and normalizes with function Get-EmailSafe and Test-AvailableIdentity and returns a userprincipalname
If the UPN is taken then runs a for loop where it tries to combine the first GivenName and last SurName with initials from additional names. It tries to find and unique UPN with 5 different combinations

function New-UPN {
    param (
        [Parameter(mandatory = $true)]
        [String]$GivenName,
        [Parameter(mandatory = $true)]
        [String]$SurName,
        [Parameter()]
        [String] $MiddleName
    )

    $gname = $GivenName -split ' '
    $sname = $SurName -split ' '
    $mname = $mname -split ' '

    $UserPrincipalName = Get-EmailSafe($gname[0] + '.' + $sname[-1])
    if (Test-AvailableIdentity -Identity $UserPrincipalName ) {
        return $UserPrincipalName
    }
    for ($i = 0; $i -le 5; $i++) {

        $names = @($gname[0])

        if ($gname.count -gt 1) {
            $names += [String]$gname[1][0]
        }

        if ((($mname.count -gt 0) -and ($mname[0] -ne '')) -and (($gname.count -eq 1) -or ($i -gt 0))) {
            $names += [String]$mname[0][0]
        }

        if (($sname.count -gt 1) -and ($i -gt 2)) {
            $names += [String]$sname[0][0]
        }
        $names += $sname[-1]

        $UserPrincipalName = Get-EmailSafe ($names -join '.')
                if (Test-AvailableIdentity -Identity $UserPrincipalName ) {
            return $UserPrincipalName
        }

       
    }

    Return $null

}

Results where first example shows how the script creates an upn with initial from the second GivenName as sandra.saluti was taken and how a normalized email would look like

PS C:\Windows\system32> New-UPN -GivenName 'Sandra Irean' -SurName Saluti
sandra.i.saluti

PS C:\Windows\system32> New-UPN -GivenName Örjan -SurName Ågrén
orjan.agren