Password Encryption for PowerShell
It has been a while since my last post. This one is really for you techs out there. Where I work is currently in the process of implementing Office 365 and Azure. This requires some scripting. More accurately it requires scripts to be run at night. But to connect to most cloud services you need to pass some credentials to make the connect. How to do this so the script doesn’t prompt you when it runs at 12:00am (some people would argue the over time would be worth it. Me I like my sleep). Password encryption to the rescue!
How do I pass credentials in a a script?
The easiest way is to hard code your username and password in clear text in the script. 🙁 That is the lazy admins way of doing things. Here is a better option.
Encrypt the password using some type of key then store the output to a protect file. How do we do this? Below I have broken a function I wrote into three parts. I will explain each of them.
Create your signing Key for Password Encryption
The first thing we need to do is create the key you will use to encrypt your password. To do that you use the New-Object commandlet. We specify the object to be bytes and we going to use 32bits. All of this will be assigned to a variable.
$AESKey = New-Object byte  32
Next we use a bit of .net code to encrypt
Now we just need to export the encryption key to a file. This file need to be secured latter.
$AESKeyFilePath = Read-Host -Prompt “please enter the full path and file name for the AES Key (e.g. C:\AESKey.txt)”
Set-Content $AESKEYFilePath $AESKey
Collect password to encrypt
Now that we have our unique key we need to get the password you want encrypted. To do this we read the password into a variable. For added security we hide the password with asterisks.
$InputPwd = Read-Host -Prompt “Please enter the password to encrypt” -AsSecureString
The content of $InputPwd is now secured so it can’t read due to the -AsSecureString switch. But it can still be easily decrypted. We need to encrypt it using the unique key we created. This is where we seem to take a step backwards by using some more .net code to read the secure text back to plain text. Here is the code we use.
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($InputPwd)
$PlainTxtPsswd = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
Why did we do that?
We could have left the console in clear text which meant that if someone was looking over your shoulder they could get the password. By masking the text with Asterisks this is no longer possible. However the -AsSecureString uses a combination of your user and machine GUID to make up the encryption key which means that the end result is not transportable between users and machines. Therefore we convert it back to plain text then use the AES key we created to encrypt making it completely portable.
Now for the last bit, taking that plain text password and converting it to a secure encrypted password then storing it in a file for later use.
$secureStringPwd = $PlainTxtPsswd | ConvertTo-SecureString -AsPlainText -Force
#Export Secure content to password file
$SecurePwdFile = Read-Host -Prompt “Please enter the full path and file name for the Secure Password file (e.g. C:\AppSecurePwd.txt)”
$password = $secureStringPwd | ConvertFrom-SecureString -Key $AESKey
Add-Content $SecurePwdFile $password
For extra security (as stated earlier) these files should be stored in a folder using NTFS security settings to limit who can actually read them.
Now when you want to use these files to pass credentials through a script you only need to add the following lines in your script (changing variables so they fit your naming convention or programming style):
$UserName = “YOUR USERNAME HERE”
$SecurePwdFilePath = “PATH TO YOUR PASSWORD FILE HERE”
$AESKeyFilePath = “PATH TO YOUR AESKEY FILE HERE”
$AESKey = Get-Content $AESKeyFilePath
$pwdTxt = Get-Content $SecurePwdFilePath
$securePwd = $pwdTxt | ConvertTo-SecureString -Key $AESKey
$credObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $securePwd
You now have a variable called $CredObject that can be used where-ever the -credential switch is used e.g. Connect-MSolService -Credential $CredObject
And there you have it. A secure and portable way to pass credentials via a PowerShell Script.
To download the entire script function click Hereby