Securely Storing Credentials with PowerShell

When you write a script that uses credentials to access a resource, there is always the dilemma of how to request or store those credentials, especially when other users are going to use your script. Your options are:

  1. Use Integrated Windows Authentication.
  2. Request the username and password every time you run the script.
  3. Store the username and password in the script itself.
  4. Store the username and password in a file protected with an ACL.
  5. Store the username and password in an encrypted file.

Using Integrated Windows Authentication (IWA) is by far the most secure option, and you should always use this if possible. The problem is: IWA only works if the resource is Active Directory aware and in the same Active Directory domain or a trusting domain.

If you can’t use IWA, then entering your credential every time you start a script gets annoying very fast, especially if you have to enter your credentials several times a day.

Storing your username and password in the script itself is the worst choice you can make. And storing credentials in an unencrypted file, which hopefully only you have access to, is not much better. Remember: administrators can get access to any file.

The only option left is storing your credentials in an encrypted file. But wait… where do you store the decryption key? That is where the PowerShell “ConvertFrom-SecureString” and “ConvertTo-SecureString” cmdlets come to the rescue.

At first, these cmdlets don’t seem to help much. But if you don’t specify the -Key or -SecureKey parameters, the Windows Data Protection API (DPAPI) is used. And DPAPI uses your logon credentials to encrypt and decrypt the data. That means you don’t need an encryption or decryption key at all.

At this point, I could show you examples of how to use these cmdlets, as many others already did. But instead, I have a better option: a PowerShell module you can use in your own projects that does all the hard work for you. It is a wrapper around Get-Credential, with some extra features. You can download it here: https://bitbucket.org/metisit/credentialmanager/src

To use it, Import the module in your PowerShell session and/or script with:

Import-Module CredentialManager.psm1

The cmdlet defined in this module is Get-StoredCredential, and it works just like Get-Credential, with an extra mandatory argument: the name of the credential, for example:

Get-StoredCredential -Name vCenter

or for short:

Get-StoredCredential vCenter

The first time you use Get-StoredCredential with a certain name, the cmdlet calls Get-Credential to get the username and password and stores it somewhere encrypted, normally in %HOME%\Credentials.

thblog-fig1

The next time you use it with the same name, it will try to decrypt the credential and, if that succeeds, it will return the credential immediately, without any prompts.

 

thblog-fig2

The Get-StoredCredential cmdlet is fully documented, so you can just type:

Get-Help Get-StoredCredential -Detailed

To see a full description of the cmdlet with all options and some examples.

Happy coding!

12 oktober 2016
Theo Hardendood