Using a data source like a CSV file, PowerShell, and a little sweat equity, we can create a script that creates Active Directory (AD) objects such as users, groups, and organizational units (OUs) in bulk from a single CSV file.

Adam Bertram

Adam Bertram is a 20-year IT veteran, Microsoft MVP, blogger, and trainer. Adam is the founder of the e-learning tech screencast platform TechSnips. Catch up on Adam’s articles at, or follow TechSnips on Twitter at @techsnips_io.

To demonstrate creating AD objects from a CSV file, let's use a real-world example. Perhaps our HR department generates a report in CSV format from their HR database of employees. The CSV file has five fields: First Name, Last Name, Department, EmployeeID, Location, and Phone Number.

Employee CSV file

Employee CSV file

You have the task of setting up these employees with AD user accounts, getting them in the right groups, in the right OU, and so on. You'd like to build this script to be resilient, meaning that if an object already exists for some reason, you'd want to skip it, otherwise create it.

The first step is to read all of the users in the CSV file. We can do this with Import-Csv. In this example, my CSV is called Employees and is located in the root of my C: drive.

Preliminary code testing ^

Once I have the users in a variable, I then need to figure out how to process just one. After figuring this out, we can then extrapolate the code to all of the other users.

Since the CSV file doesn't contain a username, we need to create one. Our company standard is first initial/last name. We can build this by testing it with the first CSV user in the $csvUsers variable.

Now that we have the username we'd like to create, we then need to figure out the code to test whether this user exists or not. For this, we can use Get-AdUser and the ‑Filter parameter.

Next, we have a policy that dictates every department has an associated AD group. Without much research, we find we can use the Get-AdGroup cmdlet.

Next, our company dictates that we also need to have an OU per location. No problem! With the Get-AdOrganizationalUnit cmdlet, we can test whether or not that OU exists in our script.

Creating the script code ^

Because there may be more than one employee in each department and we only want to attempt to create a group or OU once, we need to remove all of the duplicates from the CSV file. We do this by enumerating all of the departments and locations and only picking the unique ones.

Next, we need to start creating the base "infrastructure" like the OUs and groups the users will go in. To do this, I will iterate over each of the groups and OUs I've previously defined for creation. I will use the "Get" code I discovered earlier here, and only if that object doesn't exist, I will then attempt to create it.

We can take a look at each of these arrays to ensure we're going to be using the expected groups and OUs.

Inspecting groups and OUs

Inspecting groups and OUs

Now that the OUs and groups are out of the way, I can then begin to iterate over each of the employees in the CSV file I previously set in my $csvUsers variable. You can see below that I'm now placing the code I researched ahead of time into the appropriate spots in the loop.

I'm performing the same general activity as I did with the groups and OUs, although this time it's with users.

Wrapping it up ^

I've shown a lot of code in this article, and it'd be cumbersome to remember to do it all again. Instead, we can wrap it all up into a single function. This way, we only need to call the function once, and it will create our AD users using input from the CSV file!

Below is an example of the function. If your company policies are different, this will give you a great template to start with. This function assumes the CSV file has fields the same as we just discovered. If your CSV file is different, you should be able to change these fields in the function quickly.

You can see that although there's a lot of code to create an AD script that creates various objects, by using PowerShell and wrapping everything up in a single function, we can let PowerShell do all of the work for us!

Join the 4sysops PowerShell group!


Users who have LIKED this post:

  • avatar
1 Comment
  1. JohnM 10 months ago

    should the line

    OfficePhone = 'Phone Number'

    actually be

    OfficePhone = $csvUser.'Phone Number'


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2019


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account