Handling Secrets Securely in PowerShell
Hardcoding passwords or API keys in your scripts is a major security risk. If your script is shared or committed to version control, your secrets are compromised. This guide covers secure alternatives.
Parent Topic: PowerShell Scripting and Programming Related: PowerShell Comprehensive Guide
1. Interactive Prompts (Manual Execution)
If a human is running the script, ask them for the secret at runtime.
Read-Host -AsSecureString
Converts input into a SecureString immediately. The plain text is never stored in memory.
$token = Read-Host "Enter API Token" -AsSecureString
# To use it (e.g., for an API call), you might need to convert it back temporarily
$plainToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token))
Get-Credential
Prompts for a username and password using the standard Windows dialog.
$cred = Get-Credential
# Usage
Connect-ExchangeOnline -Credential $cred
2. The SecretManagement Module (Recommended)
For automation or managing multiple secrets, Microsoft's SecretManagement module is the industry standard. It provides a common set of cmdlets (Get-Secret, Set-Secret) that work with different "Vaults" (Local, Azure Key Vault, KeePass, etc.).
Installation
Install-Module Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore -Repository PSGallery -Scope CurrentUser
Setting up a Local Vault
The SecretStore vault encrypts secrets on the local disk for the current user.
# Register the local store
Register-SecretVault -Name LocalStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
# Save a secret
Set-Secret -Name "GitHubAPI" -Secret "ghp_123456789"
Retrieving a Secret
In your script, you simply request the secret by name.
$token = Get-Secret -Name "GitHubAPI" -AsPlainText
3. Encrypted Files (Legacy/Simple)
You can save a SecureString to disk. Note: This file can only be decrypted by the same user on the same computer that created it.
Saving Credentials
$cred = Get-Credential
$cred.Password | ConvertFrom-SecureString | Set-Content "C:\Secure\cred.txt"
Loading Credentials
$encrypted = Get-Content "C:\Secure\cred.txt" | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential ("username", $encrypted)
4. Azure Key Vault (Cloud Automation)
For scripts running in the cloud (Azure Automation, Functions), use Azure Key Vault.
# Requires Az module and authentication
$secret = Get-AzKeyVaultSecret -VaultName "MyVault" -Name "DatabasePassword"
$password = $secret.SecretValueText
Return to PowerShell Scripting and Programming