I’ve always hated trying to store passwords for scheduled tasks and other automation in a TXT file with the standard ConvertTo-SecureString cmdlet for a couple of reasons….
Firstly, it’s not altogether that secure, and while it does obfuscate the password somewhat, it’s only just the tiniest bit removed from saving the value in clear text.
Second, and probably more frustrating, is that the value is “encrypted” using the Windows Data Protection API (DPAPI) so it will only work for the same user on the same computer, which means that if you create a scheduled task to run the script which uses the password, it will fail unless you happen to login to the system as the service account (or launch PowerShell as that user) and then issue the ConvertTo cmdlet so that when it’s decrypted the key used (ie. service account) will work. Not ideal.
So, in an attempt to add some additional security, and leverage Public Key encryption, I’ve built a PowerShell module (the CredentialVault) that I use to create a certificate and use that certificate to encrypt login information which can then be stored in an XML and used for credential automation.
The module consists of several cmdlets:
New-Certificate – creates a new certificate with the Subject name you provide. This certificate is used to encrypt passwords.
Test-Thumbprint – ensures that the thumbprint value for the certificate exists in the Local Machine certificate store, returns True if present on the system.
Encrypt-Credentials – Uses the certificate with the thumbprint specified to save to the specified XML file the encrypted credentials provided to the command.
Decrypt-Credentials – Uses the XML input file and thumbprint specified to decrypt the credentials stored in the XML and returns a PSCredential Object.
Test-CredentialStore – Uses the XML input file, thumbprint and connected system specified to read the XML, decrypt the credentials using the certificate and then test the password against the system specified.
In addition to certificate creation, thumbprint validation, encryption, decryption and credential testing, the module also contains some additional helper cmdlets:
- Test-ActiveDirectoryModule
- Test-ADCredentials
- Test-AzureCredentials
- Test-IsAdministrator
- Test-MSOnline
- Update-Credentials
The module is fully documented, so be sure to review these other cmdlets on their syntax and usage.
Credential Vault In Action
Now that we’ve reviewed the module and the primary usage, let’s walk thru creating a secure XML using a certificate, testing the thumbprint and resulting credential as well as how to use it for automation…
First, let’s create a certificate that will be used for the encryption of the credential.
Using the command New-Certificate, we will supply a Subject Name of “Secure Password Encryption”
Once the certificate has been created, we can obtain the thumbprint by navigating to the Local Machine Certificate Store within PowerShell by changing to the Certificate store using the command Cd Cert: then navigating to LocalMachine\My
Once in the Certificate store, the DIR, LS or GCI cmd will return a list of all the certificates.
Locate your certificate via Subject name, and record the Thumbprint value. You will be referring to this certificate using it’s Thumbprint from now on.
Next, you will want to create an XML file which contains the encrypted credentials that you plan to use. Just specify a target XML file, the credentials you want to encrypt and the certificate Thumbprint.
To do this, enter the command Encrypt-Credentials -XMLPath C:\temp\SecureCreds.xml -Thumbprint XXXXX
Since you did not provide any credentials, a dialog box will be displayed and prompt you for the credentials you want to store.
Enter your credentials and click OK
If everything worked as planned, you will be returned to the PowerShell command prompt.
Now, using Notepad, let’s take a look at the contents of the XML file we just created….
Notice that the resulting XML contains the User, Key and Payload. The Payload is actually the encrypted password!
Now that you have a credential stored as an XML, let’s use that in a script that connects to Azure.
In the screen shot below, you’ll notice that we are unable to issue the Get-MSOLUser cmdlet because we haven’t yet authenticated to Office 365. In fact the error states clearly that we need to use the Connect-MSOLService cmdlet first.
The Connect-MSOLService cmdlet, issued with no parameters, will prompt for credentials, however you can specify the parameter -Credential if you want to provide a credential.
The provided credential could be a variable that you defined previously in your PowerShell session, or in our case below, we’re issuing the Decrypt-Credential cmdlet with the path to the XML and the Certificate Thumbprint. We wrap that cmdlet in parenthesis so that it’s evaluated first. Remember, the command returns a PSCredential object.
Once the command has completed, we’re connected to MSOnline, and the Get-MSOLUser cmdlet works as intended….
As you can see, the CredentialVault module allows you to handle public key encryption of credentials with ease, allowing you to automate the use of credentials in your PowerShell scripts without sacrificing security.
Just remember that the Certificate is the key to the process, so it must be secured properly, just like you’d secure a password!
Some of my upcoming posts will rely heavily on the CredentialVault module, so stay tuned!
The CredentialVault module can be found on the TechNet Gallery here.