VaultTools.psm1

function New-VaultToken {
<#
.SYNOPSIS
Command to get a new token that represents a approle secret ID
.EXAMPLE
New-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]$LdapCredential,

        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [ValidateScript({$_ -notmatch '/$' -and $_ -notmatch '/v1$'})]
        [string]$Vault_Address,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Rolename
    )

    #Stop when an error comes up
    $ErrorActionPreference='Stop'

    #Addresses
    $VAULT_ROOT          = $Vault_Address + '/v1'
    $VAULT_LOGIN_LDAP    = $VAULT_ROOT+'/auth/ldap/login'
    $VAULT_LOGIN_APPROLE = $VAULT_ROOT+'/auth/approle/login'
    $VAULT_AUTH_APPROLE  = $VAULT_ROOT+'/auth/approle/role'
    $VAULT_ROLEID        = "$VAULT_AUTH_APPROLE/$Vault_RoleName/role-id"
    $VAULT_SECRETID      = "$VAULT_AUTH_APPROLE/$Vault_RoleName/secret-id"

    #Get token equivalent of $LdapCredential
    $Username = $LdapCredential.GetNetworkCredential().UserName
    $PlainPassword = $LdapCredential.GetNetworkCredential().Password
    $JsonBody = @{password = $PlainPassword} | ConvertTo-Json
    Write-Verbose "Authenticating $Username to $Vault_Address"
    $UserToken = (Invoke-RestMethod -Method 'Post' -Uri "$VAULT_LOGIN_LDAP/$Username" -Body $JsonBody).auth.client_token

    #Get Role ID of $Vault_RoleName
    $RoleID = (Invoke-RestMethod -Headers @{"X-Vault-Token"="$UserToken"} -Uri $VAULT_ROLEID).data.role_id

    #Get Secret ID of $Vault_RoleName
    $SecretID = (Invoke-RestMethod -Method 'Post' -Headers @{"X-Vault-Token"="$UserToken"} -Uri $VAULT_SECRETID).data.secret_id

    #Send the role ID and the secret ID and receive a new token for the secret ID of $Vault_RoleName
    $JsonBody = @{role_id=$RoleID;secret_id=$SecretID} | ConvertTo-Json
    [ValidateNotNullOrEmpty()]$Output = (Invoke-RestMethod -Method 'Post' -Uri "$VAULT_LOGIN_APPROLE" -Body $JsonBody).auth.client_token

    #Output
    $Output
}
function Save-VaultToken {
<#
.SYNOPSIS
Command to save a token representation of a approle secret ID to local encrypted file
.DESCRIPTION
This function retrieves a token representation of the secret ID for a vault rolename
The function then outputs the token into an encrypted file.
The file can only be opened on the computer and user account where it was created.
.EXAMPLE
Save-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role' -OutputPath 'c:\some_role_token.dat'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]$LdapCredential,

        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [ValidateScript({$_ -notmatch '/$' -and $_ -notmatch '/v1$'})]
        [string]$Vault_Address,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Rolename,

        [Parameter(Mandatory=$true)]
        [string]$OutputPath
    )

    $ErrorActionPreference='Stop'
    $Verbose = $VerbosePreference -ne 'SilentlyContinue'

    #Get Token
    $OutputToken = New-VaultToken -LdapCredential $LdapCredential -Vault_Address $Vault_Address -Vault_Rolename $Vault_Rolename -Verbose:$Verbose

    #Output the token as encrypted file
    $SecureStringOutputToken = ConvertTo-SecureString -String $OutputToken -AsPlainText -Force
    [System.Management.Automation.PSCredential]::New('na',$SecureStringOutputToken) | Export-Clixml -Path $OutputPath
    Write-Verbose "Token saved to $OutputPath"
}
function Get-VaultValue {
<#
.SYNOPSIS
function to get a value for a key from the Vault Address
.DESCRIPTION
function to get a value for a key from the Vault Address
.PARAMETER Vault_Full_Address
The complete address to where the key is stored.
Example: https://myvault.com/v1/secret/data/mypath
.PARAMETER Vault_SavedTokenPath
The path to the saved token (OutputPath from Save-VaultToken function)
.PARAMETER Vault_Key
The name of the key you are trying to get the value from.
.EXAMPLE
Save-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://myvault.com' -Vault_Rolename 'some_role' -OutputPath 'c:\some_role_token.dat'
Get-VaultValue -Vault_Full_Address 'https://myvault.com/v1/secret/data/mypath' -Vault_SavedTokenPath 'c:\some_role_token.dat' -Vault_Key 'mykey'
.EXAMPLE
$NewToken=New-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role'
Get-VaultValue -Vault_Full_Address 'https://myvault.com/v1/secret/data/mypath' -Vault_Token $NewToken -Vault_Key 'mykey'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [string]$Vault_Full_Address,

        [Parameter(Mandatory=$true,ParameterSetname='SavedToken')]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Vault_SavedTokenPath,

        [Parameter(Mandatory=$true,ParameterSetName='NewToken')]
        [string]$Vault_Token,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Key
    )

    $ErrorActionPreference = 'Stop'

    #Get Vault Token from locally encrypted dat file, otherwise it came from Param block
    if ($Vault_SavedTokenPath) {
        [ValidateNotNullOrEmpty()]$Vault_Token=(Import-CliXml -Path $Vault_SavedTokenPath).GetNetworkCredential().Password
    }

    #Get the Value that is associated with $Vault_Key from $Vault_Full_Address
    $InvokeRestMethodParams = @{
        Uri = $Vault_Full_Address
        Headers = @{"X-Vault-Token"="$Vault_Token"}
    }
    [ValidateNotNullOrEmpty()]$Output = (Invoke-RestMethod @InvokeRestMethodParams).data.data |
                                        Select-Object -ExpandProperty $Vault_Key

    #Output
    Return $Output
    Write-Verbose "Successfully retrieved value for $Vault_Key from $Vault_Full_Address"
}