Retrieve Hashicorp Vault Secrets and Key Names

The web interface that is supplied with Vault has a Search capability, but it is limited. Users are not able to search for nested secrets or Key names. The PowerShell function below can be used to export complete secret paths and the key names. It requires use of the vault command line and that the user has already logged in to Vault.

function Traverse-Secrets {

    [CmdletBinding()]

    param (

        [Parameter(Mandatory=$true)]

        [string]$enginePath,

 

        [Parameter(Mandatory=$true)]

        [string]$vaultAddr

    )

 

    try {

        # Retrieve secrets from Vault

        Write-Verbose "Retrieving secrets from Vault at $vaultAddr"

        $secrets = vault kv list -format=json -address $vaultAddr "$enginepath"

        $jSecrets = $secrets | ConvertFrom-Json

        $currentDate = Get-Date -Format "M/dd/yyyy"

        # Create an array to hold the custom objects

        $secretObjects = @()

 

        # Iterate over each secret

        foreach ($secret in $jSecrets) {

            Write-Verbose "Processing secret: $secret"

            $secretKeysObject = $null

            $keysObject = $null

            $secretKeys = $null

            # Create a custom object and add it to the array

            $splat = [ordered]@{

                ReportDate = "$currentDate"

                Path       = "$enginepath"

                Secret     = "$secret"

                Key        = $null

            }

 

            if (-not ($secret -match "/")) {

                # If the secret does not contain a "/", retrieve the keys

                Write-Verbose "Retrieving keys for secret: $secret"

                $secretKeysObject = vault kv get -format=json "$enginepath$secret" | ConvertFrom-Json

                $keysObject = $secretKeysObject.data.data

                $secretKeys = $keysObject | Get-Member -ErrorAction SilentlyContinue -MemberType NoteProperty | Select-Object -ExpandProperty Name

                foreach($key in $secretKeys){

                    $splat.Key = $key

                    $secretObject = New-Object PSObject -Property $splat

                    $secretObjects += $secretObject

                }

            }elseif ($secret -match "/") {

                # If the secret contains a "/", recursively call Traverse-Secrets

                Write-Verbose "Recursively calling Traverse-Secrets for secret: $secret"

                Traverse-Secrets -enginePath "$enginepath$secret" -vaultAddr $vaultAddr

            }

        }

 

        # Return the array of custom objects

        return $secretObjects

    } catch {

        Write-Error "Error executing: $_"

    }

}