Security

How To Change User Password With PowerShell

I am going to show a couple of very easy ways to change or reset a user’s local or domain account password using PowerShell.  You do not need any PowerShell modules.  Just built in PowerShell will be used to change the password.

Why do anything with PowerShell when you can already use CMD?

An important concept to grasp is the ability to reuse code and process multiple items.

“I can already use the NET USER command from CMD.  Why use PowerShell?”

Sponsored Content

Passwords Haven’t Disappeared Yet

123456. Qwerty. Iloveyou. No, these are not exercises for people who are brand new to typing. Shockingly, they are among the most common passwords that end users choose in 2021. Research has found that the average business user must manually type out, or copy/paste, the credentials to 154 websites per month. We repeatedly got one question that surprised us: “Why would I ever trust a third party with control of my network?

We want to use PowerShell for 3 reasons:

  1. It’s the new way.  PowerShell creator Jeffrey Snover is now the Lead Architect for Windows Server 8.  Him moving into a role of such importance is the exclamation point on what PowerShell people have been saying since it came out: “Start using it or start getting left behind!”
  2. Reusability.  Even though our simple task of changing a user’s password should not be something that needs to be scripted, and then reused, it could be.  And anything you use with PowerShell can be.  It’s definitely one of the important reasons we want to use PowerShell when we can.  You never know at the start of a project that you won’t want to reuse some part of it on a later project.
  3. Write once, process many.  Once we’ve got a command to change a password, there’s no reason we can’t use that command on multiple objects.  It’s easy, and that’s philosophy is at the core of all automation.

Change every local user account on a computer to have the same password

Lets dive into an example to make a great point about the reusability and the ability to handle multiple password changes with a single command.

First, we need to get a list of users to change the passwords on.  We’ll use WMI for this task.

A great thing about using WMI for this task is that it can be used remotely or locally.  If you want to run this on a remote computer (appropriately named “remote-pc”) it’s almost as easy – no extra setup required (firewall exceptions and RPC come in handy though.)

How To Get a List of Local User Accounts with PowerShell:

​$userlist  = get-wmiobject win32_useraccount

How To Get a List of Local User Accounts from Remote Computer with PowerShell:

​$remoteuserlist = get-wmiobject win32_useraccount –computername “remote-pc”

 

Change Password using ADSI object

Secondly, we’ll look at how to change a password using the ADSI object in .NET.

To get the ADSI object for a user, we need the computer name that the local account belongs to, and the user account name.  One thing that we can use from the list of user accounts from WMI that we got with PowerShell is that the computer name and user account name are both listed in a property called “Caption”.   Too bad the Caption property uses a backslash (“\”) and ADSI uses a slash (“/”).  To get around that, I will use the string method Replace().  That part looks like this:

​$userlist[0].caption.replace(“\”,”/”)

There are several options for telling the ADSI class what kind of account to connect to.  Two of those I find : WinNT (for local accounts), and LDAP (for domain accounts).  Those are case sensitive. Since we’re looking for a local account, it will be in this format:

​[adsi]“WinNT://local-PC/accountname”

Retrieving a domain user account is just as easy.  It’s in the form:

​[adsi]“LDAP://www.contoso.com/accountname”

How to Set a Password For a User Account

There are two options for creating the user account object:  use it one time then it’s gone, or save it as a variable.

If you’re going to do a password reset, and will not be making any other changes, you can use this simple method of creating your user object instance.  Just use parentheses around the object, and this will ensure that the object is able to be referenced and methods can be run from it.  It looks like this:

​([adsi]“WinNT://Remote-PC/AccountName”).SetPassword(“Shazbot!”)

After this runs, the password for the account “Accountname” on the computer “Remote-PC” is set to “Shazbot!”.  There is no further reference to the object in the script.

If you know the computer name, and the account name, this one liner will set your password:

​([adsi]“WinNT://<Local or Remote Computer Name>/<Username>”).SetPassword(“<Password>”)

On the other hand, if you’re going to need to account for anything else, such as viewing or changing any other property on the account, then you should keep it as a variable.  It’s very similar to the first method:

​[adsi]$userVariable = “WinNT://<Local or Remote Computer Name>/<Username>”

Now you have a variable that represents the user account, and you can change the password using the same SetPassword() method used above.

​$userVariable.SetPassword(“Gilligan+Skipper=TrueLove4Ever”)

How To Reset All Local User Accounts on a Computer to the Same Password

Here’s a quick one-liner that sets all user accounts on a computer to have the same password.

​Get-WmiObject win32_useraccount | Foreach-Object {
([adsi](“WinNT://”+$_.caption).replace(“\”,”/”)).SetPassword(“FluxCapacitor!11-5-1955”)
}

If that seems like gibberish to you, here’s the translation:

Get the local user accounts from WMI, and since we’re not done with those objects, they are passed through the pipeline.  They are the input for the Foreach-Object, which applies everything that’s in the scriptblock to each individual user account.  When being passed through the scriptblock, individual user accounts are referenced by the “$_”.  We build a string like “WinNT://computer/user” by switching the “\” symbol from the user accounts “caption” property into a “/” by the use of the string method Replace.  After the string is put together, [adsi] processes and creates an ADSI reference to the real user account on the computer.  The SetPassword method is called on the object, which sets the password to “FluxCapacitor!11-5-1955”.  It performs that on each local user account, and then it’s done.

Conclusion

PowerShell can be used to administer every facet of Windows Operating Systems.  In this example we see how to easily use PowerShell to work with .NET and WMI to get a list of user accounts from the local, or the remote, system.  The ability to both query WMI and take actions from .NET in the same command is just one example of the flexibility and robustness of PowerShell, and it’s improvements over previous ways of managing one account at a time.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (6)

6 responses to “How To Change User Password With PowerShell”

  1. except this is stupid – you don’t even say how to get to this command line? What i mean is no where is [adsi] a functioning command line! Is this is some powershell shell? really? how about some complete instructions. this is totally worthless without the HOW TO START or BEGIN with….. and yes I can open a powershell and command prompt but [adsi] is not a command. geeez

    • You need to learn the basics of powershell before you get all pissy. He told you that [adsi] cast the variable as an object type. You don’t get to it. His instruction was great. You might want to stick to the gui.

  2. Hi David, thanks for the comment and for taking me to task on this.

    There are a lot of ways to set a user account password with PowerShell.

    What I was trying to show with this article was how to use the ADSI class to have 1 way to set a password for either a domain account or a local account.

    If you’re trying to set a domain password with PowerShell, you could very easily do this using the ActiveDirectory module.

    1) Install Remote Server Administration Toolkit for your workstation OS

    2) Open PowerShell using an account that has permissions to manage user accounts in your domain

    3) Enter “Import-Module ActiveDirectory”

    4) Save a password as a secure string
    $NewPassword = Read-Host “Enter Password” -AsSecureString

    5) Update the password for a user

    Get-ADUser | Set-ADUser -Password $NewPassword

    But that command doesn’t work with local accounts.

    To work with local accounts, you need to use the ADSI object. Here’s all the details about the ADSI object.
    http://msdn.microsoft.com/en-us/library/aa772208(v=vs.85).aspx
    The [ADSI] used here is not a command, it’s casting the object as a specific type.
    If you just type in [ADSI] into a PowerShell session, it will output an object of that type. While it’s not a “command”, it does process.
    Then look at the difference between these two things:
    1) This line, complete with quotes, makes a string:
    “WinNT://MYPCHostname/Administrator”
    The output of that string is just a line of text, without quotes.
    2) This line, being CAST as an ADSI object
    [ADSI]”WinNT://MYPCHostname/Administrator”
    The output of that is not just a string, but the user account object of my Administrator account. Once the ADSI object is returned, it opens up the opportunity for us to use the “SetPassword” method on the ADSI object.
    Does this help clear it up? I hope so, but let me know if there is something more specific that I can help with, I’d be happy to help you get rolling.
    -Flash

Leave a Reply

Live Webinar - Thursday, December 2nd! Active Directory Masterclass: AD Configuration Strategies for Stronger SecurityREGISTER NOW - Thursday, December 2, 2021 @ 1 pm ET

Active Directory (AD) is leveraged by over 90% of enterprises worldwide as the authentication and authorization hub of their IT infrastructure—but its inherent complexity leaves it prone to misconfigurations that can allow attackers to slip into your network and wreak havoc. 

Join this session with Microsoft MVP and MCT Sander Berkouwer, who will explore:

  • Whether you should upgrade your domain controllers to Windows Server
    2019 and beyond
  • Achieving mission impossible: updating DCs within 48 hours
  • How to disable legacy protocols and outdated compatibility options in
    Active Directory

Sponsored by: