🐍 Powershell : Creating Users

 All, another requirement to create some new users accounts via scripting to the following requirements:

  1. UPN set correctly for domain
  2. Login ID set correctly for domain
  3. Member of the default groups
  4. Added to a certain OU
  5. Manager set correctly
Scripts are obviously quicker that users, so when you have lots of people to create then this is way forward to lets get started with the script.

The script

You only need to modify the items in bold to your requirements:

# Import the Active Directory module
Import-Module ActiveDirectory

# Read user information from a CSV file
$users = Import-Csv -Path "users.csv"

# Define the list of groups
$groups = @("Group1", "Group2", "Group3", "Group4")

# Loop through each user in the CSV
foreach ($user in $users) {
    $firstName = $user.FirstName
    $lastName = $user.LastName
    $username = $user.Username
    $managerName = $user.Manager
    $ou = $user.OU

    # Generate a password with a word and 2 special characters repeated three times
    $password = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 15 | ForEach-Object {[char]$_})

    # Set the User Principal Name (UPN)
    $upn = "$firstName.$lastName@pokebearswithsticks.com"

    # Create the user
    New-ADUser -Name "$firstName $lastName" -GivenName $firstName -Surname $lastName -SamAccountName $username -UserPrincipalName $upn -AccountPassword (ConvertTo-SecureString -AsPlainText $password -Force) -Enabled $true -Path $ou -Manager $managername

 # Add the user to specified groups
    foreach ($group in $groups) {
        Add-ADGroupMember -Identity $group -Members $username
    }

    # Output the user details and password
    Write-Host "User created: $firstName $lastName"
    Write-Host "Username: $username"
    Write-Host "Password: $password `n"
}

Login ID not the UPN

If you require the login ID or the pre-windows 2000 login name 

Then you will need to add the variable 

# Set the Common Name (CN) to the username
    $cn = $username

The you will need to update this section:

New-ADUser from -Name "$firstName $lastName"

To this:

New-ADUser -Name $cn

The CSV File

This is required for the script as needs to follow the format with the data below:

FirstName,LastName,Username,Manager,OU

That should look something like this, each value is separated with a comma (hence the CSV file)


Password Generation

This took some turns first I started with a wordlist which failed to read correctly, then I came across across another way to do this:

 # Generate a password with a word and 2 special characters repeated three times
    $password = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 15 | ForEach-Object {[char]$_})

Which can be broken down here for those interested:
  1. `(48..57)`: This part represents a range of ASCII values from 48 to 57, which corresponds to the characters '0' to '9'. This range includes digits.
  2. `(65..90)`: This part represents a range of ASCII values from 65 to 90, which corresponds to the uppercase letters 'A' to 'Z'.
  3. `(97..122)`: This part represents a range of ASCII values from 97 to 122, which corresponds to the lowercase letters 'a' to 'z'.
  4. `(48..57) + (65..90) + (97..122)`: These ranges are concatenated together using the `+` operator to create a list of ASCII values that includes digits, uppercase letters, and lowercase letters.
  5. `-join`: This is used to join the elements in the list into a single string without any separator.
So, when you run this code, it generates a random password by selecting characters from the ranges mentioned above, including digits, uppercase letters, and lowercase letters. The resulting password will be a combination of these characters.

Executing the Script

Once you run the script it will return something like this, and if you take a look in the OU you specified you will notice that all the accounts are there, setup as per the requirements in the CSV file.

User created: Mia Crumplehorn
Username: httttx8
Password: KXQGtRT2JOvqYag

User created: Charlotte Pumpernickel
Username: httttx9
Password: xG3H67rwyCBtNei

User created: Evelyn Wobbleberry
Username: httttx12
Password: sU1427drhQXgnxC

User created: Abigail Blunderbuss
Username: httttx13
Password: Uwd5RToeMi9FEgI

User created: Emily Higgledy-Piggledy
Username: httttx14
Password: Rr4fjxGcvJPB3o1

Login ID Generation

If you wish to auto generate the login ID, as currently that is defined in the CSV then you can do that by removing the "Username" field from the CSV file so it looks like this:

FirstName,LastName,Manager,OU

Then you can use this code, the will take the first letter of the first name, then 5 letters from the surname and find a unique number for the end of that username, this will form the login ID, then means Lee.Croucher as the UPN start will be LCrouc1 as the Login ID.

Script will automatically detect if that username is being used by someone else and will assign it the next number in the list that’s not used, this means if you have the Username of LCrouc1 it will automatically use LCrouc2, for more information see below the script.

# Import the Active Directory module
Import-Module ActiveDirectory

# Read user information from a CSV file
$users = Import-Csv -Path "users.csv"

# Define the list of groups
$groups = @("Domain Users", "Scripted-Users", "Proxy-Access", "CraftyBearClaws", "HelpmeRhonda")

# Function to find the next available username with a unique number
function Get-NextUniqueUsername {
    param (
        [string]$baseUsername
    )

    $counter = 1
    $available = $false

    while (-not $available) {
        $proposedUsername = "$baseUsername$counter"
        if (-not (Get-ADUser -Filter {SamAccountName -eq $proposedUsername})) {
            $available = $true
            return $proposedUsername
        }
        $counter++
    }
}

# Loop through each user in the CSV
foreach ($user in $users) {
    $firstName = $user.FirstName
    $lastName = $user.LastName
    $managerName = $user.Manager
    $ou = $user.OU

    # Generate a password with a word and 2 special characters repeated three times
    $password = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 25 | ForEach-Object {[char]$_})

    # Create a base username using the first letter of the first name and the first 5 letters of the last name
    $baseUsername = ($firstName.Substring(0, 1) + $lastName.Substring(0, [Math]::Min(5, $lastName.Length))).ToLower()

    # Find the next available username by appending a unique number
    $username = Get-NextUniqueUsername -baseUsername $baseUsername

    # Set the User Principal Name (UPN)
    $upn = "$firstName.$lastName@pokebearswithsticks.com"

    # Set the Common Name (CN) to the username
    $cn = $username

    # Create the user
    New-ADUser -Name $cn -GivenName $firstName -Surname $lastName -DisplayName "$firstName $lastName" -SamAccountName $username -UserPrincipalName $upn -AccountPassword (ConvertTo-SecureString -AsPlainText $password -Force) -Enabled $true -Path $ou -Manager $managerName

    # Add the user to specified groups
    foreach ($group in $groups) {
        Add-ADGroupMember -Identity $group -Members $username
    }

    # Output the user details and password
    Write-Host "User created: $firstName $lastName"
    Write-Host "Username: $username"
    Write-Host "Password: $password `n"
}

The code that find the next username is this code below:

# Function to find the next available username with a unique number
function Get-NextUniqueUsername {
    param (
        [string]$baseUsername
    )

    $counter = 1
    $available = $false

    while (-not $available) {
        $proposedUsername = "$baseUsername$counter"
        if (-not (Get-ADUser -Filter {SamAccountName -eq $proposedUsername})) {
            $available = $true
            return $proposedUsername
        }
        $counter++
    }
}

It works like this, if anyone would like to know the "why"....
  1. The function takes one parameter, $baseUsername, which represents the base username that you want to make unique.

  2. Inside the function, there is a $counter variable initialized to 1 and an $available variable initialized to false. The $counter variable keeps track of the unique number that will be appended to the base username, and $available is used to determine whether a unique username is found.

  3. The function enters a while loop that continues until an available (unique) username is found. The loop checks for uniqueness by attempting to construct a new username by appending the current value of $counter to the base username.

  4. Inside the loop, the $proposedUsername is formed by concatenating the $baseUsername with the current value of $counter.

  5. The script then uses the Get-ADUser cmdlet to query Active Directory for a user with the same SamAccountName as the proposed username. It does this by using a filter that checks if there are any existing users with the same username. The -not operator is used to negate the result, so if there are no users with the same username, it returns true.

  6. If Get-ADUser returns true, indicating that the proposed username is not already in use, the $available variable is set to true, and the function returns the proposed username as a unique username.

  7. If the proposed username is found to be in use (i.e., Get-ADUser returns false), the $counter is incremented, and the loop continues to the next iteration to check the next candidate username.

  8. This process repeats until an available username is found, at which point the function returns the unique username.
Any that is all for this post, all hail megatron.
Previous Post Next Post

Ω†Ω…ΩˆΨ°Ψ¬ Ψ§Ω„Ψ§ΨͺΨ΅Ψ§Ω„