How To Manage Credentials in PowerShell
Learn best practices for managing credentials in PowerShell, including three popular techniques. We also provide tips for handling PowerShell security vulnerabilities.
November 15, 2022
Historically, credentials have always presented a bit of a problem for PowerShell scripts.
Many PowerShell scripts require authentication before the script can run. That means that script authors must figure out how to get the necessary credentials to PowerShell without compromising security in the process.
Use the Get-Credential Cmdlet
One technique for managing PowerShell credentials is to simply make the script prompt users for a password. This is easily accomplished by using the Get-Credential cmdlet, which you can see in Figure 1.
PowerShell Credentials 1-1
Figure 1. The Get-Credential cmdlet will prompt you to enter a set of credentials.
The main disadvantage to this technique is that it only works if the script is being run interactively. A script that is meant to run unattended cannot stop and wait on an administrator to enter a password.
Store Credentials in an Encrypted File
Alternatively, you can store the credentials in an encrypted file. Like the Get-Credential cmdlet technique, this is easy to accomplish and has been a PowerShell staple for years.
The process can be done in essentially two steps.
First, create the password file using the following command:
(Get-Credential).Password | ConvertFrom-SecureString | Out-File "C:Scriptspassword.txt"
The above command will prompt you for a set of credentials.
PowerShell will then take just the password portion of the credential set and write it in encrypted form to a password file named password.txt.
Use a Variable to Store Credentials
There’s a third option you can use for managing PowerShell credentials.
Suppose that a script needs to pass a set of credentials to a remote PowerShell session. To do this, you can create a variable containing the credentials.
Using a variable to store credentials is a common practice even for interactive logons. You will often see a script that includes a line such as this:
$Cred=Get-Credential
In Figure 2, notice that once the credential has been entered, the variable contains two pieces of information: 1) a username that is stored in plain text, and 2) a password that is stored as a secure string.
PowerShell Credentials 1-2
Figure 2. The $Cred variable stores the password in an encrypted format.
With that in mind, think back to the line of code that we used to create a password file. It is different from the $Cred variable that we just looked at because it contains only a password, not a username and password combination. That means that if you want to use the password file to supply credentials to a script, you will have to combine the password that is stored in the file with a username that is stored elsewhere.
The most common method for doing this involves hardcoding the username and then reading the password from a file. Those two pieces of information are then added to a PsCredential object.
Here is what the code looks like:
$password = Get-Content "C:Scriptspassword.txt" | ConvertTo-SecureString $Cred = New-Object System.Management.Automation.PsCredential("Brien",$Password)
The first line of the above code defines a variable named $Password. PowerShell reads the encrypted password file and converts it to a secure string. This conversion is necessary because the password must be put into a format that PowerShell can work with. Once the conversion is complete, the $Password variable will contain the password in secure string format. Typing $Password will not reveal the clear text password, although there is a way to decrypt a password file and reveal the passwords within.
The second line of code creates a variable named $Cred. Rather than assigning credentials to this variable by using the Get-Credential command as we did before, we are creating a PsCredential object and assigning that object the username (“Brien”) and the password that is stored in the $Password variable.
So, let’s see what this looks like in practice. In Figure 3, you can see that the first command I typed created the password file. Next, I used the Type command to display the contents of the password file that I just created. The result was a long hexadecimal value. Using the Type command is not a required step. I simply used this command to illustrate that the password is indeed encrypted.
PowerShell Credentials 1-3
Figure 3. This is how you create and use a password file.
The next two things that I did was create the $Password variable and display its contents. PowerShell shows the contents to be System.Security.SecureString.
The last step in the process was to create the $Cred variable. As you can see, I combined a hardcoded username with the contents of the $Password variable into a PsCredential object. When I display the contents of the $Cred variable, they are the same as if I had used $Cred=Get-Credential instead of reading the password from a file.
Security Concerns with PowerShell Credentials
Now that I have explained how to create and use a password file, then use that file to pass a set of credentials to a PowerShell script, I will discuss associated security issues.
There are two main problems with using a password file like the one I created above.
The first problem is that it is possible to decrypt a password file and reveal the password in plain text. Password decryption is beyond the scope of this article, but it can absolutely be done.
The second problem is that a cybercriminal can use the file without having to decrypt it. Think about how we put the password file to work: PowerShell simply read the file and combined it with a hardcoded username to form a set of credentials that could be used to access to a resource. In other words, having access to the script file and the password file is just as good as knowing the actual credentials. A cybercriminal could easily build their own PowerShell script that uses the password file you have already created.
This, of course, raises the question of what you can do to better secure PowerShell authentication. There are different solutions for different situations, so you must determine which solution is the best fit for you.
Create Dedicated User Accounts for Each PowerShell Script
First, you can and should be practicing Least User Access. Normally, Least User Access refers to the practice of giving end users only the bare minimum permissions that they need to do their jobs. However, this same concept can apply to PowerShell scripts.
It would be a major security risk to create a password file that grants a PowerShell script full-blown administrative access. Likewise, it would also be unsafe to create a generic set of credentials that are used by all your PowerShell scripts.
A better approach is to create a dedicated user account (and corresponding password file) for each of your PowerShell scripts. Once each script uses a dedicated user account, you can lock down the user accounts. This will prevent the scripts from being used for anything other than their designated purpose.
There are multiple ways to accomplish this. An easy way is to use role-based access control. Another option is to use access control lists.
Remember, in a Windows environment, a specific denial of permissions overrides any permissions that have been granted. In other words, you can deny your PowerShell user accounts access to anything that those accounts do not absolutely need.
Prevent Access to Password Files or Scripts
Another thing you can do is prevent users from accessing your password files or the scripts themselves. This will generally require a bit of creativity, but there are several ways to approach the problem.
You might, for example, store the scripts and the password files in locations that are completely inaccessible to end users. For example, if your organization makes use of Active Directory resource domains, they might be a good place to store your PowerShell scripts and password files.
Use Certificate-based Authentication
Unfortunately, it’s probably impossible to harden a PowerShell script and password file to the point where it is impossible for a determined attacker to exploit the stored credentials. There are, however, techniques you can use as an alternative to storing a password in an encrypted file.
One such technique involves using certificate-based authentication. The basic idea is that rather than using a username and password combination, PowerShell scripts rely on digital certificates that have been installed on the machine where the script is running. Because such certificates can positively identify the machine, they can be used as an alternative authentication mechanism.
Download PowerShell Credential Manager
One more possible option is to use the PowerShell Credential Manager.
Credential Manager is a downloadable PowerShell module that adds four PowerShell cmdlets:
Get-StoredCredential
Get-StrongPassword
New-StoredCredential
Remove-StoredCredential
The Get-StrongPassword cmdlet is essentially a password generator that will create strong passwords. You can then use the New-StoredCredentials cmdlet to store a set of user credentials in a secure location. Whenever you need to put a stored credential to work, just use the Get-StoredCredential cmdlet. And, of course, you can use the Remove-StoredCredential cmdlet to delete a stored credential that you no longer need.
About the Author
You May Also Like