Public/Get-StoredCredential.ps1
function Get-StoredCredential { <# .SYNOPSIS Gets the specified credential that is stored on the local hard drive .DESCRIPTION This function either retrieves a specified credential or a list of all stored credentials .PARAMETER Name The name of the credential to get .PARAMETER EncryptionKey The key that was used to encrypt the credential .PARAMETER List Switch specifying that a list of the credentials stored on the local hard drive should be returned .EXAMPLE $StoredCredential = Get-StoredCredential -Name 'MyCreds' .EXAMPLE $StoredCredential = Get-StoredCredential -Name 'MyCreds' -EncryptionKey .OUTPUTS A PSCredential object containing the specified credential #> [CmdletBinding(DefaultParameterSetName = "Single")] param( [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Single")] [Parameter(Mandatory = $true, Position = 0, ValueFromPipelineByPropertyName = $true, ParameterSetName = "EncryptedWithKey")] [ArgumentCompleter({ Get-StoredCredential -List })] [Alias('CredentialName')] [String]$Name, [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'EncryptedWithKey')] [Alias('Key')] [Object]$EncryptionKey, [Parameter(Mandatory = $false, ParameterSetName = "List")] [switch]$List ) begin { function DecryptCredential { param ( [Parameter(Mandatory = $true)] [System.IO.FileInfo]$File, [Parameter(Mandatory = $false)] [Byte[]]$Key ) if ($File.Extension -eq '.credential') { Import-Clixml -Path $File.FullName } elseif ($null -ne $Key) { $EncryptedCredential = Get-Content -Path $File.FullName | ConvertFrom-Json try { $SecurePassword = $EncryptedCredential.Password | ConvertTo-SecureString -Key $Key -ErrorAction Stop [PSCredential]::new($EncryptedCredential.UserName, $SecurePassword) } catch { $ErrorRecord = [System.Management.Automation.ErrorRecord]::new( [Exception]::new("Could not decrypt credential with provided key"), "TMD.CRED03", [System.Management.Automation.ErrorCategory]::InvalidArgument, $Key ) $PSCmdlet.WriteError($ErrorRecord) } } } # Validate the encryption key provided if ($PSCmdlet.ParameterSetName -eq 'EncryptedWithKey') { # Make sure the encryption key is a string or a byte array if ($EncryptionKey.GetType() -notin [String], [Byte[]]) { throw "EncryptionKey must be either a Base64 encoded string or byte array with a size of 128, 192, or 256 bits" } # Convert the base64 string into a byte array if ($EncryptionKey.GetType() -eq [String]) { $EncryptionKey = [Convert]::FromBase64String($EncryptionKey) } # Make sure the byte array is the correct size if ($EncryptionKey.Count -notin 16, 24, 32) { throw "The encryption key must have a size of 128, 192, or 256 bits" } } } process { try { $CredentialFiles = Get-ChildItem -Path $Global:UserPaths.Credentials -File if (-not $Name -or $List) { $CredentialFiles | ForEach-Object { if ($List) { $_.Name -replace $_.Extension, '' } else { [PSCustomObject]@{ Name = $_.Name.Replace($_.Extension, '') Credential = (DecryptCredential -File $_ -Key $EncryptionKey) Encrypted = ($_.Extension -eq '.ecredential') } } } } else { $CredentialFileName = $Name if($PSCmdlet.ParameterSetName -eq 'EncryptedWithKey'){ $CredentialFileName += '.ecredential' } else { $CredentialFileName += '.credential' } $CredentialFilePath = Join-Path $Global:UserPaths.Credentials $CredentialFileName if (Test-Path -Path $CredentialFilePath) { Write-Host "Importing file from: $CredentialFilePath" DecryptCredential -File (Get-Item -Path $CredentialFilePath) -Key $EncryptionKey } } } catch { $PSCmdlet.WriteError($_) } } } |