Bulk modifications using Set-AdUser


The standard approach to the bulk modification of users is to create a CSV file with an identifier and the data you want to change. Here’s part of a CSV file that could be used to modify some AD attributes – Division, City and Office

mgreen,Accounting,”Main Office”,”New York”
dgreen,Sales,”North East”,Boston
jgreen,Marketing,”North West”,Seattle

I always like to first test what is set

$users = Import-Csv -Path C:\Scripts\adtest.csv            
foreach ($user in $users) {            
 Get-ADUser -Identity $user.SamAccountName -Properties * |            
 select SamAccountName, Division, Office, City             

A simple loop through each user and display the data. I’ve used –Properties * to ensure that I get the data I want. I could have put the attribute names in to restrict the returned data – might be a good idea if you are working with lots if user accounts at once

SamAccountName      Division            Office              City              
————–      ——–            ——              —-              
jgreen                                  Test                                  
bkent               AD Admin            ADML House          Peterborough

With Set-ADUser you get two options – a named parameter or the Add, Replace, Clear, Remove parameters.  See the help file for more details. All of our attributes have named parameters  so we can use this code

# Import AD Module             
Import-Module ActiveDirectory            
# Import CSV into variable $userscsv            
#$userscsv = import-csv D:\areile\Desktop\adtest.csv            
$users = Import-Csv -Path C:\Scripts\adtest.csv            
# Loop through CSV and update users if the exist in CVS file            
foreach ($user in $users) {            
#Search in specified OU and Update existing attributes            
 Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" -Properties * -SearchBase "cn=Users,DC=manticore,DC=org" |            
  Set-ADUser -City $($user.City) -Office $($user.Office) -Division $($user.Division)            

Import the CSV file and loop through the users. For each user get the user object and pipe to Set-ADUser. The new attribute values are set from the CSV file data

Alternatively if you know the LDAP name of the attribute OR there isn’t a parameter for that attribute use the –Replace parameter.

# Import AD Module             
Import-Module ActiveDirectory            
# Import CSV into variable $userscsv            
#$userscsv = import-csv D:\areile\Desktop\adtest.csv            
$users = Import-Csv -Path C:\Scripts\adtest.csv            
# Loop through CSV and update users if the exist in CVS file            
foreach ($user in $users) {            
#Search in specified OU and Update existing attributes            
 Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" -Properties * -SearchBase "cn=Users,DC=manticore,DC=org" |            
  Set-ADUser -Replace @{l = "$($user.City)"; physicalDeliveryOfficeName = "$($user.Office)"; division = "$($user.Division)"}            

The thing to note here is that the LDAP attribute names don’t always match the GUI names which are used as parameters. Get-ADUser seems to translate OK though!  You can find the correct name using ADSIEdit.

Note also that the help file for Set-AdUser is incorrect in at least once place – the list of attribute name-value pairs must be separated by semi-colons NOT commas as the help file states

This entry was posted in PowerShell and Active Directory. Bookmark the permalink.

27 Responses to Bulk modifications using Set-AdUser

  1. cavallogolooso says:

    Reblogged this on Depresso Gioioso.

  2. Alan says:

    Would you please also include an example of the -clear property using the same code example as the other 2 shown above?


  3. rkk says:

    Can you please show how I could change AD contact attributes. We have external contacts in ad but have not been able to modify attributes in bulk. Please advise, Thanks!

  4. Ramez says:

    Thanks really helpful

  5. robstelz says:

    Good day. Thank you for taking the time to share your knowledge. Is there a way of calling the identity of the users in the csv file by something other than samAccountName? My goal is to be able to get the ad account using givenName+surname and then be able to set-aduser. Thank you.

  6. tom says:

    Good Morning ….Would it be possible to know how to change POBox Attribute ? Thanks very much

  7. Tariq says:

    Thank you for a good, clear example

  8. Rodrigo says:

    Thank you, for share this, i have a Q… Would it be possible pass a value if this is empty or null?

  9. speedy says:

    when trying to run this script in SQL 2012 agent job, it fails on line starting with “Get-ADUser -Filter…” reporting a syntax error” or if the script is run in cmdexec mode it hangs indefinitely. Tried both with proxy user and sql agent user but not really getting past these errors…

    • Your problem is one of permissions. The account under which SQL Server agent jobs run normally don’t have permissions to other systems. Either change the account you’re using in SQL server or run the script another way. Are the AD cmdlets installed on the SQL server machine?

  10. Edgardo says:

    Please could you give and example of the import csv file

    thank you

  11. Rahul says:

    Hi Richard, could you help me with renaming the Samaccount name itself , rgupta1983@gmail.com

  12. albajock1816 says:

    Great post, thanks – I didn’t know about the replace option when there isn’t a parameter for the attribute. This was driving me barmy.

  13. Piano Man says:

    Thank you for this post. I’ve spent a chunk of today trying to modify your technique for my needs. I’m trying to update e-mail, title, officephone, mobilephone, and display name. I’ve used excel to filter etc. which stripped any quotes. I’ve gone in after the fact and added quotes to all the sections with spaces using notepad++ and regex.
    The issue I have is not all users have both phone numbers. this would end up with the set-aduser having the swtich -officePhone but $($user.officePhone) would be empty. which would bomb the execution. With an error like this.

    Set-ADUser : replace
    At line:1 char:158
    + foreach ($user in $Users) { Get-ADUser -Filter “SamAccountName -eq ‘$($user.Sama …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (CN=Jon Doe…domain,DC=com:ADUser) [Set-ADUser], ADInvalidOperationException
    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.SetADUser

    Ultimately I found the IF syntax that would work.

    foreach ($user in $Users) {
    if ( $($user.emailAddress) -ne “”) {Set-ADUser -identity $($user.SamaccountName) -emailAddress $($user.emailAddress) }
    if ( $($user.Title) -ne “”) {Set-ADUser -identity $($user.SamaccountName) -Title $($user.Title) }
    if ( $($user.officePhone) -ne “”) {Set-ADUser -identity $($user.SamaccountName) -officePhone $($user.officePhone) }
    if ( $($user.MobilePhone) -ne “”) {Set-ADUser -identity $($user.SamaccountName) -MobilePhone $($user.MobilePhone) }
    if ( $($user.DisplayName) -ne “”) {Set-ADUser -identity $($user.SamaccountName) -DisplayName $($user.DisplayName) }

  14. Ewa says:

    I’m using the below to amend a division within AD but I want to be able to amend other attributes (employeenumber) with the same script. Do I just add employeeNumber = $User.EmployeeNumber, after $User.division.. What would happen if for some of the employees there is no employee no within my csv?

    Import-Module ActiveDirectory
    $Users = Import-Csv .\division.csv
    foreach ($User in $Users)
    {Set-ADUser -identity $User.SamAccountName -Replace @{division=$User.division},

  15. Ewa says:

    I have used your script and modified it to adapt to my needs. I’m testing it on a single test user and I got to last error when I can understand

    The script
    $users = Import-Csv -Path C:\Scripts\division1.csv
    foreach ($user in $users) {
    Get-ADUser -Filter “SamAccountName -eq ‘$($user.SamAccountName)'” -Properties * -SearchBase ‘OU=TEST,OU=USERS,OU=TMG,DC=xxxxxx,DC=locdom’ |
    Set-ADUser -Replace @{ Manager = “$($user.Manager)”; division = “$($user.division)”;Employeeid = “$($user.Number)”}

    I’m getting the following error :
    Set-ADUser : The parameter is incorrect
    At line:5 char:3
    + Set-ADUser -Replace @{ Manager = “$($user.Manager)”; division = “$($user.divis …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (CN=TEST\, Ewa,O…group,DC=locdom:ADUser) [Set-ADUser], ADInvalidOperationException
    + FullyQualifiedErrorId : ActiveDirectoryServer:87,Microsoft.ActiveDirectory.Management.Commands.SetADUser

    And this is the get user output:

    AccountExpirationDate :
    accountExpires : 9223372036854775807
    AccountLockoutTime :
    AccountNotDelegated : False
    AllowReversiblePasswordEncryption : False
    AuthenticationPolicy : {}
    AuthenticationPolicySilo : {}
    BadLogonCount :
    CannotChangePassword : False
    CanonicalName : xxxxx.locdom/TMG/USERS/TEST/TEST, xx
    Certificates : {}
    City :
    CN : TEST, xx
    codePage : 0
    Company :
    CompoundIdentitySupported : {}
    Country :
    countryCode : 0
    Created : 01/03/2017 16:45:41
    createTimeStamp : 01/03/2017 16:45:41
    Deleted :
    Department :
    Description :
    DisplayName : TEST, Ewa
    DistinguishedName : CN=TEST\, Ewa,OU=TEST,OU=USERS,OU=TMG,DC=xxxxxx,DC=locdom
    Division : South
    DoesNotRequirePreAuth : False
    dSCorePropagationData : {01/01/1601 00:00:00}
    EmailAddress :
    EmployeeID : 12345
    EmployeeNumber :
    Enabled : True
    Fax :
    GivenName : Ewa
    HomeDirectory : \\xxxxx\StoUsersHomeDir\etest
    HomedirRequired : False
    HomeDrive : X:
    HomePage :
    HomePhone :
    Initials : EK
    instanceType : 4
    isDeleted :
    KerberosEncryptionType : {}
    LastBadPasswordAttempt :
    LastKnownParent :
    LastLogonDate :
    LockedOut : False
    LogonWorkstations :
    Manager :
    MemberOf : {}
    MNSLogonAccount : False
    MobilePhone :
    Modified : 03/03/2017 12:40:51
    modifyTimeStamp : 03/03/2017 12:40:51
    msDS-User-Account-Control-Computed : 0
    Name : TEST, Ewa
    nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
    ObjectCategory :
    ObjectClass : user
    ObjectGUID : bbf1186d-065c-40ac-bf73-
    objectSid : S-1-5-21-42734540
    Office :
    OfficePhone :
    Organization :
    OtherName :
    PasswordExpired : False
    PasswordLastSet : 01/03/2017 16:45:41
    PasswordNeverExpires : True
    PasswordNotRequired : False
    POBox :
    PostalCode :
    xprimaryGroupID : 513
    PrincipalsAllowedToDelegateToAccount : {}
    ProfilePath :
    ProtectedFromAccidentalDeletion : False
    pwdLastSet : 131328603416996784
    SamAccountName : etest
    sAMAccountType : 805306368
    ScriptPath :
    sDRightsEffective : 0
    ServicePrincipalNames : {}
    SIDHistory : {}
    SmartcardLogonRequired : False
    sn : TEST
    State :
    StreetAddress :
    Surname : TEST
    Title :
    TrustedForDelegation : False
    TrustedToAuthForDelegation : False
    UseDESKeyOnly : False
    userAccountControl : 66048
    userCertificate : {}
    UserPrincipalName : etest@xxxx
    uSNChanged : 241938011
    uSNCreated : 241391653
    whenChanged : 03/03/2017 12:40:51

  16. RamblingMAdmin says:

    I’ve got a bit of a weird one, I have a service account I’m trying to use to update UNIX properties on AD Objects via PS and a Scheduled Task. Whenever I use ADUC with the account I can modify the property, whenever I do PS one liners using the service account, it works. But when I do a for each loop, it seems to lose the credentials. To make matters weirder, when I use DA rights, the script runs just fine. Have you ever seen something like this?

    Import-Module ActiveDirectory
    $userList = Import-CSV -Path “C:\Folder\Unix-AD-List.csv”

    if($userList.uid -ne “”){
    $userList | Add-Member -MemberType NoteProperty -Name “updateTime” -Value (Get-Date -Format g)

    foreach($user in $userList){
    Set-ADUser $user.uid -Replace @{
    uid = $user.uid
    uidNumber = $user.uidNumber
    gidNumber = $user.gidNumber
    gecos = $user.gecos
    unixHomeDirectory = $user.unixHomeDirectory
    loginShell = $user.loginShell

    $user | Out-File -FilePath C:\Folder\Unix-AD-Update-Log.txt -Append

    Remove-Item -Path “C:\Folder\Unix-AD-List.csv”
    Copy-Item -Path “C:\Folder\Originals\Unix-AD-List.csv” -Destination “C:\Folder\”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s