There are times when you want to securely save and retrieve information in PowerShell. Saving things like passwords and other credentials to plain text is not a good idea at all. To avoid that, you can use the Secure string feature of PowerShell. The most common way to do this is via the command:
$Secure = Read-Host –AsSecureString
This creates a secure string. After you enter the command, any characters that you type are converted into a secure string and then saved in the $secure variable. With this command, the characters you enter are not displayed on the screen.
Because the $secure variable contains a secure string, PowerShell displays only the System.Security.SecureString text when you try and view it. So the information to be secured is now saved as a protected variable called $secure in PowerShell. How can this now be written securely to a file so that it can be re-used later and still remain protected, even on the disk?
You can use the command Export-Clixml because a valuable use of this on Windows computers is to export credentials and secure strings securely as XML.
Thus, a better way to capture the value you want to save securely is probably via:
$Secure = get-credential -credential ClientID
Which will prompt you for the information as shown above. You will note that the User name filed has already been created thanks to the –credential parameter.
This will then give you a variable with a username (here ClientID) and a secure string that is a PowerShell credential.
You can then save the information via:
$clientid | Export-CliXml -Path .\clientid.xml
If the Export-Clixml is used to save that variable to a file (here clientid.xml), it will save it like shown above. You will note that the Password field is encrypted. This is where the secure information is kept, which is great, since it is now encrypted on disk.
The other great thing about using Export-Clixml is that:
The Export-Clixml cmdlet encrypts credential objects by using the Windows Data Protection API. The encryption ensures that only your user account on only that computer can decrypt the contents of the credential object. The exported CLIXML file can’t be used on a different computer or by a different user.
Thus, if the file with the saved and encrypted information is copied and used by another login on the same machine or on a different machine, you get the above result. Basically, it can’t be decrypted.
Of course, this isn’t perfect, but it does mean that once you have saved the information using the above technique the only way it can be decrypted is via the same logon on to the same machine. This means you don’t need to have secure variables saved as plain text inside scripts or in unprotected files on disk that can be copied and work anywhere. With this technique you can ensure that information saved to a file is encrypted and cannot be used by any other user or by any other machine. Thus, if someone got hold of the file, the information couldn’t be viewed or decrypted and thus access would be denied.
Hopefully, that should allow you to develop more secure PowerShell scripting.
3 thoughts on “Saving credentials securely with PowerShell”