Powershell to Copy a User, but fill in details from CSV

Hi,

I want to create a Powershell Script that creates New Users from a CSV file. This I have done.
However, I want to be able to copy the Group Memberships from another User to these New Users. Preferably, a column in the CSV to detail which User to copy from, since we have a number of Template Users with various permissions.

I have the following two scripts that - when run - kind of do what I want. The first Script pulls the details from the CSV file:-
#Import the PowerShell module containing AD CMDLETS
Import-Module ActiveDirectory

#Read a CSV File with the User or Group details and create an account in AD for each entry
Function Create-ADAccountsFromCSV {
    Param (
        [parameter(Mandatory=$true)][string]$CSVPath,
        [parameter(Mandatory=$true)][string]$Type,
        [parameter(Mandatory=$true)][string]$OrgUnit
        )
    if (($Type -ne "Group") -and ($Type -ne "User"))
    {
        Throw New-Object System.ArgumentException("Type parameter must be specified as either 'User' or 'Group'.")
    }

    #Read the CSV File
    $csvData = Import-Csv $CSVPath
    foreach ($line in $csvData) {
 #Create a hash table of the account details
        $accountTable = @{
            'givenName'=$line.FirstName
            'sn'= $line.LastName
            'displayName'= $line.DisplayName
            'sAMAccountName'= $line.sAMAccountName
            'password' = $line.Password
            'description' = $line.Description
            'office' = $line.Office
            'officephone' = $line.Phone
            'emailaddress' = $line.Email
            'streetaddress' = $line.Address1
            'pobox' = $line.Address2
            'city' = $line.City
            'state' = $line.County
            'postalcode' = $line.Postcode
            'department' = $line.Department
            'company' = $line.Company
            'group1' = $line.Group1
            'group2' = $line.Group2


            'ou' = $OrgUnit  

        }
        if ($Type -eq "User")
        {
            #Call the function to create a User Account
            CreateUser -AccountInfo $accountTable
        }
        if ($Type -eq "Group")
        {
            #Call the function to create a Group Account
            CreateGroup -AccountInfo $accountTable
            
            #Get New Group
            $groupFilterString = "samAccountName -like `"" + $line.sAMAccountName + "`""
            $group = Get-ADGroup -Filter $groupFilterString
            #Walk through each member column associated with this group
            $memberColumnNumber = 1
            $memberColumn = "Member" + $memberColumnNumber
            #While a member column still exists, ad the value to a Group
            while ($line.$memberColumn)
            {
                #Check if User is already a member of the Group
                $member = Get-ADGroupMember $group | Where { $_.samAccountNmae -eq $line.$memberColumn }
                #If not already a member of the Group, add the User to the Group
                IF ($member -eq $null)
                {
                    Write-Host "Adding" $line.$memberColumn "as a Member of the Group" $group.Name
                    try
                    {
                        $userFilterString = "samAccountName -like `"" + $line.$memberColumn + "`""
                        $user = Get-ADUser -Filter $userFilterString
                        Add-ADGroupMember -Identity $group -Members $user

                    }
                    Catch
                    {
                        Write-Host "There was a problem adding" $line.$memberColumn "as a member to the Group" $group.Name "-" $_ -ForegroundColor Red
                    }
                }
                ELSE
                {
                    Write-Host "User" $line.$memberColumn "was not added to the Group" $group.Name "as this User was already a member of that Group" -ForegroundColor Blue
                }
                $memberColumnNumber = $memberColumnNumber + 1
                $memberColumn = "Member" + $memberColumnNumber
            }
        }
    }
}

#Create an Active Directory User
Function CreateUser {
    Param($AccountInfo)
        TRY
        {
            #Check to see if the User Account already exists
            $userFilterString = "samAccountName -like `"" + $AccountInfo['sAMAccountName'] + "`""
            $user = Get-ADUser -Filter $userFilterString
            #If User Account does not already exist, create it
            
           
Function CopyFrom {
    $GroupBool = Read-Host "Copy group membership from existing user? Y/N. Default is N"
    if ($GroupBool.ToLower() -eq "y"){
        $UserToCopyFrom = Read-Host "Enter the user account to copy from."
        return (Get-ADUser $UserToCopyFrom -Properties MemberOf).MemberOf
    }
}
 cls

$Name = Read-Host "Enter the User Name for the New User"
$Groups = CopyFrom
 
#This is a very basic account creation. You should probably set Surname, First Name, Full Name, Department, etc. Tailor this to your environment.
   if ($user -eq $null)    
            {
                Write-Host "Creating User Account:" $AccountInfo['sAMAccountName']
            #Create the user account object
            New-ADUser -SamAccountName $AccountInfo['sAMAccountName'] `
                       -Name $AccountInfo['displayName'] `
                       -DisplayName $AccountInfo['displayName'] `
                       -GivenName $AccountInfo['givenName'] `
                       -Surname $AccountInfo['sn'] `
                       -Path $AccountInfo['ou'] `
                       -Office $AccountInfo['office'] `
                       -OfficePhone $AccountInfo['officephone'] `
                       -EmailAddress $AccountInfo['emailaddress'] `
                       -StreetAddress $AccountInfo['streetaddress'] `
                       -POBox $AccountInfo['pobox'] `
                       -State $AccountInfo['state'] `
                       -PostalCode $AccountInfo['Postalcode'] `
                       -City $AccountInfo['City'] `
                       -Title $AccountInfo['description'] `
                       -Department $AccountInfo['department'] `
                       -Company $AccountInfo['company'] `
                       -ChangePasswordAtLogon $true `
                       -AccountPassword (ConvertTo-SecureString $AccountInfo['password'] -AsPlainText -Force) `
                       -Description $AccountInfo['description'] `
                       -Enabled $true

            #Set "User must change password" to TRUE after User has been created.
            #For some reason, if you set to TRUE above it doesn't work - presumably a bug
            #To set this option to TRUE, de-comment the 2 lines below (remove the hashtag symbols)
            #     $user = Get-ADUser -Filter $userFilterString
            #     Set-ADUser $user -ChangePasswordAtLogon $true
        }
        ELSE
        {
            Write-Host "User" $AccountInfo['sAMAccountname'] "was not created as this User Account already exists" -ForegroundColor Cyan
        }
    }
    CATCH
    {
        Write-Host "There was a problem creating a User Account:" $AccountInfo['sAMAccountName']  "-" $_ -ForegroundColor Red
    }
 
#This will be empty if the user opted not to  copy existing membership.
ForEach ($g in $groups){
    #This adds the group membership after the account is created.
    Add-ADGroupMember $g $name
}

Open in new window


This code actually creates the Users and puts them in the OU:-
#NOTE: YOU MUST RUN "PREPARE TO CREATE USERS AND GROUPS FROM CSV.PS1" BEFORE YOU RUN THIS SCRIPT
#IF YOU GET THE ERROR:
    #Create-ADAccountsFromCSV : The term 'Create-ADAccountsFromCSV' is not recognized as the name of 
    #a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path
    # was included, verify that the path is correct and try again.
#THEN YOU'VE NOT RUN THAT COMMAND FIRST!!!!!

#Create Users from the CSV File in C:\CSVs\NewUsers.csv - you need to edit the OrgUnit entry.
#EXAMPLE:
#Create-ADAccountsFromCSV -CSVPath "C:\CSVs\NewUsers.csv" -OrgUnit "OU=Staff,OU=Users,OU=Waterloo Lodge,OU=Education,DC=ACE,DC=Local" -Type "User"

Create-ADAccountsFromCSV -CSVPath "C:\CSVs\NewUsers.csv" -OrgUnit "OU=Users,OU=OFFICE,OU=OU,DC=DOMAIN,DC=Local" -Type "User"

Open in new window


However, if you run these one after the other, you get asked for the new User Name, which is fine(ish) but it requires you putting the names in one by one. It also asks who the Groups should be copied from - which I can probably live with!

is it possible to do this all in one go? For the script to go through the CSV file and create the New User(s) copying the Group Memberships from another User - preferably also specified in the CSV (which will obviously need updating!)? Could it even be done to copy the OU from the existing User to the New one?

I've attached a basic CSV file, too!

Thank you!NewUsers.csv
winstallaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Nadav SolomonCommented:
First add "User2CopyFrom" and "copyGroups" to your csv,
I didn't touch the first script, i think you better stick with putting the ou in the first one (less mistakes).
my changes are encapsulated in "############### changes ########################## "
then use the following script:

#Import the PowerShell module containing AD CMDLETS
Import-Module ActiveDirectory

#Read a CSV File with the User or Group details and create an account in AD for each entry
Function Create-ADAccountsFromCSV {
    Param (
        [parameter(Mandatory=$true)][string]$CSVPath,
        [parameter(Mandatory=$true)][string]$Type,
        [parameter(Mandatory=$true)][string]$OrgUnit
        )
    if (($Type -ne "Group") -and ($Type -ne "User"))
    {
        Throw New-Object System.ArgumentException("Type parameter must be specified as either 'User' or 'Group'.")
    }

    #Read the CSV File
    $csvData = Import-Csv $CSVPath
    foreach ($line in $csvData) {
 #Create a hash table of the account details
        $accountTable = @{
            'givenName'=$line.FirstName
            'sn'= $line.LastName
            'displayName'= $line.DisplayName
            'sAMAccountName'= $line.sAMAccountName
            'password' = $line.Password
            'description' = $line.Description
            'office' = $line.Office
            'officephone' = $line.Phone
            'emailaddress' = $line.Email
            'streetaddress' = $line.Address1
            'pobox' = $line.Address2
            'city' = $line.City
            'state' = $line.County
            'postalcode' = $line.Postcode
            'department' = $line.Department
            'company' = $line.Company
            'group1' = $line.Group1
            'group2' = $line.Group2


            'ou' = $OrgUnit 
            ############### changes ##########################
            'user2copyfrom' = $line.User2CopyFrom
            'copyGroups' = $line.copyGroups
            ############### changes ########################## 

        }
        if ($Type -eq "User")
        {
            #Call the function to create a User Account
            CreateUser -AccountInfo $accountTable
        }
        if ($Type -eq "Group")
        {
            #Call the function to create a Group Account
            CreateGroup -AccountInfo $accountTable
            
            #Get New Group
            $groupFilterString = "samAccountName -like `"" + $line.sAMAccountName + "`""
            $group = Get-ADGroup -Filter $groupFilterString
            #Walk through each member column associated with this group
            $memberColumnNumber = 1
            $memberColumn = "Member" + $memberColumnNumber
            #While a member column still exists, ad the value to a Group
            while ($line.$memberColumn)
            {
                #Check if User is already a member of the Group
                $member = Get-ADGroupMember $group | Where { $_.samAccountNmae -eq $line.$memberColumn }
                #If not already a member of the Group, add the User to the Group
                IF ($member -eq $null)
                {
                    Write-Host "Adding" $line.$memberColumn "as a Member of the Group" $group.Name
                    try
                    {
                        $userFilterString = "samAccountName -like `"" + $line.$memberColumn + "`""
                        $user = Get-ADUser -Filter $userFilterString
                        Add-ADGroupMember -Identity $group -Members $user

                    }
                    Catch
                    {
                        Write-Host "There was a problem adding" $line.$memberColumn "as a member to the Group" $group.Name "-" $_ -ForegroundColor Red
                    }
                }
                ELSE
                {
                    Write-Host "User" $line.$memberColumn "was not added to the Group" $group.Name "as this User was already a member of that Group" -ForegroundColor Blue
                }
                $memberColumnNumber = $memberColumnNumber + 1
                $memberColumn = "Member" + $memberColumnNumber
            }
        }
    }
}

#Create an Active Directory User
Function CreateUser {
    Param($AccountInfo)
        TRY
        {
            #Check to see if the User Account already exists
            $userFilterString = "samAccountName -like `"" + $AccountInfo['sAMAccountName'] + "`""
            $user = Get-ADUser -Filter $userFilterString
            #If User Account does not already exist, create it
            
           
Function CopyFrom {
    ############### changes ########################## 
    param(
        [string]$GroupBool,
        [string]$UserToCopyFrom
    )
    #$GroupBool = Read-Host "Copy group membership from existing user? Y/N. Default is N"
    ############### changes ########################## 
    if ($GroupBool.ToLower() -eq "y"){
        ############### changes ##########################
        #$UserToCopyFrom = Read-Host "Enter the user account to copy from."
        ############### changes ##########################
        return (Get-ADUser $UserToCopyFrom -Properties MemberOf).MemberOf
    }
}
 cls
############### changes ########################## 
$Name = $AccountInfo['sAMAccountName'] #Read-Host "Enter the User Name for the New User"
$Groups = CopyFrom -GroupBool $AccountInfo['copyGroups'] -UserToCopyFrom $AccountInfo['user2copyfrom']
############### changes ########################## 
 
#This is a very basic account creation. You should probably set Surname, First Name, Full Name, Department, etc. Tailor this to your environment.
   if ($user -eq $null)    
            {
                Write-Host "Creating User Account:" $AccountInfo['sAMAccountName']
            #Create the user account object
            New-ADUser -SamAccountName $AccountInfo['sAMAccountName'] `
                       -Name $AccountInfo['displayName'] `
                       -DisplayName $AccountInfo['displayName'] `
                       -GivenName $AccountInfo['givenName'] `
                       -Surname $AccountInfo['sn'] `
                       -Path $AccountInfo['ou'] `
                       -Office $AccountInfo['office'] `
                       -OfficePhone $AccountInfo['officephone'] `
                       -EmailAddress $AccountInfo['emailaddress'] `
                       -StreetAddress $AccountInfo['streetaddress'] `
                       -POBox $AccountInfo['pobox'] `
                       -State $AccountInfo['state'] `
                       -PostalCode $AccountInfo['Postalcode'] `
                       -City $AccountInfo['City'] `
                       -Title $AccountInfo['description'] `
                       -Department $AccountInfo['department'] `
                       -Company $AccountInfo['company'] `
                       -ChangePasswordAtLogon $true `
                       -AccountPassword (ConvertTo-SecureString $AccountInfo['password'] -AsPlainText -Force) `
                       -Description $AccountInfo['description'] `
                       -Enabled $true

            #Set "User must change password" to TRUE after User has been created.
            #For some reason, if you set to TRUE above it doesn't work - presumably a bug
            #To set this option to TRUE, de-comment the 2 lines below (remove the hashtag symbols)
            #     $user = Get-ADUser -Filter $userFilterString
            #     Set-ADUser $user -ChangePasswordAtLogon $true
        }
        ELSE
        {
            Write-Host "User" $AccountInfo['sAMAccountname'] "was not created as this User Account already exists" -ForegroundColor Cyan
        }
    }
    CATCH
    {
        Write-Host "There was a problem creating a User Account:" $AccountInfo['sAMAccountName']  "-" $_ -ForegroundColor Red
    }
 
#This will be empty if the user opted not to  copy existing membership.
ForEach ($g in $groups){
    #This adds the group membership after the account is created.
    Add-ADGroupMember $g $name
}

Open in new window

0
winstallaAuthor Commented:
Nadav,

I had to add a closing } to the end of the script, but otherwise it seems to work - apart from that I'm not sure what to put in the CopyGroups field in the CSV file?

The User was created without asking the question, but the AD Group Memberships did not copy. I have tried putting the User whose Groups I want to copy in both the CopyGroups and User2CopyFrom fields, but this did not help.

Thank you for your assistance!
0
Nadav SolomonCommented:
in the copyGroups put y or n
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
What were the top attacks of Q1 2018?

The Threat Lab team analyzes data from WatchGuard’s Firebox Feed, internal and partner threat intelligence, and a research honeynet, to provide insightful analysis about the top threats on the Internet. Check out our Q1 2018 report for smart, practical security advice today!

winstallaAuthor Commented:
That simple! Thank you again!
0
Nadav SolomonCommented:
User2CopyFrom put the samaccountname of the user to copy groups from.
0
Nadav SolomonCommented:
Glad I could help, and thanks for the feedback.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.