Bulk Active Directory Changes Using PowerShell


At my job we are moving from 4 digit extensions to 5 digit extensions because we are running out of numbers. That’s a lot of records to update by hand in Active Directory. So I figured out a nifty way to use PowerShell to reduce the workload. During my research I encountered a bunch of broken scripts, misinformation, and awful solutions posed in forums. So to help the next guy out I figured I’d do a quick what-went-wrong-and-how-to-make-it-right blog post. The principles I used here for my use-case can be applied to any Active Directory user property. Let’s dig in.

Figuring Out What You’re Looking For

Firstly, we want to identify the property name of the attribute we want to change in Active Directory. Open Active Directory and change the attribute you want to modify for a single user to something that will stand out. Like “THIS ONE HERE”, “TARGET”, “XXXXXXXXXX”, or something. I’m childish, so I use “poop”.

Once you’ve applied the changes, we are going to open PowerShell to find the “poop” or whatever your boring name is. But first you’re going to need the Active Directory PowerShell Module installed so you can play with AD in PowerShell. If you have the Remote System Administration Toolkit (RSAT) installed on your computer, you should be fine. Running this won’t hurt either way.

PS C:\Users\typicaltim> Import-Module ActiveDirectory

Next you’re going to take a peek at the properties of the user you changed.

PS C:\Users\typicaltim> Get-ADUser -Identity "typicaltim" -Properties *

Look for the property that has the value you applied earlier.

Sweet! Looks like I’m looking for “telephoneNumber”.

Exporting the Data

Now we want to export that into a CSV en masse for all of our users. So we are going to do the following:

PS C:\Users\typicaltim> Get-ADUser -Properties * -Filter {enabled -eq "True"} | Select-Object "SamAccountName", "Department", "ipPhone", "TelephoneNumber", "enabled" | Export-Csv C:\Users\typicaltim\Desktop\ad-user-data-list.csv -NoTypeInformation -Delimiter ","

There’s a bunch of stuff in this one liner, so let me break it down for you. That way you’re not running commands blindly. Where I work we have a metric ass-ton of disabled accounts, I am not concerned about updating those records. So I filter only the enabled accounts. The first bit gets all the enabled users and their properties and pipes it to Select-Object where we grab the specific properties of the items we want. Otherwise we would have a massive spreadsheet about 98% full of bullshit we don’t need. I want the account username, their department (to make it easy to organize), the IP Phone number, the Telephone number, and the enabled status – just in case. That gets piped to Export-CSV to save it to the desktop – but with a few parameters I feel are worth mentioning. Export-CSV likes to put a bunch of garbage in the first few lines of the file, which messes with the CSV formatting when you open it up. Using “-NoTypeInformation” gets rid of that. I like specifying the “,” character as the delimiter to make sure everything is clean, so that’s what the last bit is for.

Modifying the Data

We should now have a CSV file on our desktop with everything we want in it. Now to make all the changes. I prefer to open the CSV up and make a separate column next to the fields I’m changing called “newtelephonenumber” and so on. That way I have a record of what they were prior to the changes in case something goes aloof. Like this:

SAMAccountName telephoneNumber newtelephonenumber
typicaltim 1234 12345
anotheruser 2345 34567

If you do this, make sure that you save the document as a CSV and not an XLS or XLSX file. Things could go wrong.

Importing the Data Back Into Active Directory

Once you have all the changes in place, it’s as easy as 4 lines of PowerShell to achieve our goal!

PS C:\Users\typicaltim>
$UpdatedADUserData = Import-Csv -Path C:\users\typicaltim\desktop\ad-user-data-list.csv
ForEach ($user in $UpdatedADUserData){
Get-ADUser $user.SamAccountName | Set-ADUser -Replace @{telephoneNumber=$user.newtelephonenumber ;IPPhone=$user.newipphonenumber}

What this does is fills the $UpdatedADUserData variable with our CSV data, then breaks each line of the file into the $user variable. Now we can select specific “columns” from each line. For every line we will select the SamAccountName and replace the telephoneNumber and IPPhone properties in Active Directory with the data from the newtelephonenumber and newipphonenumber columns.

Hopefully this helps someone out there! :)