Powershell Script to generate unique username

Freddie 21 Reputation points
2022-09-04T18:26:30.727+00:00

What I am trying to do is create unique usernames using the first initial of first name, and last name(complete last name). If a user already exists, then it should take first 2 initials of first name and complete last name and so on. If a characters in first name ends, then it should increment it with number. For example:
User 1: John Smith - JSmith
User 2: John Smith - JoSmith
User 3: John Smith - JohSmith
User 4: John Smith - JohnSmith
User 5: John Smith - JohnSmith1
User 6: John Smith - JohnSmith2

And so on.
Currently, I have written below script, which increments till it reaches last character of first name, but throws an error when it has to increment with a number

Import-Module ActiveDirectory
function CreateUsername($csvPath) {
$users = Import-Csv -path "C:\Users\Administrator\Desktop\Bulkload\Input.csv"
$resultsArray = @()
foreach ($user in $users) {
$firstname = $user.FirstName
$lastname = $user.LastName
$i = 1
$logonnameCounter = 1
$logonname = $firstname.substring(0,$i) + $lastname
$existingUserName = $firstname + $lastname

Displaying Account information.

Write-Host "======================================="
Write-Host
Write-Host "Firstname: $firstname"
Write-Host "Lastname: $lastname"
Write-Host "Logon name: $logonname"
$UsernameCreationStatus=""
$ErrorMessage=""
DO {
DO {
If (($(Get-ADUser -Filter {SamAccountName -eq $logonname}) -and ($(Get-ADUser -Filter {SamAccountName -ne $existingUserName} ))))
{
$i++
$logonname = $firstname.substring(0,$i) + $lastname
Write-Host
Write-Host
Write-Host "Changing Logon name to" $logonname.toUpper() -ForegroundColor:Green
Write-Host
$taken = $true
sleep 5
} else {
$taken = $false
}
} Until ($taken -eq $false)
} while ($(Get-ADUser -Filter {SamAccountName -eq $existingUserName} -EA 0)) {
$logonnameCounter++
$logonname = $existingUserName + $logonnameCounter
Write-Host
Write-Host
Write-Host "Changing Logon name to" $logonname.toUpper() -ForegroundColor:Green
Write-Host
$taken = $true
sleep 5
}
$logonname = $logonname.toLower()

Displaying account information that is going to be used.

Write-Host "======================================="
Write-Host
Write-Host "Firstname: $firstname"
Write-Host "Lastname: $lastname"
Write-Host "Logon name: $logonname"

$resultsArray += [PSCustomObject]@{
FirstName=$user.FirstName;
LastName=$user.LastName
samAccountname=$logonname

    }  

} $resultsArray | Export-Csv "C:\Users\Administrator\Desktop\Bulkload\Output-Result.csv"
}

CreateUsername Input.csv

Output:

=======================================

Firstname: Test
Lastname: User
Logon name: TUser

Thank you!
Changing Logon name to TEUSER

Changing Logon name to TESUSER

Changing Logon name to TESTUSER

Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location
within the string.
Parameter name: length"
At line:26 char:7

  • ... $logonname = $firstname.substring(0,$i) + $lastname
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • CategoryInfo : NotSpecified: (:) [], MethodInvocationException
  • FullyQualifiedErrorId : ArgumentOutOfRangeException

Changing Logon name to TESTUSER

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,344 questions
0 comments No comments
{count} votes

Accepted answer
  1. MotoX80 31,556 Reputation points
    2022-09-06T13:38:21.203+00:00

    You don't need all that.

    Updated to include csv export.

    $users = Import-Csv -path "C:\Users\Administrator\Desktop\Bulkload\Input.csv"  
    $resultsArray = @()  
    foreach ($user in $users) {  
        $firstname = $user.FirstName  
        $lastname = $user.LastName  
        $i = 1                        # pointer for first name   
        $LogonNameCounter = 0  
        $LogonNameSuffix = ""     # no trailing number while looping thru first name   
        While($true) {  
            $logonname = $firstname.substring(0, $i) + $lastname + $LogonNameSuffix  
            "Looking for $logonname"  
          
            # Call AD here  
            If ($(Get-ADUser -Filter {SamAccountName -eq $logonname})) {  
              "That account exists."   
                "Try the next name."  
            } else {  
                "That account does not exist."  
                " Use this name. Add it to the results."  
                $resultsArray += [PSCustomObject]@{  
                         FirstName=$user.FirstName;  
                         LastName=$user.LastName  
                         samAccountname=$logonname  
                }  
                break                   # exit this loop.  Maybe set a flag to indicate that how to proceed.   
            }  
                      
            if ($i -eq $firstname.Length) {  
                $logonNameCounter++   
                $LogonNameSuffix = $logonNameCounter  
            } else {  
                $i++   
            }  
            if ($logonNameCounter -gt 10) {  
                "We exceeded the max number to use. Something is wrong."  
                break                   # exit the while loop   
            }  
        }  
        "Done with this user."  
    }   
    $resultsArray | Export-Csv "C:\Users\Administrator\Desktop\Bulkload\Output-Result.csv"  
    
    
      
    
    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. MotoX80 31,556 Reputation points
    2022-09-04T20:45:03.637+00:00

    How about doing it like this?

            $firstname = "John"  
            $lastname = "Smith"  
            $i = 1                        # pointer for first name   
            $LogonNameCounter = 0  
            $LogonNameSuffix = ""     # no trailing number while looping thru first name   
            While($true) {  
                $logonname = $firstname.substring(0, $i) + $lastname + $LogonNameSuffix  
                "Looking for $logonname"  
      
                # Call AD here  
                # if not found, we can use this name  
                # do whatever here and then use break to exit the while loop and go on to the next user    
                  
                if ($i -eq $firstname.Length) {  
                    $logonNameCounter++   
                    $LogonNameSuffix = $logonNameCounter  
                } else {  
                    $i++   
                }  
                if ($logonNameCounter -gt 10) {  
                    "We exceeded the max number to use. Something is wrong."  
                    break                   # exit the while loop   
                }  
            }  
            "Done with this user."  
    

  2. Rich Matheisen 44,541 Reputation points
    2022-09-04T21:24:39.357+00:00

    What's missing from the answer @MotoX80 posted, is what's not stated by you: Is it possible that accounts like "JohnSmith2" are already present in your AD?

    If they do, then in addition to the answer from @MotoX80 , you'll have to start adding an incrementing value to the end of the account name you're trying to verify is not present once you reach the end of the user's first name, and start using just the users complete first and last names as the base.

    Two other points:

    1. When you post code, please use the "Code Sample" editor. It's the icon with the "101 010" graphic (it's the 5th from the left on the format bar).
    2. If you're getting an exception, post the text of the error message. That will contain what the error is, and where in the script the error occurred.