James Tew
James Tew

Reputation: 11

Creating new AD users and adding them to multiple groups from CSV

I have been given the task of creating a school's worth of users (UK Secondary). The PS to create the users from a CSV, what I need to do is add the newly created users to various groups at the same time.

The code I am using is as follows

$DCName = '<DC FQDN>'

Import-Csv -Path "D:\Import.csv" |

ForEach-Object {
    $Displayname = $_.'FirstName' + " " + $_.'LastName'
    $UPN = $_.'UPN'
    $GroupName = $_.'GroupName'
    $Prop = @{
        Name = $Displayname
        DisplayName = $_.'FirstName' + " " + $_.'LastName'
        GivenName = $_.'FirstName' 
        Surname = $_.'LastName' 
        UserPrincipalName = $UPN 
        EmailAddress = $UPN 
        SamAccountName = $_.'SAM' 
        AccountPassword = (ConvertTo-SecureString $_.'Password' -AsPlainText -Force) 
        Enabled = $true 
        Path = $_.'OU' 
        ChangePasswordAtLogon = $false 
        Title = $_.'JobTitle' 
        StreetAddress = $_.'Street' 
        City = $_.'Town' 
        State = $_.'County'
        PostalCode = $_.'PostCode' 
        OfficePhone = $_.'Telephone' 
        Company = $_.'Company' 
        Department = $_.'Department' 
        HomeDrive = $_.'HomeDrive' 
        HomeDirectory = $_.'Home-Directory' 
        OtherAttributes = @{
            'extensionAttribute1'= $_.'ExtendedAttribute1'; 
            'extensionAttribute2'= $_.'ExtendedAttribute2'; 
            'extensionAttribute14'= $_.'ExtendedAttribute14'; 
            'extensionAttribute15'= $_.'ExtendedAttribute15'; 
            'proxyAddresses' = "SMTP:" + $UPN;} 
        Server = $DCName

        }

         New-ADUser @prop

         Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'

}

The user gets created with all properties correctly set. It fails with the following error

Add-ADGroupMember : Cannot find an object with identity: 'Test.User' under: 'DC=AD,DC=example,DC=uk'.
At C:\Scripts\NewUserFromCSV2.ps1:47 char:10
+          Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Test.USer:ADPrincipal) [Add-ADGroupMember], ADIdentityNotFoundException
    + FullyQualifiedErrorId : SetADGroupMember.ValidateMembersParameter,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember

It looks like the Add-ADGroupMember command can't find the user that has just been created, however, if that is the case I don't understand why.

Also at the moment, my CSV has only one group in the 'GroupName', what would be the best way to add the user to multiple groups? e.g. School-All-Staff, Teaching-Staff, Science-Teachers etc.

Thanks in advance for any help received.

Upvotes: 1

Views: 977

Answers (2)

James Tew
James Tew

Reputation: 11

I got it working as a combined script in the end and added in error checking for pre-existing users, existing staff often move to the new school that is being added to the Trust prior to its addition to our AD and get included in the list of users to create.

Also added log file creation to record newly created users and list those whose SAMAccount name already exists so we can check to see if the user does need creating or if they need moving from another School OU.

This is my final code:

#Get deafult variables to tidy up created variables at the end
$ExistingVariables = Get-Variable | Select-Object -ExpandProperty Name

#New User Code Starts Here>

#Variables not set by CSV

#Set DC name to update - prevents errors due to replication delay
$DCName = '<DC FQDN>'

#Create log files
"Users Exist in AD" | Out-File -FilePath "D:\Logs\ExistingUsers-$(get-date -f yyyyMMdd).txt" -Append
"New Users Created" | Out-File -FilePath "D:\Logs\NewUsers-$(get-date -f yyyyMMdd).txt" -Append

#Specify path and file to import
Import-Csv -Path "D:\Import.csv" |

#Iterate through each row in the CSV
ForEach-Object {

    #Set per object variables from fields in the CSV
    $DisplayName = $_.'FirstName' + " " + $_.'LastName'
    $UPN = $_.'UPN'
    $GroupName1 = $_.'GroupName1'
    $GroupName2 = $_.'GroupName2'
    $GroupName3 = $_.'GroupName3'
    $GroupName4 = $_.'GroupName4'
    $SAM = $_.'SAM'
    $Password = $_.'Password'
    $SAMTest = Get-ADUser -Filter {(sAMAccountName -eq $SAM)} -Server $DCName

    #Splatting Hash Table holds all user attribute properties set in the CSV
    $Prop = @{
        Name = $DisplayName
        DisplayName = $DisplayName
        GivenName = $_.'FirstName' 
        Surname = $_.'LastName' 
        UserPrincipalName = $UPN 
        EmailAddress = $UPN 
        SamAccountName = $_.'SAM' 
        AccountPassword = (ConvertTo-SecureString $_.'Password' -AsPlainText -Force) 
        Enabled = $true 
        Path = $_.'OU' 
        ChangePasswordAtLogon = $false 
        Title = $_.'JobTitle' 
        StreetAddress = $_.'Street' 
        City = $_.'Town' 
        State = $_.'County'
        PostalCode = $_.'PostCode' 
        OfficePhone = $_.'Telephone' 
        Company = $_.'Company' 
        Department = $_.'Department' 
        OtherAttributes = @{
            'extensionAttribute1'= $_.'ExtendedAttribute1'; 
            'extensionAttribute2'= $_.'ExtendedAttribute2'; 
            'extensionAttribute14'= $_.'ExtendedAttribute14'; 
            'extensionAttribute15'= $_.'ExtendedAttribute15'; 
            'proxyAddresses' = "SMTP:" + $UPN;} 
        Server = $DCName

        }


    #Check if SAMAccount name exists in AD and skip existing users
    if ($SAMTest -ne $Null)
        {
        #Get UPN property of the pre-existing user
        $Exist = Get-ADUser -Filter {(sAMAccountName -eq $SAM)} -Properties 'userprincipalname'

        #write UPN value to variable
        $ExistUPN = $Exist.userprincipalname

        #Update log of pre-existing users
        "$DisplayName exists with email $ExistUPN" | Out-File -FilePath "D:\Logs\ExistingUsers-$(get-date -f yyyyMMdd).txt" -Append

        #Write to screen
        Write-Host "$DisplayName already exists in AD" -ForegroundColor Red

        }
    else
        {
        #Create new user with the attribute properties collected above
        New-ADUser @prop

        #Check if group fields in CSV were populated, if true add user to group, if false skip                  
        if ($_.'GroupName1'){Add-ADGroupMember -Identity $_.'GroupName1' -Members $_.'SAM' -Server $DCName}

        if ($_.'GroupName2'){Add-ADGroupMember -Identity $_.'GroupName2' -Members $_.'SAM' -Server $DCName}

        if ($_.'GroupName3'){Add-ADGroupMember -Identity $_.'GroupName3' -Members $_.'SAM' -Server $DCName}

        if ($_.'GroupName4'){Add-ADGroupMember -Identity $_.'GroupName4' -Members $_.'SAM' -Server $DCName} 

        #Update New user log 
        "$UPN" | Out-File -FilePath "D:\Logs\NewUsers-$(get-date -f yyyyMMdd).txt" -Append

        #Write to screen
        Write-Host "User $SAM created at $((Get-Date).ToString('hh:mm'))" -ForegroundColor Green

        }
}

#End Of New User Code

#Remove variables set by script - keeps PS memory space tidy
$NewVariables = Get-Variable | Select-Object -ExpandProperty Name | Where-Object {$ExistingVariables -notcontains $_ -and $_ -ne "ExistingVariables"}
if ($NewVariables)
    {
    Write-Host "Removing the following variables:`n`n$NewVariables"
    Remove-Variable $NewVariables
    }
else
    {
    Write-Host "No new variables to remove!"
    }

I used the bit about clearing up variables because the values seemed to persist if the PowerShell session remained open and it was causing odd things to happen. I also removed the home drive attributes because the file server specified hasn't been implemented yet but management still wants the users in AD now.

For reference my import.csv looks like this

FirstName,LastName,UPN,SAM,Password,OU,JobTitle,Street,Town,County,PostCode,Telephone,Company,Department,ExtendedAttribute1,ExtendedAttribute2,ExtendedAttribute14,ExtendedAttribute15,GroupName1,GroupName2,GroupName3,GroupName4
Test,User,[email protected],Test.User,,"OU=Admin Staff,OU=User Resources,OU=School,OU=Trust Schools,DC=AD,DC=Trust,DC=org",,Street Name,TownName,County,AA11 1AA,116123,Name Of School,Name Of Trust,,Staff,,,AllStaffGroup,AdminStaffGroup,SpecialPermissionsGroup,Group4

Upvotes: 0

henrycarteruk
henrycarteruk

Reputation: 13237

As it's a bulk operation, I would just split the user creation from the group membership.

Create all the users first, then add them to the groups:

$DCName = '<DC FQDN>'
$Users = Import-Csv -Path "D:\Import.csv"

$Users | ForEach-Object {
    $Displayname = $_.'FirstName' + " " + $_.'LastName'
    $UPN = $_.'UPN'

    $Prop = @{
        ## properties as per original code ##
    }

    New-ADUser @prop
}

$Users | ForEach-Object {
    $GroupName = $_.'GroupName'
    Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'    
}

The to add the users to multiple groups:

If you've got a semicolon separated list of the groups in GroupName eg

School-All-Staff;Teaching-Staff;Science-Teachers

Split will convert this to an array then you can loop through them:

$_.'GroupName' -split ';' | ForEach-Object {
    Add-ADGroupMember $_ –Member $user.'SAM'
}

(edit: updated to semicolon as you have a csv source)

Upvotes: 1

Related Questions