One of the great things about PowerShell is that you can use it to build simple tools that you can hand off to someone else. Your tool can have only what is required. As an example, let’s look at creating a simple account password change for Active Directory that uses PowerShell.

I’m going to assume you have at least PowerShell 3.0; otherwise, you will need to make sure you manually import the ActiveDirectory module first. If you don’t have that on your desktop, then download and install the latest Remote Server Administration Tools (RSAT).

The basics

The cmdlet to use is called Set-ADAccountPassword. To use it, all you need to do is specify the account and the new password and that you are resetting it. If you don’t use the –Reset option, you have to also specify the user’s old password. The only tricky part is that the new password must be specified as a SecureString. You can create it like this:

PS C:\> $newpwd = Read-Host "Enter the new password" -AsSecureString
Enter the new password: ********

Or you can create it without any user intervention:

PS C:\> $newpwd = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText –Force

You need to use all the parameters. Otherwise, you will still get prompted or get an error.

Do it for one

Armed with the new password, you'll find it is as easy as this to reset a user’s password:

PS C:\> Set-ADAccountPassword jfrost -NewPassword $newpwd –Reset

With this simple command, I’ve reset the password for user Jack Frost. The command uses my current credentials, but it also supports –Credential if I want to make the change using a different account.

This cmdlet changes only the password. But many organizations also want to force users to change their password at the next logon. I can do that as well by adding another step to my pipelined expression. If you try this command, you’ll notice that you get nothing written to the pipeline. This is the default behavior unless you use –Passthru.

When you do that, you get the user object, which is handy because this can be piped to Set-ADuser.

PS C:\> Set-ADAccountPassword jfrost -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True

Unfortunately, at least in my opinion, the –ChangePasswordAtLogon is not a switch, so you have to explicitly specify a Boolean value. But it works!

User must change password at next logon

User must change password at next logon

Do it for many

The beauty of PowerShell is that if you can do something for one object, such as a user account, you can do it for many. I already have code that works for resetting the password and forcing the user to change a password at the next logon. All I have to do is come up with a PowerShell expression to get the necessary user accounts.

Let’s say I need to force a password reset on all users in the Marketing Department. A command like this will return all of the enabled accounts:

PS C:\> get-aduser -filter "department -eq 'marketing' -AND enabled -eq 'True'"

After verifying the accounts, I can add on the rest of my command:

PS C:\> get-aduser -filter "department -eq 'marketing' -AND enabled -eq 'True'" | Set-ADAccountPassword -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True

This command will give all the users the same new password and then force them to change it the next time they use it. If I simply wanted to force them all to change their existing passwords the next time they logged on, I could drop the Set-ADAccountPassword part of my expression:

PS C:\> get-aduser -filter "department -eq 'marketing' -AND enabled -eq 'True'" | Set-ADuser -ChangePasswordAtLogon $True

Summary

I hope you can appreciate how easy this is to accomplish and that there’s no scripting involved at all. But there is a fair amount of typing, so in my next article we’ll look at some ways to package this functionality.

15 Comments
  1. Robert Pearman 9 years ago

    I came up with a quick way to build a password in PowerShell – probably better ways but…

    # Password Settings
    $PasswordLength = 8
    $password = “”
    # Set Password Character Strings
    $Set0 = “abcdefghijklmnpqrstuvwxyz”.ToCharArray()
    $Set1 =”123456789″.ToCharArray()
    $Set2 = “ABCDEFGHIJKLMNPQRSTUVWXYZ”.ToCharArray()
    $Set3 = “!£$%^&()_ @#”.ToCharArray()

    # Build Password on Length Variable
    do{

    $password += $set0 | Get-Random;
    $password += $set1 | Get-Random;
    $password += $set2 | Get-Random;
    $password += $set3 | Get-Random;
    }
    until ($password.Length -eq $passwordlength)
    # Convert to Secure String
    $pwd = convertto-securestring $password -asplaintext -force
    # Display Password
    $password

    I also published a password reminder script here: http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27

  2. Robert Pearman 9 years ago

    That script i just sent through has a bug in it – so no need to approve 🙂

  3. Jose Ortega (Rank ) 9 years ago

    Hi all As I take part of your script, I think that the best way to help us all is to share.
    I created a script that export users with comma separated values. Imported with csvde -i -f File.csv . Then all users were created with no password and inactives. So
    I wanted to set them all same Password, changed them at next logon and Active the users. So, this is the result:

    Import-Module Activedirectory -Cmdlet Get-ADUser,Set-ADUser,Set-ADAccountPassword,Enable-ADAccount

    #Set the generic windows password.
    $newpwd = “Pa$$w0rd” #convertto-securestring-asplaintext -force

    #Set all inactive users in the $InactiveUsers Variable
    $InactiveUsers = Get-ADUser -filter * | Select SamAccountName,Enabled | Where-Object { $_.Enabled -eq $false }

    ForEach($IUser in $InactiveUsers){
    #setalias
    $aliasAC = $IUser.SamAccountName
    #if user is guest or krbtgt (default inactives) just skip them

    if($aliasAC -eq “Guest” -or $aliasAC -eq “krbtgt”){
    continue;
    }
    else{
    #set password
    Set-ADAccountPassword $aliasAC -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True
    #set active
    Enable-ADAccount -Identity $aliasAC
    Write-Output “User $aliasAC has been actived with password $newpwd”
    }
    }

  4. Jose Ortega (Rank ) 9 years ago

    In the previous correct the 4th line with:
    $newpwd = convertto-securestring “Pa$$w0rd” -asplaintext -force

  5. Michael 8 years ago

    So i have been trying all day to get a script that will change the users password and require the user to change it at logon. i have tried the above and all was working till i tried:

    PS C:\> Set-ADAccountPassword (username) -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True

    it did reset the password but it did not require the user to change at next logon. no errors in the powershell so i do not know why it did not work

  6. Author

    I suspect the issue is that Set-AdAccountPassword doesn’t really write an ADUser object to the pipeline which is what Set-ADUser is expecting. A command like Get-ADUser | Set-ADUser works because the object type is the same. I don’t have access to my test network now, but I think Set-ADAccountPassword is sending a different type of object, most likely some sort of PasswordObject. It may have an Identity property, but Set-ADUser doesn’t take pipeline input by property name for that property. You could try using a ForEach loop: Set-ADAccountpassword | foreach { Set-ADUser -identity $_.identity …. }

  7. Eric Newton 6 years ago

    The term ‘set-adaccountpassword’ is not recognized as the name of a cmdlet, function, script file, or operable program

    Lovely.

    • This cmdlet is part of the ActiveDirectory module, which is installed with RSAT on your workstation.
      Try Import-Module -Name ActiveDirectory to see if the module is installed.

      You can also execute Set-ADAccountPassword from a domain controller.

      avatar
  8. Peter 5 years ago

    Im not a powershell expert so I’m asking some help of you guys here.
    Is there anyone who could make me a script which picks up usernames from a list (lets say a txt file) and creates a new password for all of them

    It needs to be exactly the same password for all the users in the list, no change at logon whatsoever.

    anyone cna help me with that?

    Thank you!
    Peter

  9. Michael J. Thomas 4 years ago

    # I had an issue with the command until I change it to the following:

    $UserName = “mthomas”

    $Password = “P@$$w0rd”

    Get-ADUser -Identity $UserName | Set-ADAccountPassword -NewPassword (ConvertTo-SecureString -String $Password -AsPlainText –Force) –Reset -PassThru | Set-ADUser -ChangePasswordAtLogon $true

  10. Tim 4 years ago

    Greenhorn here: How do I specify what domain the PS cmdlet is making a password change on? (Think Prod vs. Dev environments that share similar usernames across them)

    • @Tim

      Nearly every Active Directory cmdlet has a -Server parameter to specify the domain controller on which you want to make the operation.

      For example:

      Get-ADUser -Identity $SAMAccount -Server $DCName

      If not, you can use the Invoke-Command cmdlet

      Invoke-Command -ComputerName $DCName -ScriptBlock {Get-ADUser -Identity $SAMAccount}

  11. Angu 3 years ago

    I have to reset the Workgroup servers Users . using Powershell script.. Password should be encrypted.

  12. Syltrem 3 years ago

    The term 'Set-ADAccountPassword' is not recognized… on Windows 10 ???

    • Leos Marek (Rank 4) 3 years ago

      You need to have RSAT installed, so you have the proper Powershell module available.

Leave a reply to Michael Click here to cancel the reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account