I have struggled within my company with trying to make bulk changes to AD objects, and of those objects, mainly AD users. I have 250 users within my AD environment, not really a large environment, ut large enough that with me being the only System Administrator, making a change of more than 5 users becomes time consuming, and labor intensive. Two things I don't have much extra to spare. What drove me to make this script was having to change the ProxyAddress attribute on every user within my AD. This was due to Office 365 inputting the wrong data into that field, and borking the domain that my internal emails were being set under. After looking through many Technet postings, and bashing my head against the PowerShell wall for an hour. I put together this snippet of code.
ForEach-Object ($user in (Get-ADUser -filter *))
{$newinfo= "Replacement Data String Here"
{$newinfo= "Replacement Data String Here"
Set-ADUser $user.samaccountname -replace @{ADAttribute>=$newinfo}}
First thing you will notice is that it is very short, and that is one of the beautiful things about PowerShell, you can do a lot in a very small amount of code. I have found that most of the time I try and write two much code, when a very short two - five line script will do everything I need and more. So let's dive into what this script does.
Line 1
ForEach-Object ($user in (Get-ADUser -Filter *))
The ForEach-Object command allows us to do two things.
>
>
- Run an operation or query defined within the parentheses after the ForEach command, that pulls some sort of data. In this case that query is Get-ADUser -Filter *.
- The second is that you can then run a second operation or query against the first query, in a nested query sort of fashion.
($user in (Get-ADUser -Filter *))
The second part of this line takes the results of the Get-ADUser -filter command, and drops it into a variable called $user, storing the data from the Get-ADUser command and then allowing us to preform an operation against that data later. The * at the end of the -Filter command is a wildcard in PowerShell. It causes PowerShell to use all data that the command has access too.
You can change the * to get a more specific set of objects by adding a better filter, and a different wildcard. Some examples of filters and wildcards you can do are:
($user in (Get-ADUser -Filter {Name -like “*e”)) #This finds all of the AD attribute Names that end in e.
($user in (Get-ADUser -Filter {Surname -like “d*”)) #The second filter finds all AD objects with Surnames that start with D.
($user in (Get-ADUser -Filter {Surname -like “*d*”)) #The third filter finds all AD objects with a Surname that contain a D in them.
The Second Line
$newinfo= " Data string replacement here"
This variable is where you put the data that you want to replace in the attribute. You can place any type of string in this field, and PowerShell will replace it in the attribute field.
The Final Line
Set-ADUser $user.samaccountname -replace @{ADAttribute=$newinfo}}
The last line of this command is where all the hard work is done. First off it starts by using the Set-ADUser Command. Set-ADUser is the main command that you will use when editing existing users within Active Directory. Through this command you can edit every attribute of every user within your AD environment. Sexy Huh?
The Set-ADUser requires us to specify a unique user to be edited, so we provide that user by using the data we pulled into the $user variable. But if you look at that data, which you can do by typing $user in the PowerShell windows, you are going to see that it pulled upwards of 10 attributes from all of your users. This amount of data is great, but we need to narrow it down to one field that is unique to each object. When I need a unique attribute I almost always use the SamAccountName attribute. This field is required to be unique by AD thus always providing us with that unique field we need. To do this we attach the attribute name to the variable with a period, this gives us $user.samaccountname.
-replace @{ADAttribute=$newinfo}}
Then we use the -replace flag for the Set-ADUser command, and add a filter to pick the specific attribute we want to edit. Where I have put ADAttribute is where you want to put the exact name of the attribute you want to enter. Some examples to give you an idea are:
if you wanted to edit the email attribute under all users it would be:
-replace @{mail=$newinfo}}
If you wanted to change the Office of a group of users it would be
-replace @{Office=$newinfo}}
Putting It All Together.
Now I know if you are still reading this, you're questioning, okay so what does it look like when it's in a script and I want to use it. So here are a couple of examples and what the do.
ForEach-Object ($user in (Get-ADUser -filter *))
{$newinfo= "Contoso, Inc."
Set-ADUser $user.samaccountname -replace @{Company=$newinfo}}
This version of the script pulls all users from AD and replaces the Company attribute in AD with Contoso, Inc.
ForEach-Object ($user in (Get-ADUser -filter {Office -eq "Miami, FL" ))
{$newinfo= "Jacksonville, FL"
Set-ADUser $user.samaccountname -replace @{Office=$newinfo}}
This script pulls only users who have "Miami, FL" in the office attribute, and changes it to "Jacksonville, FL".
This script pulls only users who have "Miami, FL" in the office attribute, and changes it to "Jacksonville, FL".
Thus you can now see the true power of this command. It allows you to change any attribute within your AD infrastructure, over a group of users, and when I ran this command against my entire AD, which has 300 active, and inactive users, it took less then 30 seconds to edit all the accounts. Something that would have taken me 6 hours in the GUI!!! I hope that this information will make you life much easier, and wet your appetite for learning about PowerShell.