Save to My DOJO
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 taking a peak at your code. However, there are certain scenarios that 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?
Let’s say you need to routinely run a script against a group of non-domain joined servers, or you’d like to allow users to run a specific elevated task but don’t want to give them the elevated credentials. There are a few solutions around this, but there is a proper balance between security and accessibility and it takes some discerning on if a solution is secure enough to be accepted. Luckily with PowerShell, there are a few tricks we can use to hide our passwords, and while they are not 100% secure, it will still reduce the risk by a significant amount depending on the method.
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:\Passwords\password.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:\passwords\password.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:\Passwords\password.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:
Like 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 on. 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:\passwords\aes.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 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:\passwords\aes.key) | set-content "C:\Passwords\password.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:\Passwords\password.txt | ConvertTo-SecureString -Key (Get-Content C:\Passwords\aes.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.
Each method has it’s 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? Let us know in the comments section below!
More articles about how MSPs can make the most out of PowerShell in their operations:
Get a 30-day trial of Altaro VM Backup for MSPs
Manage all your customer VM backups from a single cloud console, on a monthly subscription. Try Altaro VM Backup for MSPs for 30 days - no strings attached!
Not a DOJO Member yet?
Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!