Bulk update user properties

I have this csv that has 3 properties and is importing correctly but when I do the Set-ADUser in the ForEach, I get error

Set-ADUser : A parameter cannot be found that matches parameter name ‘mail’.

Here is my script:

$users = Import-Csv -Path .\SourceAttributes.csv

# Loop through CSV and update users if the exist in CSV file            
    foreach ($user in $users) {                       
 Get-ADUser -Filter "SamAccountName -eq '$($user.sAMAccountName)'" -Properties * |            
  Set-ADUser -Manager $($user."Primary Contact") -mail $($user."Technical Contact") -WhatIf            

If you review the help for Set-ADUser you’ll see that the parameter is named “-EmailAddress”.
BTW: When you have the sAMAccountName in your csv file you don’t need to get the account with Get-ADUser first. You can use right away Set-ADUser with the parameter -Identity wich takes the sAMAccountName.


revised script:

    foreach ($user in $users) {
Get-ADUser -Identity ‘$($user.sAMAccountName)’ -Properties * | Set-ADUser -Replace -Manager $($user.“Primary Contact”) -emailaddress $($user.“Technical Contact”)

new error:

Set-ADUser : Cannot bind parameter ‘Replace’. Cannot convert the “-Manager” value of type “System.String” to type “System.Collections.Hashtable”.

The -Replace parameter takes a hashtable of one or more values to replace. If you want to set values individually, use other parameters. To replace a bunch at once, use -Replace. Not all AD properties have explicit parameters laid out for you to use with the cmdlet. It is mostly for those that the -Add, -Remove, and -Replace parameters exist; to update those parameters that aren’t accessible through other parameters.

It’ll still work for regular ones, though, and it’s a bit neater than specifying every parameter.

foreach ($user in $users) {                       
    Set-ADUser -Identity '$($user.sAMAccountName)' -Replace @{
        Manager = $user."Primary Contact"
        EmailAddress = $user."Technical Contact"


I had to remove a single quote mark from around part of the loop. So, with the revised script:

foreach ($user in $users) {
Set-ADUser -Identity $($user.sAMAccountName) -Replace @{
Manager = $user.“Primary Contact”
EmailAddress = $user.“Technical Contact”

I get a new error:

Set-ADUser : The specified directory service attribute or value does not exist
Parameter name: EmailAddress

…yet, I have verified with Get-ADUser that the samAccountName for each in my csv exists.

Does it matter that a current value exists in AD for any given samAccountName? It doesn’t matter that this would get replaced by my values in the .csv.

Nah, that’s kinda what you’re after.

Lemme see… Okay, the issue is probably that the property names differ slightly depending on your method. Try applying the email using ‘mail’ as the property name instead. (Or just pull that one out of the hashtable and apply it with the -EmailAddress parameter instead.

Not following you exactly I’m afraid, but I tried this and got a different error.

foreach ($user in $users) {                       
 Set-ADUser -Identity $($user.sAMAccountName) emailAddress = $user."Technical Contact"


Set-ADUser : A positional parameter cannot be found that accepts argument 'emailAddress'.


foreach ($user in $users) {
Set-ADUser -Identity $($user.sAMAccountName) mail = $user.“Technical Contact”


Set-ADUser : A positional parameter cannot be found that accepts argument 'mail'.

You don’t think it’s my csv file being in a weird .csv format? I save mine in Excel as a MS-DOS csv type

You need “-emailaddress” as per the documentation


You are also over complicating things with having to worry about substrings, I would simplify it a bit. In your CSV I would have a column with samaccountname, mail, manager etc then…

import-csv C:\attributes.csv | % {set-aduser -identity $_.samaccountname -emailaddress $_.mail -manager $_.manager }

Thanks Jon, That’s exactly what’s in my .csv so will try your simplified one-liner.

I feel like I am getting close to this and the help file for Set-ADUser wasn’t helping completely. It doesn’t address the use of quotes when using the -Replace Parameter. When i used them, I was able to write values without error.

Anyway, I have this new code:

foreach ($mgr in $mgrs) {                       
    Set-ADUser -Identity $($mgr.sAMAccountName) -Replace @{
       otherMailbox = '$mgr."PrimaryContact"'

…and it does write to the intended attribute (otherMailbox) but it isn’t just the mail address I want from my .csv. It’s many different things depending on how I arrange the quotes.

I’ve tried the following:

$mgr.“PrimaryContact” ERROR: Set-ADUser : replace At line:2 char:5…)
“’$mgr’.PrimaryContact” SUCCES WRITE but {’@{sAMAccountName=svcacctjfw; PrimaryContact=}’.PrimaryContact}
$mgr.PrimaryContact ERROR: Set-ADUser : replace At line:2 char:5…)

…before throwing my hands up in the air!

I just want the next string (mgr.PrimaryContact) in the pipeline (that I verified exists) to populate the otherMailbox attribute.

You’re very close. Your last issue there is that single quotes do not expand variables in strings, period. In this instance, you could simply drop all quotes from the expression. Or, you can use double quotes (but you’d need to be careful because of how PS handles variable properties in strings – it doesn’t, essentially). Or you could use a format string. So… options:

# Option 1
Set-ADUser -Identity $mgr.sAMAccountName -Replace @{
   otherMailbox = $mgr.PrimaryContact
# Option 2
Set-ADUser -Identity $mgr.sAMAccountName -Replace @{
   otherMailbox = "$($mgr.PrimaryContact)"
# Option 3
Set-ADUser -Identity $mgr.sAMAccountName -Replace @{
   otherMailbox = '{0}' -f $mgr.PrimaryContact

In this case, because the property name has no spaces, actually having quotation marks around the property name itself is unnecessary.

Joel, thanks for all of the examples