It’s important not to hardcode plain-text passwords anywhere, let alone in the code you’re writing. This isn’t a great idea. We need to use passwords often in PowerShell scripts, so how do we make it happen? Encryption.
You don’t have to be a cryptographer to use encryption with PowerShell. You merely need to understand how to encrypt and decrypt strings with PowerShell, and this article is here to help!
The word “encryption” is a big topic. We’re going to cover a few ways to encrypt and decrypt strings in PowerShell. These strings will be passwords, and we’ll go over how to store these encrypted passwords on disk so they can be reused in other scripts, if necessary.
Creating a Certificate
The first step we’ll do is to create a certificate. For our purposes, we’ll produce a self-signed certificate. You could also use a certificate issued by a certificate authority, but since I don’t have one of those in my environment, nor do I want to pay for a public one, I’ll create one on my own. To do that, I can use the New-SelfSignedCertificate command.
Since we’ll be encrypting passwords, we’ll create a cert using Document Encryption in my user’s personal certificate store:
Once I have the certificate created, I can now use it to encrypt data a few different ways.
Encrypting with CMS
Using the Protect-CmsMessage PowerShell cmdlet, I can simply pass any string I’d like to it using the To parameter indicating a certificate to encrypt it with using the subject. Below, I’m encrypting the string Text to Encrypt using the certificate I just created:
Once created, I can then view some useful information about this CMS message using Get-CmsMessage:
Once I need to decrypt the string, I then use Unprotect-CmsMessage to see what the original string was:
We can easily add this encrypted string to a file and then decrypt it back, too:
Using Import/Export CLIXML
PowerShell has an object type called PSCredential and is used in many different contexts when scripting. For example, run Get-Credential where you’ll be prompted for a username and password. This type of object is more complicated than a simple string, but using the Import and Export-CliXml commands, we can easily store this type of object to disk encrypting the password.
For example, I can call Get-Credential, provide my username and password then save that credential to disk using Export-CliXml as shown below.
Once the credential is saved to disk, I then can reference that file across any script I choose using the Import-CliXml command. This command natively decrypts the password that was encrypted in the file:
At this point, you can either use the whole credential object on a Credential command parameter, or if you just need the password, call the GetNetworkCredential() method referencing the Password property to return only the password.
Now that you know of a couple of ways to encrypt and decrypt passwords, you should have no excuse to manage plain-text passwords again. Managing passwords securely takes a little bit more time and dramatically decreases the chances of nefarious individuals getting ahold of your passwords and using them for all the wrong purposes.