change aduser attributes

Hello,

I need to change existing values in multiple aduser, attribute fields.
Only when I run this script Powershell does not return a error, unfortunately it also does not change anything.

I have a imported csv file, with adusers and a to be replaced /filled Atrribute field and its new value
Example:

Samaccountname : adm-test-RevV
Displayname : Revel Vin
Description : Admin account Servicedesk CTASK0902707
Emailaddress : Revelino.Vin@test.nl
Company : test-Company

When I use a set-aduser -replace on a test account it works fine.
In the foreach loop is looks fine only it does not change any attribute

I am not sure what I am missing at this moment.
$Users = import-csv .\Output\Beheeraccounts1.csv -Delimiter ";"

$Sam = ($Users).samaccountname
$Display = ($Users).Displayname
$Description =($Users).Description
$Emailaddress = ($Users).Emailaddress
$Company = ($Users).Company

foreach($user in $sam){
{Get-ADUser -Filter “SamAccountName -eq ‘$($Sam)’” |Set-aduser -Replace @{$Displayname= $($Display)}
{Get-ADUser -Filter “SamAccountName -eq ‘$($Sam)’” |Set-aduser -Replace @{$Description = $($Description)}
{Get-ADUser -Filter “SamAccountName -eq ‘$($Sam)’” |Set-aduser -Replace @{$Emailadress = $($Emailaddress)}
{Get-ADUser -Filter “SamAccountName -eq ‘$($Sam)’” |Set-ADUser -Identity $_ -Company $Company}
}
#}}}


Since the company attribute field is empty, I use the -add instead of - replace.

thx

There are a couple of things wrong.

  • It appears you want to process each row for a user. When you use the dot notation (e.g ($Users).samaccountname), that is creating an array of just samAccountNames. The only data you have in your loop is that sam, so you do not have the rest of the row (DisplayName, Description, etc.) for the user.
  • The Set-ADUser should be called one time, with the Server set to the DC you want to write to, otherwise it will be updating all over the place and you can't validate until replication is complete.
  • The Set-ADUser replace is a hashtable with the AD Attribute you want to set and the value you want to set. The code you posted has a variable setting a variable
  • Recommend collecting the results. You have a row with the user data, so you can just append a 'Status' to capture success\issues so you can review what happened for each user
$Users = import-csv .\Output\Beheeraccounts1.csv -Delimiter ";"

#for each row in the csv...
$results = foreach ( $user in $users ){
    $sam = $user.samaccountname
    #try to find the user
    $adUser = Get-ADUser -Filter {SamAccountName -eq $sam} 
    #if you find the user, e.g. $adUser is not null...
    if ($adUser) {
        #the set can be a single call
        #in the replace, you need to reference the AD attribute name and then a variable
        $params = @{
            Identity    = $adUser
            Company     = $user.Company
            Server      = "My_Domain_Controller"
            ErrorAction = 'Stop'
            Replace = @{
                Displayname = $user.DisplayName
                Description = $user.Description
                Mail        = $user.Emailaddress
            }
        }
        try {
            Set-ADUser @params
            $user | Select-Object -Property *, {Name='Status';Expression={'Success'}}
        }
        catch {
            #Set failed
            $setErr = $_
            $user | Select-Object -Property *, {Name='Status';Expression={'Failed: {0}' -f $setErr}}
        }
    }
    else {
        $user | Select-Object -Property *, {Name='Status';Expression={'Not_Found'}}
    }
}

@Rob Simmers,

Thank you for the reply, I will “investigate” this solution, and compare it with that what I did sofar.
Copy paste is one thing, to see the difference and knowing why is more my goal. :slight_smile:

#Names in upper case come from input csv
#Keys of user email address provided in csv

$creds  = Get-Credential
$server = 'adserver.contoso.com'
$users  = import-csv '.\users.csv'
ForEach ($u in $users) {
    try {
        $email = $u.EMAIL
        $user = Get-ADUser -Credential $creds -Server $server -Filter {EmailAddress -eq $email} -Properties *
        
        $user.Title      = $u.TITL
        $user.EmployeeID = $u.EMPID
        $user.Department = $u.DEPARTMENT
        $user.Division   = $u.DIV
        
        Set-ADUser -Instance $user 
    } 
    catch {
        Write-Warning $Error[0]
        Continue
    }
}

 

Rob, I have this same question. In your answer code, can I still use the “REPLACE” block if my Users’ (extension) attributes are blank?

obijuan, what does it mean “…#Keys of user email address”

Jeff, Have you tried testing it on a single user with a single attribute? Key or lookup attribute to find the user.

@Rob, yes I’m trying with this code:

$Users = import-csv .\Users.csv -Delimiter ";"

#for each row in the csv...
$results = foreach ( $user in $users ){
    $sam = $user.samaccountname }
    #try to find the user
    $adUser = Get-ADUser -Filter {SamAccountName -eq $sam}

…but it’s balking that: “Get-ADUser : Variable: ‘sam’ found in expression: $sam is not defined.”

My $Users variable is properly formatted and import-csv is working with it (for one test user)

$results = foreach ( $user in $users ){
#try to find the user
$adUser = Get-ADUser $user.samaccountname }

you have your aduser query outside of your foreach loop.
as well, you don’t need to utilize the filter on your get-aduser statement, get-aduser accepts samaccountname for the identity value

David, even with these tweaks:

$Users = import-csv .\Users.csv -Delimiter ";"

#for each row in the csv...
$results = foreach ( $user in $users ){
    #try to find the user
    $adUser = Get-ADUser $user.samaccountname}

…I get the error:

Get-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.

I do have value(S) inside of $adUser including one for SamAccountName (I’m testing with one User)

The users.csv contains users with a samaccountname? If it’s a single user, try wrapping $users in @() to ensure it’s an array:

$results = foreach ( $user in @($users) ){...

Note that I normally use a -Filter to find a user rather than -Identity to connect to a user. Filter you are checking to see if a result returned (e.g. If ($aduser)…) whereas -Identity you have to use a try\catch to capture the error if the user doesn’t exist.

Thanks Obijuan, this code worked for me

yep, have samAccoutnName in csv and per your first suggestion, testing with one user.

Revised code:

$Users = import-csv .\Users.csv -Delimiter ";"

#for each row in the csv...
$results = foreach ($user in @($users)){
    #try to find the user
    $adUser = Get-ADUser -identity $user.samaccountname}

Error still on both Get_ADUser with -identity (and -filter)

Get-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and 
then try running the command again.

I got my work done with Obijuan’s code but still trying to do same thing with yours for the sake of the education. Thanks

Let’s do some basic 101 troubleshooting. Both errors indicate you are passing NULL or nothing to the parameters. The csv content has not been shared.

$csv = @"
samAccountName
user1234
"@ | ConvertFrom-Csv

foreach ($user in @($csv)) {
    $user.SamAccountName
}

I always highlight the code that is importing the csv and check it:

PS C:\Users\rasim> $csv = @"
samAccountName
user1234
"@ | ConvertFrom-Csv

PS C:\Users\rasim> $csv

samAccountName
--------------
user1234      

Before I start writing code for Active Directory or anything else, I verify my for loop is getting my data:

PS C:\Users\rasim> 
foreach ($user in @($csv)) {
    $user.SamAccountName
}
user1234

Yes, all that checks out on my end. I do Return the samAccountName from the $csv > $user variable.