Store encrypted password in a PowerShell script

I write a lot of PowerShell scripts where I need to access different kinds of services, servers and databases. Often these scripts needs to run on schedules in the background and so on.

Instead of having cleartext passwords scattered throughout the scriptfile I like to store a securestring version of the password in the script.

Normally you would build a credential object using something like this

That means that anyone who can open and read the scriptfile, will know what the password for the account in question is. Which is VERY BAD.

It would be better if we could create the SecureString from the content of itself (does that make sense?)

It turns out that you can in fact output the content of a securestring to a string using ConvertFrom-SecureString

The output is luckily not the unencrypted password we entered, it is a string containing the encrypted version of the password.

So in order to use this information as a password we need to reverse the process.

First we need to store the encrypted string in a variable

The next step is to create the credentials object

As you can see the magic stuff happens when you pipe the $password variable through ConvertTo-SecureString

So far I have not yet come up with a way the decrypt the encrypted string back to a readable value.

And the cool part is that it works everywhere you use –credentials (or at least for all the things I have tried so far)

If you prefer to store the password in an external file or a registry key you can that.

To write the securestring directly to the file you can use this

readhost AsSecureString | ConvertFromSecureString | Out-File password.txt

WARNING: This method will not prevent others from using the password, but at least its not in cleartext anymore.

By | 2017-09-07T22:55:56+00:00 September 10th, 2014|Powershell|16 Comments

About the Author:

Ronnie Jakobsen

Twitter: @RonnieJakobsen

16 Comments

  1. DexterPOSH September 11, 2014 at 4:05 - Reply

    Though it is not advised to store credentials on the disk. But if you are really looking to do this then I have found that Export-CLiXML and Import-CLiXML with PowerShell v3 make this a little bit easy.

    More details on how to here –> http://www.powershellcookbook.com/recipe/PukO/securely-store-credentials-on-disk

    Regards,

    • Ronnie Jakobsen
      Ronnie Jakobsen September 11, 2014 at 8:27 - Reply

      Nice alternative solution DexterPOSH, I am thinking about encrypting the file containing the password or credentials to improve security.

  2. Gyz September 12, 2014 at 11:52 - Reply

    In case you didn’t know, if you issue $cred.GetNetworkCredential().password you can have your password in cleartext..

    • Ronnie Jakobsen
      Ronnie Jakobsen September 12, 2014 at 16:21 - Reply

      @Gyz, you are right about that. So now I know … Thanks for your info

  3. micelshima December 10, 2014 at 14:20 - Reply

    No one but your user can execute the script.
    When a user encrypts a password he is the only one who can decrypt it.
    So there is no bother in getting the password in cleartext with $cred.GetNetworkCredential().password
    If you send that script to another user, when he executes it he will get an error with convertto-securestring cmdlet

    • Lewis December 16, 2014 at 0:21 - Reply

      Agreed, after playing with this stuff for about a day, I’ve decided it’s pointless.

      Instead, I ended up using PS2EXE to convert the PS to an EXE file to conceal the password in my ps file.

      • Roland April 19, 2016 at 11:09 - Reply

        the article you refer to is now on technet, I read:

        -extract:”Filename” Extracts the PowerShell script inside the EXE and saves it as “Filename”. The script will not be executed.

        not very secure if it was your intention to make it secure..

  4. yashpal April 14, 2015 at 11:32 - Reply

    Hello,

    I am trying to encrypt the password seprate and then use the same encryption in all other systems. but the issue is it is working fine only on the machine where I did encryption not on other machines.

    I am using below code:

    $test1 = “01000000d08c9ddf0115d1118c7a00c04fc297eb01000000ac83eb1515f4b44e84478d869b3f78ff0000000002000000000003660000c000000010000000cf044736de9f43b4a6a4d81bd65113310000000004800000a000000010000000786963e6a165bfc89e1eddc39b707e4830000000be609f5a88df9b72450ba756202f5e478759ec25f0eee89ee94f9b49b9ac02cb7c0421bbf8ab0ccec9f0b2b7dad488b714000000aee81fdb754414aed24d3bf91f2174ebb5e8a192”
    $test2 = “testdomaintestuser”
    $test3 = Convertto-SecureString -string $test1

    $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($test3)
    $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)

  5. […] method is similar to the one used in this blog post. I’ve modified it to work across all user accounts and passwords.  Generating the Secure […]

  6. […] Powershell: uložení šifrovaného hesla ve skriptu […]

  7. Tomasz July 30, 2015 at 11:17 - Reply

    Hi
    I tried to use this procedure to run program (exe file) as porcess

    Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File c:UserskowalskijDocumentsPassword.txt
    $password = type “c:UserskowalskijDocumentsPassword.txt” | ConvertTo-SecureString

    $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist “domainadministrator2”,$password

    Start-Process -Credential $cred -FilePath C:UserskowalskijDocumentsJava-64Bit.exe

    and….. error:

    start-Process : This command cannot be run due to the error: The directory name is invalid.
    .
    At line:1 char:1
    + Start-Process -Credential $cred -FilePath C:UserskowalskijDocument …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

    Do you know what does mean: This command cannot be run due to the error: The directory name is invalid.

    and how to solve it?

  8. Lang November 5, 2015 at 10:11 - Reply

    Try this to decrypt password to clear text:
    $cred.GetNetworkCredential().password

  9. Arman August 15, 2016 at 19:39 - Reply

    Guys,, I have used this info to create save an encrypted pass on a txt which I’m trying to pass as a parameter how ever its not working,,, script runs with no errors but the result says to me is not taking the password. could you please advise ?

    Im trying to execute a .batch file using another user/password, password is saved on pass.txt

    the .batch file basically opens a share folder which displays its content only to authorized users, the folder opens but no content is there so I assume is not taking the password

    $build = “c:file.bat”
    $username = “domainuser”
    $password = Get-content C:pass.txt
    $credentials = New-Object -typename System.Management.Automation.PSCredential -ArgumentList @($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
    $argu = “-Credential ($credentials)”
    Start-Process $build $argu

    Any help would be really appreciated

  10. math problem December 13, 2016 at 21:11 - Reply

    Hi there, its nice piece of writing about media print, we
    all be familiar with media is a fantastic source of facts.

  11. Sam March 7, 2017 at 6:43 - Reply

    I had created a PSCredential with the inline script and was able to access the credential until the PowerShell session which created the credential was open. When I have closed and reopened PowerShell to run the script again, I was not able to access $TFSAdminCred:
    $UserID = “xyz”
    $PswdFile = “\Server1TFSencrypt$Pswd.txt”
    $KeyFile = “\Server1TFSencrypt$AES.txt”
    $Key = New-Object byte[] 16
    [System.Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
    $Key | Out-File $KeyFile
    $Key = Get-Content $KeyFile
    $Pswd = “password” | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString -Key $Key | Out-File $PswdFile
    $TFSAdminCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList

Leave A Comment