Create new users based on department

Hi,

The code below works but i have not much experience, in total we have 7 Departments and in the script are only 2. I first asked chatgpt but what he produced did not work so i created something myself.
By as you will notice the part of the creation of a new ad users repeats in every switch so how would you guys do this?

The current rough code:

# Import users from CSV file
$CsvFilePath = "C:\tools\demo-department.csv"

if (-Not (Test-Path $CSVPath)) {
Write-Host "CSV file not found at $CSVPath"
Write-Log "ERROR: CSV file not found at $CSVPath"
exit
}

$domainname = "domain.be"

# Import the CSV file
$Users = Import-Csv -Path $CsvFilePath


foreach ($User in $Users)
{

$SurName = $User.Surname -replace '\s',''
$GivenName = $User.GivenName -replace '\s',''
$Department = $User.Department
#Write-Host $User.Department

# Create username (GivenName + Surname in lowercase)
$samAccountName = ($GivenName + '.' + $SurName).ToLower()

Switch ($User.Department) {

"Department1" {

# Define the target OU
$targetOU = "OU=Department1,OU=Users,OU=Ver,DC=ver,DC=local"

# Check if the user already exists in AD by SamAccountName
$existingUser = Get-ADUser -Filter { SamAccountName -eq $samAccountName } -ErrorAction SilentlyContinue


if (-not $existingUser) {
    # User does not exist, create the new user
    New-ADUser -SamAccountName $samAccountName `
       -UserPrincipalName ($samAccountName + "@" + $domainname) `
       -Name $User.Surname `
       -GivenName $User.GivenName `
       -Surname $User.Surname `
       -EmailAddress ($samAccountName + "@" + $domainname) `
       -AccountPassword (ConvertTo-SecureString "DefaultP@ssword1" -AsPlainText -Force) `
       -Enabled $true `
       -Path $targetOU `
       -PassThru

    Write-Host "User $samAccountName created successfully."
    Add-ADPrincipalGroupMembership -Identity $samAccountName -MemberOf "Department1", "test001", "Printers"
} else {
    Write-Host "User $samAccountName already exists. Skipping."
}



         }

         "Department2" {

            # Define the target OU
            $targetOU = "OU=Department2,OU=Users,OU=Ver,DC=ver,DC=local"
        
            # Check if the user already exists in AD by SamAccountName
            $existingUser = Get-ADUser -Filter { SamAccountName -eq $samAccountName } -ErrorAction SilentlyContinue
        
            #Write-Host "huidige gebruiker $($User.Surname) is lid van:" $User.Department
        
            if (-not $existingUser) {
                # User does not exist, create the new user
                New-ADUser -SamAccountName $samAccountName `
                   -UserPrincipalName ($samAccountName + "@" + $domainname) `
                   -Name $User.Surname `
                   -GivenName $User.GivenName `
                   -Surname $User.Surname `
                   -EmailAddress ($samAccountName + "@" + $domainname) `
                   -AccountPassword (ConvertTo-SecureString "DefaultP@ssword1" -AsPlainText -Force) `
                   -Enabled $true `
                   -Path $targetOU `
                   -PassThru
        
                Write-Host "User $samAccountName created successfully."
                Add-ADPrincipalGroupMembership -Identity $samAccountName -MemberOf "Department2", "test002", "Printers"
            } else {
                Write-Host "User $samAccountName already exists. Skipping."
            }
        
        
        
                     }
        




}

}

If the OU matches the Department you can just use a foreach (no need for the switch statement)

Just dynamically update the $targetOU to match the users department, check if it doesn’t exist and if not create user

I would keep the configuration for the departments and your code separate. You could either create a config. file per department (name each file the same as the name you get in the CSV file and import the file based on that name) or have one file and use the department name to reference the appropriate section in the file. My preference is .PSD1 files, but you could use .JSON or .XML

# departments.psd1
@{
    Department1 = @{
        TargetOU = 'OU=Department1,OU=Users,OU=Ver,DC=ver,DC=local'
        Groups   = @(
            'Department1'
            'test001'
            'Printers'   
        )
    }
    Department2 = @{
        TargetOU = 'OU=Department2,OU=Users,OU=Ver,DC=ver,DC=local'
        Groups   = @(
            'Department2'
            'test002'
            'Printers'   
        )
    }
}

Your code would then look something like this:

# Import users from CSV file
$CsvFilePath = 'C:\tools\demo-department.csv'

if (-not (Test-Path $CSVFilePath)) {
    Write-Host "CSV file not found at $CSVFilePath"
    Write-Log "ERROR: CSV file not found at $CSVFilePath"
    exit
}

# Import the CSV file
$UserList = Import-Csv -Path $CsvFilePath

# Import department data

$DepartmentList = Import-PowerShellDataFile 'C:\tools\departments.psd1'

$domainname = 'domain.be'

foreach ($User in $UserList) {

    $SurName = $User.Surname -replace '\s', ''
    $GivenName = $User.GivenName -replace '\s', ''
    $Department = $User.Department
    #Write-Host $User.Department

    # Create username (GivenName + Surname in lowercase)
    $samAccountName = ($GivenName + '.' + $SurName).ToLower()

    # Define the target OU
    $targetOU = $DepartmentList.$Department.TargetOU

    # Check if the user already exists in AD by SamAccountName
    $existingUser = Get-ADUser -Filter { SamAccountName -eq $samAccountName } -ErrorAction SilentlyContinue

    if ($existingUser) {
        Write-Host "User $samAccountName already exists. Skipping."
    }
    else {
        # User does not exist, create the new user
        $UserParams = @{
            SamAccountName    = $samAccountName
            UserPrincipalName = ($samAccountName + '@' + $domainname)
            Name              = $User.Surname
            GivenName         = $User.GivenName
            Surname           = $User.Surname
            EmailAddress      = ($samAccountName + '@' + $domainname)
            AccountPassword   = (ConvertTo-SecureString 'DefaultP@ssword1' -AsPlainText -Force)
            Enabled           = $true
            Path              = $targetOU
            PassThru          = $true
        }

        New-ADUser @UserParams
        
        Write-Host "User $samAccountName created successfully."
        
        Add-ADPrincipalGroupMembership -Identity $samAccountName -MemberOf $DepartmentList.$Department.Groups
    }
}
2 Likes

I’m with Matt on this one. When I can, I like keeping configuration data separate from PS code. When we were working on a similar task years ago we ended up with hundreds of lines of PS code to cover all of the departments, and regions, and various settings. It was a lot to look at.
Matt’s solution is elegant, and robust. Allowing you to maintain individual department settings in their own files is really nice for administration and easier for tracking changes.

Hi,

Thanks for the advice, that seems perfect and had never heard of it. Will need to do some googling i guess but i will start with the example given.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.