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
$username = "domain\admin" $password = "password" | ConvertTo-SecureString -AsPlainText -Force $cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
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
"password" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
The output is luckily not the unencrypted password we entered, it is a string containing the encrypted version of the password.
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b9fe0ca15a2ffb4a9e172d76a87afae40000000002000000000003660000c000000010000000875 eab73cc326c4acb70b609f170da6d0000000004800000a0000000100000001efe13d29355bea97995960f306c0009180000005a906fee5e408ccf685bbc56dd 1c3e3c91472d168c17d38a140000008bf9a9f060d1c46d1d96441d2080218ff0ada1a6
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
$password = "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b9fe0ca15a2ffb4a9e172d76a87afae40000000002000000000003660000c000000010000000875eab73cc326c4acb70b609f170da6d0000000004800000a0000000100000001efe13d29355bea97995960f306c0009180000005a906fee5e408ccf685bbc56dd1c3e3c91472d168c17d38a140000008bf9a9f060d1c46d1d96441d2080218ff0ada1a6"
The next step is to create the credentials object
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,($password | ConvertTo-SecureString)
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.
$password = Get-Content password.txt
To write the securestring directly to the file you can use this
read-host -AsSecureString | ConvertFrom-SecureString | Out-File password.txt
WARNING: This method will not prevent others from using the password, but at least its not in cleartext anymore.