SecretBackup.psm1

function Export-Secret {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]
        $VaultName,
        [string]
        $OutPath = (Get-Location).Path
    )
    Test-VaultAccess -VaultName $VaultName

    $Data = New-Object -TypeName System.Collections.ArrayList

    $AllSecrets = Get-SecretInfo -Vault $VaultName
    foreach ($Secret in $AllSecrets) {
        if ($Secret.Type -eq 'String' -or $Secret.Type -eq 'SecureString') {
            $Obj = [PSCustomObject]@{
                Name     = $Secret.Name
                Type     = [string]$Secret.Type
                Secret   = Get-Secret -Vault $VaultName -Name $Secret.Name -AsPlainText
                Metadata = $Secret.Metadata #| ConvertTo-Json -Compress
            }
        } elseif ($Secret.Type -eq 'PSCredential') {
            $SecInfo = Get-Secret -Vault $VaultName -Name $Secret.Name -AsPlainText
            $Obj = [PSCustomObject]@{
                Name     = $Secret.Name
                Type     = [string]$Secret.Type
                Secret   = @{
                    UserName = $SecInfo.UserName
                    Password = $SecInfo.Password | ConvertFrom-SecureString -AsPlainText
                }
                Metadata = $Secret.Metadata #| ConvertTo-Json -Compress
            }
        } else {
            'Secret {0} of type {1} is not supported' -f $Secret.Name, $Secret.Type | Write-Warning
        }
        $Data.Add($Obj) | Out-Null
    }
    $outFileName = 'Vault_Backup_{0}.json' -f (Get-Date).ToString('yyyyMMdd_HHmm')
    $outFile = Join-Path -Path $OutPath -ChildPath $outFileName
    $Data | ConvertTo-Json | Out-File -FilePath $outFile
    if ($?) {
        'Successfully exported backup to: {0}' -f $outFile | Write-Host
    } else {
        'Someting went wrong, export failed' | Write-Error
    }
}
function Import-Secret {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]
        $VaultName,
        [Parameter(Mandatory)]
        [string]
        $BackupFile,
        [switch]
        $OverWrite
    )
    Test-VaultAccess -VaultName $VaultName
    # Test-ValidJSONInput -JSONFile $BackupFile
    $RestoredCount = 0
    $JSONData = Get-Content -Path $BackupFile -Raw | ConvertFrom-Json
    foreach ($Secret in $JSONData) {
        if (Get-SecretInfo -Vault $VaultName -Name $Secret.Name) {
            $SecretExists = $true
        } else {
            $SecretExists = $false
        }
        if (-not $SecretExists -or $OverWrite) {
            $Metadata = $Secret.Metadata | ConvertTo-Json | ConvertFrom-Json -AsHashtable
            if ($Secret.Type -eq 'String' -or $Secret.Type -eq 'SecureString') {
                Set-Secret -Vault $VaultName -Name $Secret.Name -Secret $Secret.Secret -Metadata $Metadata
                $RestoredCount ++
            } elseif ($Secret.Type -eq 'PSCredential') {
                $username = $Secret.Secret.UserName
                $password = $Secret.Secret.Password | ConvertTo-SecureString -AsPlainText
                $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
                Set-Secret -Vault $VaultName -Name $Secret.Name -Secret $credential -Metadata $Metadata
                $RestoredCount ++
            } 
        }
    }
    "Imported $RestoredCount secrets" | Write-Host
}
function Test-ValidJSONInput {
    param (
        $JSONFile
    )
    # TODO Check in depth with json schema
    if (-not(Test-Json -Json $JSONFile -ErrorAction SilentlyContinue)) {
        Write-Error 'Provided backup file is corrupted and not supported' -ErrorAction Stop
    }
}
function Test-VaultAccess {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string]
        $VaultName
    )
    if (-not(Get-Command Test-SecretVault -ErrorAction SilentlyContinue)) {
        'SecretManagement module is not found, aborting' | Write-Error -ErrorAction Stop
    }
    
    Try {
        Test-SecretVault -Name $VaultName -ErrorAction Stop | Out-Null
    } Catch {
        "Unable to access Vault! `n{0}" -f $Error[0] | Write-Error -ErrorAction Stop
    }
}