PS_EncryptedCredentials.psm1
|
<#
.SYNOPSIS PS_EncryptedCredentials Module - Manage encrypted PowerShell credentials .DESCRIPTION This module provides functions to securely store and retrieve encrypted credentials using PowerShell's built-in encryption. Credentials are stored as encrypted XML files using Export-Clixml which encrypts them with DPAPI (Data Protection API). This method is user and machine-specific, meaning encrypted credentials can only be decrypted by the same user account on the same machine where they were created. .NOTES Author: Your Name Version: 1.0.0 PowerShellVersion: 5.1 Important: Encrypted credentials are tied to the user account and machine where they were created. Do not attempt to share encrypted credential files between machines or user accounts. #> function Set-EncryptedCredentialXML { <# .SYNOPSIS Creates and stores encrypted credentials in an XML file. .DESCRIPTION Prompts the user for credentials and saves them as an encrypted XML file using PowerShell's built-in encryption. The credentials are encrypted with DPAPI and can only be decrypted by the same user on the same machine. .PARAMETER XMLFileFolderPath The folder path where the encrypted credential file will be stored. Default: $home\AppData\Roaming\cred\ .EXAMPLE Set-EncryptedCredentialXML # Creates credentials and saves to default location .EXAMPLE Set-EncryptedCredentialXML -XMLFileFolderPath "C:\Credentials\" # Creates credentials and saves to custom location .NOTES The filename is automatically generated from the domain and username. If domain\username format is provided, both are used in the filename. #> param( [string]$XMLFileFolderPath = "$home\AppData\Roaming\cred\" ) $cred = Get-Credential # enter user + password $username = $cred.UserName if ($username -like "*\*") { $splitUsername = $username.Split('\') $domain = $splitUsername[0] $username = $splitUsername[1] $filename = $domain + '_' + $username } if (!(Test-Path -Path $XMLFileFolderPath)) { New-Item -ItemType Directory -Path $XMLFileFolderPath -Force | Out-Null } $path = $XMLFileFolderPath + $filename + '.psclixml' Write-Host "Creating new encrypted credential file at: $path" -ForegroundColor Yellow try { $cred | Export-Clixml -Path $path } catch { <#Do this if a terminating exception happens#> Write-Host Write-Host "File Already Exists:" -ForegroundColor Red Write-Host $XMLFileFolderPath Write-Host Write-Host "Please delete the existing file manually if you want to overwrite it." -ForegroundColor yello return } Write-Host Write-Host "-------------------------------------------------------------------------" Write-Host "Saved encrypted credential file..." -ForegroundColor Green Write-Host $path Write-Host Write-Host "Completed!" Write-Host "-------------------------------------------------------------------------" Write-Host "Please remember this file is tied to this user account and machine only." -ForegroundColor Yellow Write-Host } function Get-EncryptedCredentialXML { <# .SYNOPSIS Retrieves encrypted credentials from an XML file. .DESCRIPTION Displays available encrypted credential files and prompts the user to select one. Returns the decrypted credentials as a PSCustomObject with Username and Password properties. .PARAMETER XMLFileFolderPath The folder path where encrypted credential files are stored. Default: $home\AppData\Roaming\cred\ .OUTPUTS PSCustomObject with properties: - Username: The username from the credential file - Password: The decrypted password in plain text .EXAMPLE Get-EncryptedCredentialXML # Lists available credentials and prompts for selection .EXAMPLE $cred = Get-EncryptedCredentialXML -XMLFileFolderPath "C:\Credentials\" Write-Host $cred.Username Write-Host $cred.Password .NOTES Passwords are returned in plain text. Handle with care. #> param( [string]$XMLFileFolderPath = "$home\AppData\Roaming\cred\" ) Write-Host "Here are all the encrypted credential files available in: $XMLFileFolderPath" -ForegroundColor Yellow Get-ChildItem -Path $XMLFileFolderPath -Filter *.psclixml | ForEach-Object { Write-Host "- " $_.Name } Write-Host "What is the username for the encrypted credential file you want to retrieve?" Write-Host Write-Host "-------------------------------------------------------------------------" $XML = Read-Host "Please copy and paste the password file name here:" $path = $XMLFileFolderPath + $XML' if (!(Test-Path -Path $path)) { Write-Host Write-Host "-------------------------------------------------------------------------" Write-Host "Encrypted credential file not found at: $path" -ForegroundColor Red Write-Host "Please ensure the file exists and try again." -ForegroundColor Yellow Write-Host "-------------------------------------------------------------------------" Write-Host return } Write-Host Write-Host "Retrieving encrypted credential file from: $path" -ForegroundColor Yellow try { $importedCred = Import-Clixml -Path $path $username = $importedCred.UserName $plainPw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($importedCred.Password)) } catch { <#Do this if a terminating exception happens#> Write-Host Write-Host "Error importing credential file:" -ForegroundColor Red Write-Host $_.Exception.Message Write-Host return } $Credentials = [PSCustomObject]@{ Username = $username Password = $plainPw } Write-Host Write-Host "-------------------------------------------------------------------------" Write-Host "Successfully retrieved encrypted credential file..." -ForegroundColor Green Write-Host return $Credentials } # Export functions Export-ModuleMember -Function @( 'Set-EncryptedCredentialXML', 'Get-EncryptedCredentialXML' ) |