SecretBackup.psm1
<# .SYNOPSIS Exports secrets from a specified vault to a JSON file. .DESCRIPTION This function exports secrets from a specified vault to a JSON file. It retrieves secret information from the vault and converts it to a JSON format for export. .PARAMETER VaultName Specifies the name of the vault from which to export secrets. This parameter is mandatory. .PARAMETER OutPath Specifies the output path where the JSON file will be saved. If not provided, the current location will be used as the default output path. .EXAMPLE Export-Secret -VaultName 'MyVault' -OutPath 'C:\Backups' Exports secrets from the 'MyVault' vault and saves the JSON file to the 'C:\Backups' directory. .EXAMPLE Export-Secret -VaultName 'MyVault' Exports secrets from the 'MyVault' vault and saves the JSON file to the current location. .NOTES Exports secretes in plain text. Make sure you protect the exported data. #> 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 } } <# .SYNOPSIS Imports secrets from a backup file into a specified vault. .DESCRIPTION This function imports secrets from a backup file (generated by same module) into a specified vault. It checks if the secret already exists in the vault and either adds it or updates it based on the OverWrite switch parameter. .PARAMETER VaultName The name of the vault where the secrets will be imported. .PARAMETER BackupFile The path to the backup file containing the secrets to be imported. .PARAMETER OverWrite A switch parameter that specifies whether existing secrets in the vault should be overwritten if they already exist. .EXAMPLE Import-Secret -VaultName "MyVault" -BackupFile "C:\Path\to\backup.json" -OverWrite Imports secrets from the specified backup file into the "MyVault" vault, overwriting existing secrets if they already exist. #> 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 } } |