Skip navigation
security_lock_pixels_alamy.jpg Alamy

How To Manage Credentials in PowerShell

There are three popular techniques for PowerShell credential management. Learn about each option and associated security risks.

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.

Options for PowerShell Credential Management

There are three main options that are generally used for PowerShell credential management (as well as a few other options that aren’t quite as popular). Unfortunately, none of these options will work perfectly for every situation.

1. Use the Get-Credential cmdlet

The first option is to simply design the script so that it prompts the user for a password. This is easily accomplished by using the Get-Credential cmdlet, which you can see in Figure 1.

Brien PoseyPowerShell screenshot shows Get-Credential cmdlet prompting user to enter a set of credentials

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.

2. Store credentials in an encrypted file

The second option is to store the credentials in an encrypted file. This technique, too, is easy to accomplish and has been a PowerShell staple for years.

The process can be done in essentially two steps.

The first step is to create the password file using the following command:

(Get-Credential).Password | ConvertFrom-SecureString | Out-File "C:\Scripts\password.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.

3. Create a variable to store credentials

Using the stored credentials is almost as easy. Suppose that a script needed 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. Often, you will see a script that includes a line such as this:

$Cred=Get-Credential

As you can see in Figure 2, 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.

Brien PoseyPowerShell screenshot shows $Cred variable

Figure 2. The $Cred variable stores the password in an encrypted format.

So, 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:\Scripts\password.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.

Brien PoseyPowerShell screenshot shows how you create and use a password file

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 

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 also extend 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 so to prevent the scripts from being used for anything other than their designated purpose.

There are multiple ways to accomplish this. One of the easiest ways 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 user access

Another thing that you can do is try to prevent any users from gaining access to 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. If your organization makes use of Active Directory resource domains for example, they might be a good place to store your PowerShell scripts and password files.

Alternatives to storing passwords in encrypted files

Unfortunately, it’s probably impossible to ever harden a PowerShell script and password file to the point where it becomes 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.

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.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish