Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the Windows PowerShell Cookbook, 3rd edition.

If you own the book already, login here to get free, online, searchable access to the entire book's content.

If not, the Windows PowerShell Cookbook is available at Amazon, O'Reilly, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".

Securely Store Credentials on Disk

Problem

Your script performs an operation that requires credentials, but you don’t want it to require user interaction when it runs.

Solution

In PowerShell version 3, use the Export-CliXml and Import-CliXml cmdlets to import and export credentials. In PowerShell version 2, use the ConvertFrom-SecureString and ConvertTo-SecureString cmdlets.

Save the credential’s password to disk

The first step for storing a password on disk is usually a manual one. There is nothing mandatory about the filename, but we’ll use a convention to name the file CurrentScript.ps1.credential. Given a credential that you’ve stored in the $credential variable, you can safely use the Export-CliXml cmdlet to save the credential to disk. Replace CurrentScript with the name of the script that will be loading it:

PS > $credPath = Join-Path (Split-Path $profile) CurrentScript.ps1.credential
PS > $credential | Export-CliXml $credPath

In PowerShell version 2, you must use the ConvertFrom-SecureString cmdlet:

PS > $credPath = Join-Path (Split-Path $profile) CurrentScript.ps1.credential
PS > $credential.Password | ConvertFrom-SecureString | Set-Content $credPath

Recreate the credential from the password stored on disk

In the script that you want to run automatically, add the following commands for PowerShell version 3:

$credPath = Join-Path (Split-Path $profile) CurrentScript.ps1.credential
$credential = Import-CliXml $credPath

In PowerShell version 2, you must manually create a PSCredential object, using the password imported by the ConvertTo-SecureString cmdlet. Whereas the Export-CliXml cmdlet keeps track of the credential username automatically, this alternate approach needs to keep track of it by hand:

$credPath = Join-Path (Split-Path $profile) CurrentScript.ps1.credential
$password = Get-Content $credPath | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential `
    "CachedUser",$password

These commands create a new credential object (for the CachedUser user) and store that object in the $credential variable.

Discussion

When reading the Solution, you might at first be wary of storing a password on disk. While it is natural (and prudent) to be cautious of littering your hard drive with sensitive information, the Export-CliXml cmdlet encrypts credential objects using the Windows standard Data Protection API. This ensures that only your user account can properly decrypt its contents. Similarly, the ConvertFrom-SecureString cmdlet also encrypts the password you provide.

While keeping a password secure is an important security feature, you may sometimes want to store a password (or other sensitive information) on disk so that other accounts have access to it. This is often the case with scripts run by service accounts or scripts designed to be transferred between computers. The ConvertFrom-SecureString and ConvertTo-SecureString cmdlets support this by letting you specify an encryption key.

Note

When used with a hardcoded encryption key, this technique no longer acts as a security measure. If a user can access the content of your automated script, that user has access to the encryption key. If the user has access to the encryption key, the user has access to the data you were trying to protect.

Although the Solution stores the password in the directory that contains your profile, you could also load it from the same location as your script. To learn how to load it from the same location as your script, see Find Your Script’s Location.

For more information about the ConvertTo-SecureString and ConvertFrom-SecureString cmdlets, type Get-Help ConvertTo-SecureString or Get-Help ConvertFrom-SecureString.

See Also

Find Your Script’s Location

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.