As an MSP, managing passwords in PowerShell scripts can be a dicey task. There is always a risk that someone may find the password by simply peering at your code. However, certain scenarios call for “storing” a password somewhere and referencing it in a script for authentication. To do this safely, you’ll need to encrypt them, and you can do this using PowerShell. If you’re new to PowerShell, don’t worry it’s not too difficult!

Why Should I Encrypt Passwords?


As a savvy tech professional, you’re likely aware of the dangers lurking in the digital shadows, but have you considered the full extent of risks associated with unencrypted passwords in your PowerShell scripts? Let’s dive into why encrypting passwords isn’t just a good practice—it’s essential for maintaining robust security in an ever-evolving cyber landscape.

    • Protecting Sensitive Information 
First and foremost, PowerShell scripts often handle sensitive data that can range from user credentials to critical system configurations. Without encryption, these passwords are exposed in plain text, making them vulnerable to unauthorized access. Imagine if these scripts were compromised – it would be akin to leaving your house keys under the doormat. Encryption acts as a robust lock, safeguarding your sensitive information from prying eyes.

      • Compliance with Security Standards 
In the world of information security, compliance with standards and regulations is non-negotiable. Encrypting passwords in PowerShell scripts is not just a best practice; in many cases, it’s a requirement. Standards like GDPR, HIPAA, and PCI-DSS mandate stringent data protection measures. By encrypting passwords, you’re not just securing data but also aligning with these crucial regulatory frameworks, thereby avoiding potential legal and financial penalties.

      • Mitigating Insider Threats 
It’s a harsh reality, but not all security threats come from outside your organization. Insider threats, whether intentional or accidental, are a significant risk. By encrypting passwords in PowerShell, you’re putting an additional barrier between your sensitive data and any internal actors who might misuse it. This encryption ensures that even if someone has access to your scripts, they can’t misuse the passwords contained within.
 
      • Enhancing Security in Automation 
PowerShell is often used for automating tasks across multiple systems. When these automated scripts include plain text passwords, it’s like sending a confidential letter in a clear envelope. Encryption ensures that even if the automation process is intercepted or logs are accessed, the confidentiality of your passwords remains intact.
 
      • Safeguarding Against External Threats 
Cyber threats are evolving rapidly, and hackers are constantly devising new methods to breach systems. Encrypted passwords in PowerShell scripts act like a moat around your digital fortress, deterring hackers. If a cybercriminal accesses your scripts, they’ll find the passwords inaccessible, thwarting their malicious intentions and safeguarding your network.

      • Expand the Scope of Security
Beyond these fundamental reasons, encrypting passwords in PowerShell scripts also plays a pivotal role in maintaining operational integrity for MSPs. In an age where data breaches can lead to significant operational disruptions, encryption serves as a critical line of defense. It ensures continuity and reliability in your automated processes, safeguarding not just data but also the seamless functioning of your systems.

      • Future-Proofing Your Security Posture
Moreover, as technology continues to advance, so do the techniques used by cyber adversaries. Encrypting passwords is not just about addressing current threats; it’s about future-proofing your security posture. By adopting encryption today, you are preparing your systems to withstand emerging threats that might evolve tomorrow. By now it should be common sense that you don’t “hard code” passwords into any sort of script like below:
$password = “MYPASSWORD”
Anyone can easily just open up your script file and read the password. Instead here are 3 more secure ways of passing credentials through to your PowerShell scripts

Using Task Scheduler


This is the easiest method of all. When configuring a task, Task Scheduler allows you to store your account credentials and will execute your specified script using those credentials: This is useful when running a script that needs access to file shares or any domain authenticated endpoint. However, task scheduler will only store 1 set of credentials and uses the Windows Data Protection API to encrypt/decrypt the password. This method uses the user account login credentials sort of as a “key” to access the stored password. The con to this method is, since the login credentials are being stored locally on the server, the script can only be run on the server that has the credentials cached and the Task Scheduler configured.

Create an Encrypted Password File


Another way we can go about hiding the passwords used in our PowerShell scripts, is by creating an encrypted password file and then referencing that password file in our script. Just like Task Scheduler, this method will encrypt using the Windows Data Protection API, which also means we fall into the same limitations of only being able to access the password file with one account and only on the same device that created the password file. The user login credentials are essentially the “key” to the password file. However, this method allows us to save multiple passwords and reference them in our script.

To get started we will create the password file by inputting the following syntax into a PowerShell console. Also, note that the user account you are using to create the password file is the same account that must be used to open the password file (Windows Data Protection API remember?):
(get-credential).password | ConvertFrom-SecureString | set-content "C:Passwordspassword.txt"
You will get a prompt for the password, input the credentials that you want to save. In our example an encrypted password file will be saved to “C:passwordspassword.txt”: When we open the file we can see that our credentials are encrypted: Now, how do we retrieve these credentials? Easy, if we ever need to retrieve these we include the following syntax in our scripts to provide the creds:
$password = Get-Content "C:Passwordspassword.txt" | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential("Luke",$password)
Then just pass $credential to whatever cmdlets need a pscredential to authenticate. If we look at what’s in the $credential variable we can see our username and its encrypted password: As I said before, you still fall under the limitation of requiring the same user account to run the script and only on the same machine that you created the password file. Thankfully, there is a 3rd option that allows us to get around this.

Creating a Key File and Password File


With PowerShell, we can generate a 256-bit AES encryption key and use that key to access our password file. First, we input the following syntax to create our key file. You could take this key and put it on a network share and only give specific users access to the key along with the password file. But, in this example we will just save it to C:passwords with our password file:
$Key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file C:passwordsaes.key
If we open the aes.key in notepad we can see our key is now generated: Now, we create a password file just like the one above. However, we use the -key parameter to specify that we want to use a key and input the location of the key file. Then, we create the password file. In this example, we’ll output the password file to our C:passwords directory:
(get-credential).Password | ConvertFrom-SecureString -key (get-content C:passwordsaes.key) | set-content "C:Passwordspassword.txt"
Now that we have our password file and our key file. We can simply recall our password from any script by including the following syntax in the script:
$password = Get-Content C:Passwordspassword.txt | ConvertTo-SecureString -Key (Get-Content C:Passwordsaes.key)
$credential = New-Object System.Management.Automation.PsCredential("Luke",$password)
When we look at the data inside the $credential variable we can see that we have the username and password now.

Wrap-Up


Each method has its own pros and cons. However, keep in mind that all of these ways are not 100% foolproof. So, I would not advise doing this with a domain administrator account. Just enough access (JEA) is the way to do it, so I would recommend creating an account with just enough access to do what it needs to do.

How about you? What interesting ways have you used to get around the issue of storing credentials in plaintext?

More articles about how MSPs can make the most out of PowerShell in their operations:

Using SFTP

Working with REST APIs

HTML Tables for Reporting