Powershell: Working with Passwords

Filed under: Active Directory, PowerShell, Security — Written by Chrissy on Thursday, July 26th, 2007 @ 9:30 pm

When creating a new Active Directory user from the command line in PowerShell, you will likely find yourself using Read-Hosts's asSecureString switch when entering the password.


$password = Read-Host "Enter password" -AsSecureString

Next, you'll probably look around the Internets for a few hours or so trying to figure out how to change the password of the newly created user. You will soon discover that the user creation process in PowerShell 1.0 isn't very straightfoward and it even requires a specific order for proper account creation. First, you create the account, then you set some basic properties, next you call SetInfo(), and finally you invoke setPassword using the follwing syntax:


$newUser.psbase.Invoke("SetPassword",$password)

Now you may find yourself with the following exception: Exception calling "Invoke" with "2" argument(s): "Exception has been thrown by the target of an invocation." Originally, this post mentioned using toString() to address the problem but PowerShell team member Lee Holmes wrote to let me know that the password was changed literally to System.Security.SecureString. He also said that "there is no really easy way to convert a secure string to plain text - on purpose. Since a SecureString is supposed to prevent plain text from littering your computer's memory, converting it to plain text defeats the purpose."

My primary reason for using asSecureString is to encode the string into asterisks when typing it at the prompt. So Lee gave me two ways to convert the password to be used while invoking SetPassword. Note that unless you are using a secure LDAP channel, the password will be sent over the network in clear text.


$temporaryCredential = New-Object System.Management.Automation.PsCredential "None",$password
$newUser.psbase.Invoke("SetPassword",$temporaryCredential.GetNetworkCredential().Password)

Or, alternatively:


$temporaryCredential = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))$newUser.psbase.Invoke("SetPassword",$temporaryCredential)

If you continue to see this exception, check to make sure that the password you entered meets your domain's password complexity requirements.

4 Comments   -
  • Comment by povlhp | November 30, 2007 @ 1:49 am

    I have no luck converting a string into a securestring:

    0
    PS C:\scripts> $x = New-Object System.Management.Automation.PsCredential "None", "abekat"
    New-Object : Cannot convert argument "1", with value: "abekat", for ".ctor" to type "System.Security.SecureString": "Cannot convert value "abekat" to type "System.Security.SecureString". Error: "Invalid cast from 'System.String' to 'System.Security.SecureString'.""
    At line:1 char:16
    + $x = New-Object <<<< System.Management.Automation.PsCredential "None", "abekat"

  • Comment by bene | March 10, 2008 @ 5:01 am

    Hi,

    make the $password with " around and it works create.
    $newUser.psbase.Invoke("SetPassword","$password")

    You could also make $password.tostring():
    $newUser.psbase.Invoke("SetPassword",$password.ToString())

  • Comment by Robert | August 20, 2008 @ 2:06 pm

    Using this '$newUser.psbase.Invoke("SetPassword","$password")'

    I get an error
    Method invocation failed because [System.Management.Automation.PSMemberset doesn't contain a method names 'Invoke'

    Any ideas?

  • Comment by Troy | February 20, 2009 @ 12:50 pm

    I've seen and tried several methods now for changing passwords using Powershell. I am successfull when changing passwords in the same domain, but I manage a multidomain forest and the methods don't work from one to the next. In other words, from my management server in domainA I can't change a password of a user account in domainB. I have the permissions to do so, I am binding successfully and I can retrieve the user attributes. I can even change attributes, but I can't change the password. All my servers are Windows 2003 R2 SP2, the domains and forest level is native 2003.

Leave your comment