Safeguard Credentials using PowerShell Secret Management

Are you still hard-coding credentials in your PowerShell scripts? I hope not. But if you are, you must consider stopping that practice. Apart from not looking good for you as a scripter to use plain text passwords, it is a critical security risk for you and your organization.

You might ask, “can PowerShell store credentials securely?” Absolutely!

This post will help you get started with the transition from plain text passwords to encrypted credentials.

Requirements

  • Windows PowerShell 5.1 or PowerShell Core on any supported platforms (Windows, Linux, macOS). This post will be using PowerShell 7.2.7 on a Windows 10 computer.

Method 1: Exporting PowerShell Credential Objects to File

You can encrypt a PowerShell credential and save it to a file for later use, usually to an XML file. This method uses only built-in PowerShell cmdlets to save and retrieve the encrypted credential from the file.

ADVERTISEMENT

First, you must create the credential object; there are two ways you can do it.

Interactive using Get-Credential

The first way is to prompt for the credential and store it in a variable using the Get-Credential cmdlet.

$credential = Get-Credential

Enter the username and password to store into the variable.

powershell credential

Non-Interactive using the PSCredential Data Type

Instead of getting the credential from manual input, you can directly create the credential object by casting a PSCredential data type.

Note. This method is not secure because before you create the PSCredential object, you still have to expose the password on the host before encrypting.

First, convert the plain text password into a SecureString data type. In this example, the password is MyPassword. Don’t forget to replace MyPassword

$secureStringPassword = ConvertTo-SecureString -String 'MyPassword' -AsPlainText -Force

Next, create the credential object by running either of the below commands. Notice that the myusername is the username part of the credential.

$credential = [PSCredential]::new( 'myusername', $secureStringPassword ) 
$credential = New-Object -TypeName PSCredential -ArgumentList 'myusername', $secureStringPassword

You can see the two properties when you inspect the $credential variable. The UserName property value is exposed, and the Password is of System.Security.SecureString value.

powershell store credentials

Export and Import the Encrypted Credential Object

At this point, the credential is still stored in memory and usable only inside the current PowerShell session. So how do you make this credential reusable? You must export it to a file. Let’s export the credential object to an XML file in this case.

You must pipe the $credential variable to the Export-CliXml cmdlet and specify the output filename. In the below example, we’ll export the credential object to mycredential.xml.

ADVERTISEMENT
$credential | Export-Clixml .\mycredential.xml

Open the mycredential.xml in your editor. As you can see below, the XML file contains the data type information (System.Management.Automation.PSCredential), UserName, and Password. Notice that the password is not exposed in plain text.

powershell encrypted password

You can now reuse this PowerShell credential whenever you need it. To do so, you can import the XML file content using the Import-CliXml cmdlet.

$credential = Import-CliXml .\mycredential.xml 
$credential

powershell credential password

If you want to reveal the password, you’ll need to convert the value to plain text again.

In PowerShell Core, you can use the ConvertFrom-SecureString cmdlet.

# PowerShell Core - Secure String to Plain Text 
$mycredential.Password | ConvertFrom-SecureString -AsPlainText

powershell credentials in script

ADVERTISEMENT

The ConvertFrom-SecureString cmdlet does not exist in Windows PowerShell 5.1 and below. Don’t worry. The command below will achieve the same result.

# Windows PowerShell - Secure String to Plain Text 
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto( 
$([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR( 
$mycredential.Password 
)) 
)

powershell get current user credentials

An alternative is to call the GetNetworkCredential() method of the PSCredential object.

$credential.GetNetworkCredential() | Select-Object UserName,Password

windows powershell credential request

Question. Is the credential XML file portable? Answer: NO. Only the user account that created the credential object can access the secured password on the same machine.

Method 2: Using PowerShell Credential Vault

Storing encrypted credentials in files can become unmanageable, especially when you have multiple credentials. You have to keep track of which file contains which credentials you need.

Fortunately, you can use secret vaults with PowerShell now. You’ll need the Microsoft PowerShell Secret Management and Secret Store modules.

The Secret Store is the extension module that provides the vault, while the Secret Management module gives you the interface command to manage vaults and secrets. Both of these modules are free and work cross-platform.

ADVERTISEMENT

Install the Required Modules

As mentioned earlier, you’ll need to install two modules.

Install-Module -Name Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore

powershell secure credentials in script

Confirm that the modules are installed by running the below command.

Get-Module -ListAvailable "*.Secret*"

As of this writing, the latest versions are SecretManagement 1.1.2 and SecretManagement 1.06.

powershell get current user password

Create a Secret Vault

Now, let’s create a secret vault where you’ll store your credentials and other secrets. Run the below command to create a new vault named MySecretVault. The -ModuleName parameter indicates which module will provide the vault. In this case, the provider is Microsoft.PowerShell.SecretStore.

Register-SecretVault ` 
-Name 'MySecretVault' ` 
-ModuleName Microsoft.PowerShell.SecretStore ` 
-Description 'My credentials'

To ensure the vault was created, let’s list the vaults.

Get-SecretVault

You can see below that the MySecretVault exists. And since there’s only one vault, it is also the default.

powershell secure credentials

Create and Store New Credentials

Once you have a secret vault, you can add multiple secrets to it, making it easy to organize your credentials in a single location.

But before storing a new credential in your secret vault, here are the types of secrets you can store in the Secret Store vault.

  • PSCredential
  • HashTable
  • SecureString
  • String
  • byte[]

But in this example, we’ll use PSCredential as an example.

First, create the PowerShell credential object.

$credential = Get-Credential

secure password powershell

Next, add a new secret in the MySecretVault store. The -Name parameter specifies the secret’s name as you would see it inside the vault. The -Secret parameter accepts one of the five secret types. In this example, the secret is the PowerShell credential in $credential.

# Create a new secret named Secret1 
Set-Secret -Name mycredential -Secret $credential

The first time you add a secret to the vault, you will be asked to set a master password to protect the vault itself. Type in the master password and press Enter.

DO NOT FORGET THE MASTER PASSWORD!

password in powershell script

Disable the Vault Password Authentication Requirement

By default, the secret vault will be locked automatically after 900 seconds (15 minutes). And when it does, you’ll have to unlock the value with your master password, as shown in the command below.

Unlock-SecretStore

powershell store encrypted password

As you can imagine, this method of unlocking the vault is not suitable for unattended scripts. If you’re fine with unlocking the vault with a master password every so often, then you’re good at this point.

However, you can also disable the password requirement to unlock the vault. Run the command below if you choose to disable the vault password authentication.

Set-SecretStoreConfiguration -Authentication None -Interaction None -Confirm:$false

Even if you disable the vault password authentication, only your user account can access the vault.

Enter the current master password and press Enter to confirm the action.

powershell getcredential

Retrieve the PowerShell Credential Object from the Vault

At this point, you have already performed the following steps:

  • Installed the required modules.
  • Registered a new secret vault (MySecretVault).
  • Added a PowerShell credential to the vault.
  • Set the vault’s master password.
  • Disabled the vault’s password requirement.

The only thing left is retrieving the PowerShell credential from the vault.

First, let’s list the existing secrets in the secret vault.

Get-SecretInfo

As you can see, the result listed the secret’s name, type, and the vault where it is stored.

export encrypted credential object

Next, run the below command to retrieve the username and password from the mycredential secret.

(Get-Secret -Name mycredential).GetNetworkCredential() | ` 
Select-Object UserName, Password

create new credentials

Conclusion

Storing credentials in plain text is bad practice and can pose security risks to your account, systems, and organization. Can PowerShell encrypt passwords? – Yes. Can PowerShell store credentials securely? – Yes.

It’s hard to justify risking exposing flat passwords when the alternative is not complicated to implement, more secure, and free. Don’t get lazy caught with your password exposed; up your game with the PowerShell credential and secret management techniques you learned in this post.

I enjoy technology and developing websites. Since 2012 I'm running a few of my own websites, and share useful content on gadgets, PC administration and website promotion.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.