Search code examples
powershellactive-directorypowershell-3.0change-password

AD password update via Powershell


Too all Powershell Experts: I need some help to figure out why this is working incorrectly. What I mean incorrectly, the accounts in CSV password get updated with a random password and email is sent to the users but i don't under why they are getting the same password, and everyaccount in the AD is addressed. See email output:

Firstuser email:

Hello Guest DefaultAccount user1, user2, user3, user4 test John Doe, 
Your AD Account user1, password has been updated to e,wQlsGfBE;J'4  

Second useremail

 Hello Guest DefaultAccount user1, user2, user3, user4 test John Doe, 
Your AD Account jdoe, password has been updated to e,wQlsGfBE;J'4  

what I'm trying to accomplish are as follows:

  1. List item
  2. Import one column cvs with just "samAccountName"
  3. reset password of the accounts listed in the csv with a random generated 20 character long password
  4. Email the AD account associated email address with the new password. (I'm doing this because their email address if different from their AD Account), so they are able to receive their email.

Import-Module ActiveDirectory
# Import AD user objects and store in users variables 
$users = Get-ADUser -Filter *  -Properties Name, EmailAddress,SamAccountName | Select SamAccountName,Name,EmailAddress
    
$Name = $users.Name
$SamAccountName = $users.SamAccountName
$EmailAddress = $users.EmailAddress

#Date
$date = (Get-Date -Format F) 

#Generate a random password and store in newpwd 
$newpwd = -join (33..126|%{[char]$_}|Get-Random -Count 20)
$newPassword = ConvertTo-SecureString -AsPlainText "$newpwd" -Force

# Import users from CSV
Import-Csv "C:\Userlist.csv" | ForEach-Object {
$samAccountName= $_."samAccountName"

        #Proceed with password reset
            Set-ADAccountPassword -Identity $samAccountName -NewPassword $newPassword -Reset
            Set-AdUser -Identity $samAccountName -ChangePasswordAtLogon $true

#Server configuration 
$smtpServer =""
$SmtpPort = ""
# sending option
$from = "[email protected]"
$to = $EmailAddress 
$subject  ="AD Password updated - " + $date
$priority = "Normal"
$from = ""

$body = @"
Hello $name, <br> 
Your AD Account $samAccountName, password has been updated to $newpwd
"@
try {
# Send the report email
Send-MailMessage -To $to -Subject $subject -BodyAsHtml -body $body -SmtpServer $smtpServer -Port $SmtpPort -From $From -Priority $priority  
}
catch{
    write-warning "error in sending. $_"
}  # End User Processing
            
    }

The Account password is getting updated, but just can't send the emai


Solution

  • When you do $Name = $users.Name, the $Name variable gets an array containing ALL usernames in the CSV.

    Remove that line and instead set the variable inside your ForEach-Object loop:

    # Import users from CSV
    $UserList = Import-Csv "C:\Userlist.csv" | ForEach-Object {
        $samAccountName= $_.samAccountName
        $name = $_.Name
        # then the rest of your code
    }
    

    Note:

    • SmtpPort takes an integer, not a string
    • From cannot be an empty string

    P.S. Try to do some proper code indentation, so it is much easier to see where a code block (like ForEach-Object) starts and ends)


    Your code revised:

    Import-Module ActiveDirectory
    # Import AD user objects and store in users variables 
    $users = Get-ADUser -Filter *  -Properties Name, EmailAddress,SamAccountName | Select SamAccountName,Name,EmailAddress
    
    #Date
    $date = (Get-Date -Format F) 
    
    # Import users from CSV
    Import-Csv "C:\Userlist.csv" | ForEach-Object {
        # read this from the CSV
        $samAccountName= $_.samAccountName
        # get the user object from the $users array
        $user = $users | Where-Object { $_.SamAccountName -eq $samAccountName }
        $name = $user.Name
        $emailAddress = $user.EmailAddress
    
        #Generate a random password and store in newpwd 
        $newpwd = -join (33..126|%{[char]$_}|Get-Random -Count 14)
        $newPassword = ConvertTo-SecureString -AsPlainText "$newpwd" -Force
    
        $body = @"
    Hello $name, <br> 
    Your AD Account $samAccountName, password has been updated to $newpwd
    "@
    
        #Proceed with password reset
        Set-ADAccountPassword -Identity $samAccountName -NewPassword $newPassword -Reset
        Set-AdUser -Identity $samAccountName -ChangePasswordAtLogon $true
    
        #Server configuration 
        $mailParams = @{
            SmtpServer = "YourSMTPServer"
            Port = 25  # <-- an integer value
            # sending option
            From = "[email protected]"
            To = $user.EmailAddress 
            Subject  ="AD Password updated - " + $date
            Priority = "Normal"
            Body = $body
            BodyAsHtml = $true
        }
        try {
        # Send the report email
        Send-MailMessage @mailParams -ErrorAction Stop
        }
        catch{
            write-warning "error in sending. $_"
        }  # End User Processing
    }