PowerShell Credential Management: Store and Reuse Credentials

PowerShell Credential Management: Store and Reuse Credentials

PowerShell Tips Editor 4 min read
PowerShell Credential Management: Store and Reuse Credentials

Hard-coding passwords in scripts is the fastest way to create a security incident. Proper PowerShell credential management means creating PSCredential objects safely, encrypting passwords to disk so they survive reboots, and reusing credentials across multiple scripts without re-prompting. This post covers every practical pattern from interactive prompts to Windows Credential Manager integration.

Quick Answer / TL;DR

Use Get-Credential for interactive prompts. Save encrypted passwords to disk with ConvertFrom-SecureString | Out-File. Load them back with ConvertTo-SecureString. The encrypted file only works for the same user account on the same machine.

Get-Credential Interactive Prompt

Get-Credential displays a Windows dialog box (or console prompt in PowerShell 7) asking for username and password. It returns a PSCredential object immediately. This is the correct approach for interactive scripts where a human is present to type credentials.

# Standard credential prompt
$cred = Get-Credential

# Pre-fill the username so user only needs to enter password
$cred = Get-Credential -UserName 'CONTOSO\jsmith' -Message 'Enter your AD password'

# Check what we have
$cred.UserName
$cred.GetNetworkCredential().Password  # only use for debugging

Create PSCredential Programmatically

For automation scripts that run unattended, build the PSCredential object in code. The password must be a SecureString — never pass a plain-text password directly to PSCredential. Use ConvertTo-SecureString -AsPlainText -Force only during development or when reading from a secrets vault that provides plain text.

# Build credential programmatically (plain text — dev only)
$username = 'CONTOSO\svc_automation'
$password = ConvertTo-SecureString 'P@ssw0rd!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username, $password)

Write-Host "Credential created for: $($cred.UserName)"

Save Encrypted Password to File

ConvertFrom-SecureString serializes a SecureString to an encrypted string using the Windows Data Protection API (DPAPI). The encryption is tied to the current user account and machine. Store this in a file and reload it later. This is safe because the encrypted blob cannot be decrypted on a different machine or by a different user account.

# Prompt once and save encrypted password to file
$cred = Get-Credential -UserName 'CONTOSO\svc_backup' -Message 'Enter password to save'
$cred.Password | ConvertFrom-SecureString | Out-File C:\Secrets\backup_pass.txt

Write-Host "Encrypted password saved to C:\Secrets\backup_pass.txt"

Load Credential from Encrypted File

Reload the saved password by reading the encrypted string from the file and converting it back to a SecureString with ConvertTo-SecureString. Combine it with the stored username to rebuild the PSCredential object. This works silently in scheduled tasks running as the same service account that created the file.

# Load and reconstruct the credential in a scheduled script
$username = 'CONTOSO\svc_backup'
$encryptedPass = Get-Content C:\Secrets\backup_pass.txt
$securePass = $encryptedPass | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential($username, $securePass)

# Use the credential
Invoke-Command -ComputerName backupserver01 -Credential $cred -ScriptBlock {
    Get-Service -Name 'BackupService'
}

Windows Credential Manager with CredentialManager Module

The CredentialManager module (from the PowerShell Gallery) stores and retrieves credentials from Windows Credential Manager, which provides a proper secrets store accessible via the Windows control panel. Install once, then retrieve credentials by their target name — no file management required.

# Install the module
Install-Module CredentialManager -Scope CurrentUser

# Save a credential to Credential Manager
New-StoredCredential -Target 'MyApp-Database' `
    -UserName 'CONTOSO\svc_db' `
    -Password 'SecureP@ss!' `
    -Type Generic `
    -Persist LocalMachine

# Retrieve it later
$cred = Get-StoredCredential -Target 'MyApp-Database'
Write-Host "Retrieved credential for: $($cred.UserName)"

Pass Credential to Remote Commands

Once you have a PSCredential object, pass it to any cmdlet that accepts a -Credential parameter. This includes Invoke-Command, Enter-PSSession, New-PSSession, Get-ADUser, and many others. The credential format should match what the target expects: DOMAIN\username for NTLM/Kerberos, [email protected] for UPN format.

# Load credential from file
$cred = New-Object System.Management.Automation.PSCredential(
    'CONTOSO\admin',
    (Get-Content C:\Secrets\admin_pass.txt | ConvertTo-SecureString)
)

# Use across multiple operations
Get-ADUser -Filter * -Credential $cred -Server dc01.contoso.com
Invoke-Command -ComputerName server01,server02 -Credential $cred -ScriptBlock {
    Get-Service | Where-Object Status -ne Running
}

Common Errors and Fixes

  • Encrypted file only works for creating user on same machine. If you create the encrypted file as user1 on machine1 and try to read it as user2 or on machine2, you get “Key not valid for use in specified state.” DPAPI encryption is user-and-machine specific. For cross-machine scenarios, use a secrets vault like Azure Key Vault or CyberArk.
  • PSCredential Username format: DOMAIN\user or user@domain. Some cmdlets expect DOMAIN\username (NetBIOS format); others expect [email protected] (UPN format). AD cmdlets accept both. For WinRM remoting, DOMAIN\username is the most compatible format.

Related Cmdlets / See Also

Wrapping Up

Never hard-code passwords in scripts. Use Get-Credential for interactive use, DPAPI-encrypted files for single-machine scheduled tasks, and a proper secrets vault for multi-machine automation. The PSCredential object is accepted by hundreds of PowerShell cmdlets, making it the universal credential carrier across the entire ecosystem.

Send-Item -To