🎁 New User? Get 20% off your first purchase with code NEWUSER20 Β· ⚑ Instant download Β· πŸ”’ Secure checkout Register Now β†’
Menu

Categories

PowerShell SecretManagement and SecretStore: Stop Hardcoding Credentials (2026)

PowerShell SecretManagement and SecretStore: Stop Hardcoding Credentials (2026)
PowerShell SecretManagement and SecretStore guide

Open any PowerShell script that has been in production for more than a year and you will probably find at least one of these patterns: a password as a literal string, a hashed credential file with the key sitting in the same folder, or a comment that says "TODO: move this to env var" from 2021. Every single one of those is a security incident waiting to happen.

Microsoft fixed this. Two officially supported modules β€” Microsoft.PowerShell.SecretManagement and Microsoft.PowerShell.SecretStore β€” give you a clean, vault-agnostic API for storing and retrieving credentials. The same script can talk to a local encrypted file, Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, or 1Password without code changes. This guide is the practical setup, with patterns for both interactive use and unattended CI/CD jobs. Free PDF cheat sheet at the end.

Why SecureString and Export-Clixml are not enough

For years the standard PowerShell answer to "how do I store a password" was: Get-Credential | Export-Clixml -Path .\creds.xml. This works, but it is not actually secure in the way most people assume. The encrypted file is bound to the user account and the machine β€” copy it to another box and it cannot be decrypted. Stay on the same box and any process running as the same user can decrypt it. There is no audit trail, no rotation, no scoping, and no way to revoke a single secret.

SecretManagement separates two concerns. The module is a thin wrapper that exposes Get-Secret, Set-Secret, Remove-Secret, and Get-SecretInfo. The actual storage is handled by a pluggable vault: an extension module that knows how to talk to a particular backend (local file, cloud KV, password manager). Your scripts call the API; you swap the vault by changing one registration. That is the whole design.

Installing the modules

Both modules ship from the PowerShell Gallery. They install cleanly side-by-side with anything else:

Install-Module -Name Microsoft.PowerShell.SecretManagement -Scope CurrentUser
Install-Module -Name Microsoft.PowerShell.SecretStore -Scope CurrentUser

SecretStore is the reference local-vault implementation β€” encrypted file, AES-256, password-protected. It is the right choice when you want a real vault but do not yet need a cloud backend. Other vault providers (Azure Key Vault, 1Password, KeePass) are separate modules; install them only when you need them.

Registering your first vault

# Register the local SecretStore as the default vault
Register-SecretVault -Name LocalStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault

# First-time configuration - sets master password
Set-SecretStoreConfiguration -Authentication Password -PasswordTimeout 900 -Interaction Prompt

The first Set-Secret or Get-Secret call after that prompts for the master password and unlocks the vault for 15 minutes (900 seconds). After timeout you are prompted again. List vaults with Get-SecretVault; you can register many at once and pick which one to use per call.

Storing and retrieving secrets

# Store a string secret
Set-Secret -Name "GitHub-PAT" -Secret "ghp_xxxxxxxxxxxxxxxxxxxx"

# Store a credential object
$cred = Get-Credential -UserName "svc-deploy"
Set-Secret -Name "DeployServiceAccount" -Secret $cred

# Store a structured hashtable
Set-Secret -Name "DB-Connection" -Secret @{
    Server   = "prod-sql01"
    Database = "AppDb"
    User     = "appuser"
    Password = "P@ssw0rd!"
}

# Retrieve
$pat  = Get-Secret -Name "GitHub-PAT" -AsPlainText
$cred = Get-Secret -Name "DeployServiceAccount"   # PSCredential
$db   = Get-Secret -Name "DB-Connection" -AsPlainText

Three storage shapes β€” string, PSCredential, hashtable β€” cover virtually every real-world need. -AsPlainText opts in to getting the value as a plain string instead of a SecureString; default behaviour is the safe one.

Unattended access for scheduled tasks and CI

The whole point of a vault breaks if you have to type a password every time a scheduled job runs. SecretStore supports an unattended mode β€” but you have to be deliberate about it, because the trade-off is real.

# Allow the vault to unlock without prompting (single-user host only)
$securePass = Read-Host -AsSecureString -Prompt "Master password"
Set-SecretStoreConfiguration -Authentication Password -Password $securePass `
    -Interaction None -PasswordTimeout 0 -Confirm:$false

This stores the configuration so the vault can be unlocked programmatically, but the master password itself still has to come from somewhere. The robust pattern in production:

  • Run the scheduled task as a dedicated service account.
  • Store the SecretStore master password in a managed service account (gMSA) wrapper or in the OS credential manager (Windows Credential Manager).
  • At task start, read the master password from the OS, unlock the vault, run the work, exit. Each step is logged.

For CI/CD on a hosted runner, the cleaner answer is to skip the local SecretStore and register a remote vault provider instead β€” Azure Key Vault with a managed identity, for example. The pipeline never sees the secrets at all.

Other vault providers

The point of SecretManagement is the same script works against any registered vault. Common providers:

  • Az.KeyVault.Extension β€” read/write Azure Key Vault. Auth via managed identity, service principal, or interactive.
  • SecretManagement.1Password β€” community module, talks to the 1Password CLI.
  • SecretManagement.Hashicorp.Vault β€” community module for HashiCorp Vault.
  • SecretManagement.KeePass β€” KeePass-backed vault.
# Register Azure Key Vault as a second vault
Register-SecretVault -Name CorpKV -ModuleName Az.KeyVault.Extension -VaultParameters @{
    AZKVaultName = "kv-corp-prod"
    SubscriptionId = "00000000-0000-0000-0000-000000000000"
}

# Read from a specific vault
Get-Secret -Vault CorpKV -Name "Prod-DbAdmin"

Real-world script patterns

API client wrapper

function Invoke-MyApi {
    param([string]$Endpoint, [string]$Method = 'GET')
    $token = Get-Secret -Name "MyApi-Token" -AsPlainText
    $headers = @{ Authorization = "Bearer $token" }
    Invoke-RestMethod -Uri "https://api.example.com$Endpoint" `
                       -Method $Method -Headers $headers
}

Database connection

$db = Get-Secret -Name "DB-Connection" -AsPlainText
$cs = "Server=$($db.Server);Database=$($db.Database);User Id=$($db.User);Password=$($db.Password);"
Invoke-Sqlcmd -ConnectionString $cs -Query "SELECT TOP 10 * FROM dbo.Orders"

Bulk credential rotation

$secrets = Get-SecretInfo
foreach ($s in $secrets) {
    if ($s.Name -like "Svc-*-Password") {
        $new = New-RandomPassword -Length 24
        Set-Secret -Name $s.Name -Secret $new
        Write-Host "Rotated $($s.Name)"
    }
}

Rotation and audit

SecretStore has no built-in audit log. If you need who-read-what, you need a vault provider that does (Azure Key Vault writes every access to Azure Monitor; HashiCorp Vault has its own audit devices). For local SecretStore, the pragmatic approach is: wrap Get-Secret in your own helper that logs to a file or to the Windows event log every time a script asks for a credential, and route all production scripts through that helper.

Rotation is a script you run on a schedule. Generate a new value, update the live system that consumes the secret (database password, API key, certificate), then write the new value into the vault. Always update the system before the vault β€” if you fail mid-rotation, you want the vault to still match reality.

Cheat sheet

Everything in this guide on a single printable PDF: PowerShell SecretManagement Cheat Sheet.

FAQ

Is SecretStore really secure for production?

It is much more secure than Export-Clixml or environment variables, and is fine for single-machine production workloads with a controlled service account. For shared infra, multi-host deployments, or anything that requires audit trails, use a real vault backend (Azure Key Vault, HashiCorp Vault).

Where is the SecretStore file stored?

On Windows, under %LOCALAPPDATA%\Microsoft\PowerShell\secretmanagement\localstore\. On Linux/macOS, under ~/.secretmanagement/localstore/. The file is AES-256 encrypted; the master password is the only thing that decrypts it.

Can multiple users share a SecretStore?

Not natively β€” SecretStore is per-user. For a shared vault, use Azure Key Vault, HashiCorp Vault, or another remote provider. Multiple users can register the same remote vault and authenticate with their own credentials.

How do I migrate from Export-Clixml to SecretManagement?

Read the old XML with Import-Clixml, extract the credential, and call Set-Secret. Then delete the old file. Plan a one-time script that walks the file system for stale creds.xml files.

Does this work in PowerShell 5.1?

Yes. Both modules support Windows PowerShell 5.1 and PowerShell 7.x.

What happens if I forget the master password?

You lose every secret in that store. There is no recovery. Treat the master password the same way you treat a root key: backed up offline, in a sealed envelope, in a safe.

Can I script the initial vault setup?

Yes β€” pass the master password as a SecureString to Set-SecretStoreConfiguration -Password. Useful for provisioning new dev workstations from a setup script.

Related reading

Share this article:
Dargslan Editorial Team (Dargslan)
About the Author

Dargslan Editorial Team (Dargslan)

Collective of Software Developers, System Administrators, DevOps Engineers, and IT Authors

Dargslan is an independent technology publishing collective formed by experienced software developers, system administrators, and IT specialists.

The Dargslan editorial team works collaboratively to create practical, hands-on technology books focused on real-world use cases. Each publication is developed, reviewed, and...

Programming Languages Linux Administration Web Development Cybersecurity Networking

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.