M. M.
M. M.

Reputation: 3

Powershell function to generate samAccountName

Im trying to write PS function which is taking FirstName and LastName as parameters and returns samaccountname. Here is the algorithm how the function should work.

Name: Richard Testing

Now look if login richard is taken. If richard is taken try richard.t. If richard.t is taken try richard.te. If richard.te is taken try richard.tes, and so on.

Below is my code. I think this can be done in a much easier way than with if loops.

$FirstName = "Richard"
$LastName = "Testing"

function Remove-StringLatinCharacters {
    Param([string]$String)
    [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String))
}

$FirstnameToUPN = (Remove-StringLatinCharacters -String $firstname).ToLower()
$LastnamenameToUPN = (Remove-StringLatinCharacters -String $lastname).ToLower()

$user = $(try {Get-ADUser $FirstnameToUPN} catch {$null})
if ($user -ne $null) {
    $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]
    $user = $(try {Get-ADUser $upn} catch {$null})
    if ($user -ne $null) {
        $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]
        $user = $(try {Get-ADUser $upn} catch {$null})
        if ($user -ne $null) {
            $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]
            $user = $(try {Get-ADUser $upn} catch {$null})
            if ($user -ne $null) {
                $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]
            } else {
                $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]
            }
        } else {
            $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]
        }
    } else {
        $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]
    }
} else {
    $upn=$FirstnameToUPN
}

Edit #1:

$upn = $FirstnameToUPN
if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
    $upn = $FirstnameToUPN+"."+$LastnamenameToUPN[0]
    if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
        $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]
        if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
            $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]
            if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
                $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]
                if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
                    $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]+$LastnamenameToUPN[4]
                    if (Get-Aduser -Filter {SamAccountName -eq $upn}) {
                        $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]+$LastnamenameToUPN[4]+$LastnamenameToUPN[5]
                    } else {
                        $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]+$LastnamenameToUPN[4]
                    }
                } else {
                    $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]
                }
            } else {
                $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]+$LastnamenameToUPN[2]+$LastnamenameToUPN[3]
            }
        } else {
            $upn = $FirstnameToUPN + "." + $LastnamenameToUPN[0]+$LastnamenameToUPN[1]
        }
    } else {
        $upn = $FirstnameToUPN+"."+$LastnamenameToUPN[0]
    }
} else {
    $upn = $FirstnameToUPN
}

Upvotes: 0

Views: 831

Answers (2)

henrycarteruk
henrycarteruk

Reputation: 13217

Rather than checking each possible username individually until you find a match, you can compare all the existing username matches to all the possible new username combinations.

This actually completes the whole operation with only a single call to Get-ADUser:

# get existing accounts that could match using wildcard '$FirstnameToUPN*'
$existingAccounts = Get-ADUser -Filter "samaccountname -like '$FirstnameToUPN*'" -properties samAccountName | Select-Object -ExpandProperty samaccountname

# create all possible samaccountname combinations
$all_samaccountname = 0..($LastnamenameToUPN.Length) | % {$FirstnameToUPN + "." + $LastnamenameToUPN.substring(0, $_)}

# change first entry from "Firstname." to just "Firstname"
$all_samaccountname.Item(0) = $all_samaccountname.Item(0).TrimEnd('.')

# remove existing accounts from the possible samaccountname combinations
# then select the first available samaccountname match
$upn = $all_samaccountname | Where-Object { $existingAccounts -notcontains $_ } | Select-Object -First 1

# error if there's no matches and no username combination available
if (!($upn)) {
    Write-Error "No possible upn combinations available for: $firstname $lastname"
}

Upvotes: 1

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200203

You start with just the first name, then append characters from the last name until the resulting account name does not exists in AD or you run out of characters:

$acct = $FirstnameToUPN
$cnt  = 1
while (-not (Get-ADUser -Filter "SamAccountName -eq '$acct'") -and $cnt -le $LastnameToUPN.Length) {
    $acct = "${FirstnameToUPN}." + $LastnameToUPN.Substring(0, $cnt)
    $cnt++
}

if (Get-ADUser -Filter "SamAccountName -eq '$acct'") {
    Write-Error "No unused account name found for ${firstname} ${lastname}."
}

Upvotes: 2

Related Questions