# Create ad user from CSV

**URL:** <https://forums.powershell.org/t/create-ad-user-from-csv/17387>\
**Category:** PowerShell Help\
**Created:** [August 23, 2021, 9:28am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387 "2021-08-23T09:28:11Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 23, 2021, 9:28am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/1 "2021-08-23T09:28:11Z")

</div>

HI my name is Gianluca and I’m a Newbie in powershell scripting.  
I managed to create almost all the automations I need, but unfortunately I am stuck in some steps that I can’t solve, can you help me. I try to explain:  
[Here you will find the script and the CSV file](https://drive.google.com/drive/folders/19Eq2rZHGq3gW2FZTh4TjlakNAT2yvC0M?usp=sharing)

what I’m not capable of:

Row 58: set the manager field in AD and handle if the field is null, the data is not mandatory  
Row 59: set the Primary group ID in AD user  
Row 60: set the AccountExpirationDate in AD and handle if the field is null, the data is not mandatory  
Row 61: Set the MemberOf field in AD with the CN delimitet by “,”  
Row 71: the pager field is populated intermittently, I don’t understand if the syntax is correct

thanks to anyone who can help me  
Gianluca

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 23, 2021, 10:28am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/2 "2021-08-23T10:28:03Z")

</div>

Gianluca,  
Welcome to the forum. 👋🏽

Row 58 and 60:

That’s simple. First create the hashtable without the optional attributes. And add them only when the according variables are filled.

```auto
$userParams = @{
    SamAccountName = $Username
    UserPrincipalName = "$Username@reggiocity.it"
    Name = $Username
}
if ($Manager) {
    $userParams.Manager = $Manager
}
if ($AccountExpirationDate) {
    $userParams.AccountExpirationDate = $AccountExpirationDate
}

```

Row 59:  
That’s actually not necessary in the vast majority of the cases I know of. The default primary group is the DomainUsers. If you really need to set it you can output the newly created user account with providing the parameter -PassThru for the New-ADUser cmdlet and use

```auto
Set-ADUser -Replace @{PrimaryGroupID="513"}

```

to set the PrimaryGroupID attribute for the newly created user.

Row 61:  
I’d recommend to use

> **[Add-ADPrincipalGroupMembership (ActiveDirectory)](https://docs.microsoft.com/en-us/powershell/module/activedirectory/add-adprincipalgroupmembership?view=windowsserver2019-ps)**
>
> Use this topic to help manage Windows and Windows Server technologies with Windows PowerShell.

It is made for adding a user to one or more groups with one command.

Row 71:  
I never used this attribute so I don’t know either. Does it work the way you do? 😉

BTW:  
You code line 14 to 32 are unnecessary. You can use pipeline variable type ( $\_.Something) directly for your splatting hashtable. 😉

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 23, 2021, 2:54pm UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/3 "2021-08-23T14:54:26Z")

</div>

Hi Olaf, thanx for your help but i can’t get it to work.  
Many of the csv field must be compiled, so I can’t understand what i’ve to do.

Row 58 and 60  
I entered the code you indicated at the end of the script but I get an error

Row 59  
I don’t understand what -Passwtru mean and where the csv field for the primaryGroupID is, ad es :  
Set-ADUser -Replace @{PrimaryGroupID=‘$PrimaryGroupID’}

Row 71  
No, id doesn’t work as i expected, also in this case I need the “pager” field indicated in the csv to be inserted in the new AD user

BTW  
Mi dispiace ma non ho capito ☹  
I was thinking of mapping the csv fields before doing anything in order to have the variables always available  
I usually do scripts in VBScript, but in this case powershell seemed like the best choice. Unfortunately, I am struggling with my poor preparation on this subject. Please forgive me for the questions I ask. Thanks

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 23, 2021, 3:31pm UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/4 "2021-08-23T15:31:58Z")

</div>

Actually this should be all you need:

```auto
$ADUsers = Import-Csv -Path 'Y:\GAS\newusers.csv' -Delimiter ';'

$ADUsers | 
ForEach-Object {
    if (Get-ADUser -Identity $($_.username) -ErrorAction SilentlyContinue) {
        Write-Warning "A user account with SamAccountName '$($_.username)' already exist in Active Directory."
    }
    else {
        $userParams = @{
            SamAccountName = $_.username
            UserPrincipalName = "$($_.username)@reggiocity.it"
            Name = $_.username
            GivenName = $_.givenName
            Surname = $_.sn
            Enabled = $true
            DisplayName = $_.username
            Path = $_.path
            AccountPassword = (ConvertTo-SecureString $_.Password -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            description = $_.description
            OfficePhone = $_.telephoneNumber
            EmailAddress = $_.mail
            POBox = $_.postOfficeBox
            ScriptPath = $_.scriptPath
            HomeDirectory = $_.homeDirectory
            HomeDrive = $_.homeDrive
            MobilePhone = $_.mobile
            HomePhone = $_.HomePhone
            Title = $_.Title
            Department = $_.department
            Company = $_.company
        }
        if ($_.manager) {
            $userParams.Manager = $_.manager
        }
        if ($_.accountExpires) {
            $userParams.AccountExpirationDate = $_.accountExpires
        }
        New-ADUser @userParams -PassThru | 
            Set-ADUser -Replace @{pager = $($_.pager); PrimaryGroupID = $($_.primaryGroupID) } -Verbose

        Write-Host "Created new user '$Username' with initial password: $($_.Password)"
    }
}

```

… untested … so test with a lab environment please. 😉

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 24, 2021, 8:05am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/5 "2021-08-24T08:05:22Z")

</div>

HI Olaf…thanx thanx thanx for your help.  
I changed the first few lines because a “user not found” error was generated, and the primary groupID must be 513 (domain users) when creating the user. Now I try to convert the member of field into array and pass the variables to the script using Add-ADPrincipalGroupMembership and see if I can. In the meantime, thanks again

$ADUsers = Import-Csv -Path ‘Y:\GAS\newusers.csv’ -Delimiter ‘;’

$ADUsers | Where-Object { $_.username -match ‘\S’} | ForEach-Object {  
$Username = $_.username  
if (Get-ADUser -Filter “SamAccountName -eq ‘$Username’” -ErrorAction SilentlyContinue) {  
Write-Warning “A user account with SamAccountName ‘$Username’ already exist in Active Directory.”  
}  
else {  
$userParams = @{

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 24, 2021, 8:54am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/6 "2021-08-24T08:54:21Z")

</div>

> [@Perry](#):
>
> and the primary groupID must be 513 (domain users)

AFAIK is this the default and you don’t need to do this explicitly.

> [@Perry](#):
>
> I changed the first few lines because a “user not found” error was generated

Yes, that’s actually expected behaviour. You may read about error handling …

> **[about Try Catch Finally - PowerShell](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.4&viewFallbackFrom=powershell-7.1)**
>
> Describes how to use the \`try\`, \`catch\`, and \`finally\` blocks to handle terminating errors.

Depending on the structure and the size of your AD it might be faster and less stress for the AD when you provide a `-SearchBase` for your query or even better when you query the relevant objects from the AD in advance, save the result to a variable and use this at runtime of your script. This way you wouldn’t query your AD again and again and again for each single element of your CSV input file.

> [@Perry](#):
>
> Now I try to convert the member of field into array and pass the variables to the script using Add-ADPrincipalGroupMembership and see if I can.

If you save this information already in the proper format in your CSV you don’t need to convert it afterwards. 😉

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 24, 2021, 9:29am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/7 "2021-08-24T09:29:41Z")

</div>

The CSV is generated by a webservice, one row, one user comma separeted  
The memberOf field for every users,is populated like this: group1, group2, group, … etc  
So i need to create ad array with:  
group1  
group2  
group3  
…  
and for each group put the user in.  
at the end i will set the primary group id.  
or at least I try hahahahahahahahahahahah 😃  
Thanx Olaf for your preciuos help

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 24, 2021, 9:35am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/8 "2021-08-24T09:35:47Z")

</div>

> [@Perry](#):
>
> The memberOf field for every users,is populated like this: group1, group2, group, … etc

If you have a delimitted string you can use the `-split` operator.

```auto
"group1, group2, group" -split ','

```

To remove unwanted space charachters at the end or at the beginning you can use the `.trim()` method.

```auto
("group1, group2, group" -split ',').trim()

```

> [@Perry](#):
>
> at the end i will set the primary group id.

Did I mention that you probably don’t need to do that?

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 24, 2021, 1:04pm UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/9 "2021-08-24T13:04:16Z")

</div>

Here I am, this is the final version of the script and seems to be working:

```auto

$ADUsers = Import-Csv -Path 'Y:\GAS\newusers.csv' -Delimiter ';'

$ADUsers | Where-Object { $_.username -match '\S'} | ForEach-Object {
    $Username = $_.username
    if (Get-ADUser -Filter "SamAccountName -eq '$Username'" -ErrorAction SilentlyContinue) {
        Write-Warning "A user account with SamAccountName '$Username' already exist in Active Directory."
    }
    else {
        $userParams = @{
            SamAccountName = $_.username
            UserPrincipalName = "$($_.username)@reggiocity.it"
            Name = $_.username
            GivenName = $_.givenName
            Surname = $_.sn
            Enabled = $true
            DisplayName = $_.username
            Path = $_.path
            AccountPassword = (ConvertTo-SecureString $_.Password -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            description = $_.description
            OfficePhone = $_.telephoneNumber
            EmailAddress = $_.mail
            POBox = $_.postOfficeBox
            ScriptPath = $_.scriptPath
            HomeDirectory = $_.homeDirectory
            HomeDrive = $_.homeDrive
            MobilePhone = $_.mobile
            HomePhone = $_.HomePhone
            Title = $_.Title
            Department = $_.department
            Company = $_.company
        }
        if ($_.manager) {
            $userParams.Manager = $_.manager
        }
        if ($_.accountExpires) {
            $userParams.AccountExpirationDate = $_.accountExpires
        }
        New-ADUser @userParams -PassThru | 
            Set-ADUser -Replace @{pager = $($_.pager)}
            
            $Inputstring = $($_.MemberOf)
            $CharArray =$Inputstring.Split(",")
            $CharArray

            ForEach ($Items in $Username)

                {
                Add-ADPrincipalGroupMembership -Identity $Username -MemberOf $CharArray
                Get-ADuser "$Username" |Set-ADuser -Replace @{PrimaryGroupID = $($_.PrimaryGroupID)}
                }                     

        Write-Host "Created new user '$Username' with initial password: $($_.Password)"
        Write-Host "gruppi a cui appartiene= $($_.MemberOf)"
    }

   
}

```

Did I mention that you probably don’t need to do that?  
Each user belonging to a service has a different primarygroupID, so I have to set it every time.

Is there anything I can optimize or further checks I can do in your opinion?

Thanx

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [August 24, 2021, 6:47pm UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/10 "2021-08-24T18:47:13Z")

</div>

> [@Perry](#):
>
> seems to be working:

“_ **seems** _ to be working”?? You should be able to see if it’s working or not, don’t you? 😉 😃

> [@Perry](#):
>
> Is there anything I can optimize or further checks I can do in your opinion?

There’s always something you can improve. Actually I already mentioned some possible improvements in my earlier answer. 😉  
For now, if you’re satisfied and the script is running without errors and doing what you want - it’s fine.  
I think with time when your PowerShell knowledge eveolves you will see by yourself where you can tweak your old scripts when you review them from time to time.

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 25, 2021, 6:56am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/11 "2021-08-25T06:56:19Z")

</div>

> [@Olaf](#):
>
> “ _ **seems** _ to be working”?? You should be able to see if it’s working or not, don’t you? 😉 😃

hahahah…yes IT’S WORKING 😃  
G

---

<div class="post-metadata">

**Author:** ![Perry](https://avatars.discourse-cdn.com/v4/letter/p/b4bc9f/32.png) [@Perry](https://forums.powershell.org/u/Perry)\
**Post date:** [August 30, 2021, 10:24am UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/12 "2021-08-30T10:24:53Z")

</div>

Hi Olaf I’ve a strange problem , maybe you can help me.  
During the user creation I’m using this set of istruction to se the ACL on the homefolder of the user:

```auto
#Modifica ACL per cartella W:
                    $PathSRC="\\reggiocity.it\fs\Utenti\Default"
                    $PathTRG= $_.homeDirectory
                    Get-acl $PathSRC | Set-Acl $PathTRG
                    $acl = Get-Acl $PathTRG
                    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Username,'FullControl',('ContainerInherit,ObjectInherit'),'None','Allow')
                    $acl.SetAccessRuleProtection($true,$true)
                    $acl.SetAccessRule($AccessRule)
                    $acl | Set-Acl $PathTRG

```

The $PathSRC is the source folder from which I copy the default ACL  
the $PathTRG is the homefolder written in the csv file that corrispond the USERNAME ad es:  
\reggiocity.it\fs\utenti\calogp.  
The acl is not set correctly, there is only the SID, which has a different value from that of the user

 ![image](https://us1.discourse-cdn.com/flex019/uploads/powershell/original/2X/b/b9b2982821655c582c679308582b4f185dd7f15b.png).  
I hope you can help me as you have done up to now and for which I am grateful  
Thanks

---

<div class="post-metadata">

**Author:** ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)\
**Post date:** [May 16, 2024, 8:21pm UTC](https://forums.powershell.org/t/create-ad-user-from-csv/17387/13 "2024-05-16T20:21:39Z")

</div>


