Powershell: How to encrypt and store credentials securely for use with automation scripts.

Jul 2013

Powershell: How to encrypt and store credentials securely for use with automation scripts.

comment icon12 comment(s) |

I recently worked on a quick and dirty Powershell script to send me email notifications when content on a web page changed. To send the email, I also went for the quick and dirty method and just used SMTP with my Gmail account. After I finished this dirty masterpiece, I couldn't handle seeing my password sitting in plain text, and I knew something had to be done. Here is how I solved this dilemma:

Step 1: Create your encrypted password file.

First you need a standalone .ps1 script to generate your password file. The following code will achieve this:

<# Set and encrypt credentials to file using default method #>

$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content c:\scripts\encrypted_password1.txt

Run this script in Powershell, remember to set the execution policy appropriately, and Windows will prompt you for a username and password. Username isn't important since we are just storing the password, but go ahead and enter it anyway. This will create a text file in the specified location with a hash of your password. They "key" to this...Wah wah...is your Windows account. If you don't specify a Key or SecureKey parameter, the default is to use the Windows Data Protection API. Basically, that means using your Windows profile as the key. Note that it's also specifc to the machine where you encrypted it. So, you can't decrypt with the same account from another machine. For more information check out this long boring article: http://msdn.microsoft.com/en-us/library/ms995355.aspx. Why wouldn't I specify a key? Laziness mostly, and I like methods that integrate with Windows authentication. More importantly, I didn't see an obvious way of making the the key secure and accessible. In a production environment, I would recommend a service account used solely for creating and running the encryption and automation scripts.

Step 2: Use the encrypted password file in your automation scripts.

Here is a simplified snippet of code using the encrypted password:

    Set some variables
$emailusername = "myemail"
$encrypted = Get-Content c:\scripts\encrypted_password.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($emailusername, $encrypted)

if($something = $somethingElse)
        Do some stuff

    $EmailFrom = "[email protected]"
    $EmailTo = "[email protected]"
    $Subject = "I did some stuff!" 
    $Body = "This is a notification from Powershell." 
    $SMTPServer = "smtp.gmail.com" 
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
    $SMTPClient.EnableSsl = $true 
    $SMTPClient.Credentials = $credential;
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

Note the secret sauce that imports the password on lines 6 and 7. We don't specify any parameters with the ConvertTo-SecureString method because we want it to use the Windows account running the script for decryption, exactly like we did with the ConvertFrom-SecureString for the encryption. After that we can use that credential object willy nilly, example on line 23.

I hope this has been helpful in showing that with a small amount of effort you can get away from storing passwords in plain text in your Powershell scripts.


July 12, 2013


Stored Credentials

This is a very common problem and you can also use the Credential Manager built in to Windows to store those credentials and access them from Powershell.


July 15, 2013


Thanks for the comment Chris.

Thanks for the comment Chris. I didn't think to store credentials like that. That would definitely make this easier to manage, rather than a bunch of text files. But again this was just a quick and dirty way to get the job done. I guess SEO hadn't settled in on your post or I might have come across it while I was working this :).

October 7, 2013


SQL and encrypted pwd

Your script on stroing encrypted creds works great. I have SQL code accessing a database. I have been passing the read-only creds in the script itself. I tried your script but it won't work as the COnnection string wants an UNencrypted pwd. ANy ideas how I might do this?

October 30, 2013



Is this MSSQL? If so can you use integrated security instead?

July 21, 2013


Also works with Export-CliXml

Definitely a good read, didn't realize it could be stored that way. Personally I export credentials using Export-CliXml, it makes importing a bit simpler and you get back an entire PSCredential object rather than just the password. It still uses the same Windows Data Protection API.

Always nice to know more ways to get the job done though!

October 17, 2013


Gmail with encrypted password

The encryption do well but when i do try to pass the credential with your code , i always have the follwing error

The SMTP server requires a secure connection or the client was not authenticated.

Any idea what's wrong?

October 30, 2013


Does it work if you don't

Does it work if you don't encrypt the credentials?

March 7, 2014


thank you

This simple thing really helped me out. I'm new to PowerShell and when it actually worked, I felt like I could take on the world lol.

June 6, 2014


Sorry for the late reply

You can do this with ftp as well, but you will want to use the Net.FtpWebRequest object. It has a Credentials property that you should be able to pass these credentials to. You could also use your one line method like this: ftp://$emailusername:$[email protected]

July 7, 2014

Daniel Seisun

Possible to completely decrypt the hash?

Great article, but out of curiosity is it possible to completely decrypt the hash back to your original string, and not just do hash matching with powershell specific objects? The most direct use case for this being for use with tabcmd scripts (Tanner's blog post here: https://www.interworks.com/blogs/tladd/2013/08/22/automated-pdf-email-di...)

July 7, 2014

Daniel Seisun

Answered my own question

Yup, you can. There's a great blog post about how to do it here: http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/26/decrypt-po...