PSVault.psm1
# Override Write-Verbose in this module so calling function is added to the message function script:Write-Verbose { [CmdletBinding()] param ( [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] [String] $Message ) begin {} process { try { $PSBoundParameters['Message'] = $((Get-PSCallStack)[1].Command) + ': ' + $PSBoundParameters['Message'] } catch {} Microsoft.PowerShell.Utility\Write-Verbose @PSBoundParameters } end {} } function Get-VaultCredential { <# .SYNOPSIS Get vault credential .DESCRIPTION Get vault credential .PARAMETER Name Name of credential entry .EXAMPLE Get-VaultCredential -Name cred1 .EXAMPLE (Get-VaultCredential -Name cred2).GetNetworkCredential().Password #> [CmdletBinding()] param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position = 0)] [string] $Name ) begin { Write-Verbose -Message "Begin (ErrorActionPreference: $ErrorActionPreference)" $origErrorActionPreference = $ErrorActionPreference $verbose = $PSBoundParameters.ContainsKey('Verbose') -or ($VerbosePreference -ne 'SilentlyContinue') } process { Write-Verbose -Message "Process begin (ErrorActionPreference: $ErrorActionPreference)" try { # Make sure that we don't continue on error, and that we catches the error $ErrorActionPreference = 'Stop' $vault = New-Object -TypeName 'Windows.Security.Credentials.PasswordVault' $vaultcredential = $vault.FindAllByResource($Name) if ($vaultcredential.AdditionalTypeData) { # PS Core $vaultcredential = $vaultcredential.AdditionalTypeData.GetEnumerator() | Select-Object -First 1 -ExpandProperty Value | Select-Object -First 1 } else { $vaultcredential = $vaultcredential | Select-Object -First 1 } $null = $vaultcredential.RetrievePassword() $username = $vaultcredential.UserName $password = $vaultcredential.Password $credential = [pscredential]::new($username, ($password | ConvertTo-SecureString -AsPlainText -Force)) # Return $credential } catch { Write-Verbose -Message "Encountered an error: $_" Write-Error -ErrorAction $origErrorActionPreference -Exception $_.Exception } finally { $ErrorActionPreference = $origErrorActionPreference } Write-Verbose -Message 'Process end' } end { Write-Verbose -Message 'End' } } function Set-VaultCredential { <# .SYNOPSIS Set vault credential .DESCRIPTION Set vault credential .PARAMETER Name Name of credential entry .PARAMETER Credential Credential object with username/password to store in vault .PARAMETER Username Username to store in vault .PARAMETER Password Password to store in vault Either [string] or [securestring] .EXAMPLE Set-VaultCredential -Name cred1 .EXAMPLE Set-VaultCredential -Name cred2 -Username userx -Password sEcReT #> [CmdletBinding(DefaultParameterSetName='PSCredential')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword','')] param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position = 0)] [string] $Name, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position = 1, ParameterSetName='PSCredential')] [pscredential] $Credential, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='UserPass')] [string] $Username, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='UserPass')] [object] $Password ) begin { Write-Verbose -Message "Begin (ErrorActionPreference: $ErrorActionPreference)" $origErrorActionPreference = $ErrorActionPreference $verbose = $PSBoundParameters.ContainsKey('Verbose') -or ($VerbosePreference -ne 'SilentlyContinue') } process { Write-Verbose -Message "Process begin (ErrorActionPreference: $ErrorActionPreference)" try { # Make sure that we don't continue on error, and that we catches the error $ErrorActionPreference = 'Stop' $vault = New-Object -TypeName 'Windows.Security.Credentials.PasswordVault' if ($Password -is [securestring]) { $Credential = [pscredential]::new($Username, $Password) } if ($Credential) { $Username = $Credential.UserName $Password = $Credential.GetNetworkCredential().Password } else { $Password = [string] $Password } $vaultcredential = [Windows.Security.Credentials.PasswordCredential]::new($Name, $Username, $Password) $vault.Add($vaultcredential) } catch { Write-Verbose -Message "Encountered an error: $_" Write-Error -ErrorAction $origErrorActionPreference -Exception $_.Exception } finally { $ErrorActionPreference = $origErrorActionPreference } Write-Verbose -Message 'Process end' } end { Write-Verbose -Message 'End' } } Write-Verbose -Message "Loading assembly" $origErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' try { $null = [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] } catch { # PS Core $null = Add-Type -AssemblyName (Join-Path -Path $PSScriptRoot -ChildPath 'WinRT.Runtime.dll') $null = Add-Type -AssemblyName (Join-Path -Path $PSScriptRoot -ChildPath 'Microsoft.Windows.SDK.NET.dll') } finally { $ErrorActionPreference = $origErrorActionPreference } Export-ModuleMember -Function Get-VaultCredential Export-ModuleMember -Function Set-VaultCredential |