SecretManagement.Warden.Extension/public/Get-Secret.ps1
<#
.SYNOPSIS Retrieves a single secret from the vault or null if no secret is found. .DESCRIPTION Retrives a single secret from the vault. Corresponds with the "bw get" functionality of the CLI. .NOTES Per SecretManagement documentation, "The Get-Secret cmdlet writes the retrieved secret value to the output pipeline on return, or null if no secret was found. It should write an error only if an abnormal condition occurs." #> function Get-Secret { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "VaultName", Justification = "Function must accept this parameter to be valid.")] param( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$true)] [Alias('ID')][string] $Name, [Parameter(ValueFromPipelineByPropertyName)] [string] $VaultName, [Parameter(ValueFromPipelineByPropertyName)] [hashtable] $AdditionalParameters ) # Enable Verbose Mode inside this script if passed from the wrapper. if($AdditionalParameters.ContainsKey('Verbose') -and ($AdditionalParameters['Verbose'] -eq $true)) {$script:VerbosePreference = 'Continue'} $AdditionalParameters = Merge-Defaults $AdditionalParameters Sync-BitwardenVault $AdditionalParameters.ResyncCacheIfOlderThan [System.Collections.Generic.List[string]]$CmdParams = @("get","item") $CmdParams.Add( $Name ) #* Do not combine with the above line. For some reason that causes the function to fail in production. if ( $AdditionalParameters.ContainsKey('organizationid') ) { $CmdParams.Add( '--organizationid' ) $CmdParams.Add( $AdditionalParameters['organizationid'] ) } try { $Result = Invoke-BitwardenCLI @CmdParams } # Per SecretManagement Readme, if a secret is not found, Get-Secret should return null, not an error. catch [System.Management.Automation.ItemNotFoundException],[System.DirectoryServices.AccountManagement.NoMatchingPrincipalException] { return $null } switch ( $Result.type ) { "SecureNote" { $ObjType = ($Result.notes | Select-String -Pattern "(?<=PowerShellObjectRepresentation: )[^\n]*").Matches | Select-Object -First 1 -ExpandProperty Groups | Select-Object -First 1 -ExpandProperty Values if( !$ObjType ) { return $Result.notes } elseif( $ObjType -ieq "CliXml" ) { $tmp = New-TemporaryFile $Result.notes.Remove(0,$Result.notes.IndexOf("`n")+1) | Out-File -FilePath $tmp $obj = Import-Clixml -Path $tmp Remove-Item $tmp -Force return $obj } elseif( $ObjType -ieq "JSON" ) { $note = $Result.notes.Remove(0,$Result.notes.IndexOf("`n")+1) return $note | ConvertFrom-Json -AsHashtable } else { $ex = New-Object System.NotSupportedException "$ObjType is not a supported means of representing a PowerShell Object. Only CliXml and JSON representations are supported." Write-Error -Exception $ex -Category NotImplemented -ErrorId "InvalidObjectRepresentation" -ErrorAction Stop } break } { "Login","Card","Identity" -icontains $_ } { # Output login as a hashtable. This allows us to support credentials that lack a username and therefore cannot output a PSCredential. #* Unlike Get-SecretInfo, Get-Secret does not support ordered hashtables. return $Result.$_ | ConvertTo-Hashtable break } default {throw [System.NotImplementedException]"Somehow you got to a place that doesn't exist."; break} } } |