PowerShell script exchange
Post Reply
mboswell
Service Provider
Posts: 43
Liked: 3 times
Joined: Jul 21, 2022 10:40 pm
Full Name: Matthew Boswell
Contact:

Programmatically decrypting backups

Post by mboswell »

Is there any way to do it other than Set-VBREncryptedBackupPassword? Or, is there any way to use a credential object instead of a literal string password? Problem I'm running into is with keys that contain special characters like $ or ' and having to programmatically escape or quote them in such a way that the right expression is formed to decrypt the backup.
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Programmatically decrypting backups

Post by Mildur »

Hi Matthew

Unfortunately, the command only takes a string for the password.
May I ask what the use case is?

Thanks
Fabian
Product Management Analyst @ Veeam Software
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Programmatically decrypting backups

Post by david.domask »

To add to Fabian's answer, regarding the special characters, I was able to easily pass a similar password with $ sign and other special characters by single-quoting the string so it's taken as a literal string. Double-quotes will allow for shell interpretation within the string. (Note: there is a Microsoft Powershell bug I'm aware of where square brackets ] and [ will still attempt to be parsed by the shell sometimes)

What I can recommend is to set the string into a secure file or a password manager, and just be sure to use Remove-Variable once a password is no longer needed.
David Domask | Product Management: Principal Analyst
mboswell
Service Provider
Posts: 43
Liked: 3 times
Joined: Jul 21, 2022 10:40 pm
Full Name: Matthew Boswell
Contact:

Re: Programmatically decrypting backups

Post by mboswell »

Use case is with Ansible. I'm aware of single quoting strings that contain $ or other characters but a string that contains both $ and ' needs special attention. Here's an example string I ran into in testing:
xu!<t$5'7'48SP

For powershell to interpret this literally we need one of two expressions: ('xu!<t$5''7''48SP') or ("xu!<t`$5`'7`'48SP"). Either way I have to insert characters into it before passing it to the powershell module.
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Programmatically decrypting backups

Post by david.domask »

Hi @mboswell Got it, now I get where you're having issues beyond just the $.

This gets tricky and to be honest, this is just shell behavior in general, not even just Powershell; bash will do some annoying stuff also, but it has more flexibility.

I think though that Powershell here-strings should help you here and I just tested with a password like below

First, set a function to pull the content of a file; I suppose you can pass the credential from a password manager also, but right now it has to hit as a non-secure string ultimately:

Code: Select all

function Get-SecPassFromFile {
     param(
         [string]$FilePath
     )

      $FileContent = Get-Content -Path $FilePath
      $secpass = @"
$FileContent
"@
     Return $secpass
}
IMPORTANT: Notice I don't follow usual indentation with the here-string; $FileContent is left-aligned in full as is the terminating "@. This is because Powershell is going to interpret every character literally, so the usual tabbing will add space/tab characters. The terminating "@ must also be the first characters on their own lines else the shell will try to interpret the spaces as something.

Pass your secure file to Powershell to get the content; the @" and "@ will force it as a "here-string" and it will be taken literally without the need for escapes.

With this, I was able to get the following pass to work:

Abc123$'%$'

Code: Select all

PS C:\Users\Administrator> function Get-SecPassFromFile {
>> param(
>>     [string]$FilePath
>>    )
>>
>> $FileContent = Get-Content -Path $FilePath
>> $secpass = @'
>> $FileContent
>> '@
>> Return $secpass
>> }
PS C:\Users\Administrator> $someSecurePass = Get-SecPassFromFile -FilePath C:\Users\Administrator\Downloads\secpass.txt
PS C:\Users\Administrator> $someSecurePass
$FileContent
PS C:\Users\Administrator> function Get-SecPassFromFile {
>> param(
>>     [string]$FilePath
>>    )
>>
>> $FileContent = Get-Content -Path $FilePath
>> $secpass = @"
>> $FileContent
>> "@
>> Return $secpass
>> }
PS C:\Users\Administrator> $someSecurePass = Get-SecPassFromFile -FilePath C:\Users\Administrator\Downloads\secpass.txt
PS C:\Users\Administrator> $someSecurePass
Abc123$'%$'
PS C:\Users\Administrator> Import-VBRBackup -Repository (Get-VBRBackupRepository -name 'refs4k-dedup') -FileName F:\encryptedbackup\encryptedbackupD2022-11-22T003107_1D68.vbk
PS C:\Users\Administrator> $backup = Get-VBRImportedEncryptedBackup
PS C:\Users\Administrator> $backup

Path                                                          SupportMasterKey Name            Id
----                                                          ---------------- ----            --
F:\encryptedbackup\encryptedbackupD2022-11-22T003107_1D68.vbk             True encryptedbackup 1c62e13b-5ce1-43b8-ae...


PS C:\Users\Administrator> Set-VBREncryptedBackupPassword -Backup $backup -Password $someSecurePass
PS C:\Users\Administrator>
So yeah, PS makes you jump through hoops, but I think the above should work. I kind of prefer this to setting up replace rules for escaping ??? characters as less chance to forget, I think it's a bit cleaner to see what it's doing, and it should be fine.

I would be _very_ happy if there's a better way to do this, but I wasn't finding anything in System.String that made this easier. Regex has a nice Escape() method, but regrettably it uses regex escapes so it doesn't work right for Powershell
David Domask | Product Management: Principal Analyst
mboswell
Service Provider
Posts: 43
Liked: 3 times
Joined: Jul 21, 2022 10:40 pm
Full Name: Matthew Boswell
Contact:

Re: Programmatically decrypting backups

Post by mboswell »

Thanks; that seems like it should work nicely.

I initially ran across this because in local testing I'm using ansible-vault encrypt_string to avoid having the key in plain text in the playbook and between powershell and bash I'd end up with \'xu\!\<t\$5\'\'7\'\'48SP\' using the same example string as my previous post.

But in production we'll be using AWX and have the ability to store the keys in the database encrypted either as a credential or as part of a survey, which prompts at run-time and likewise encrypts. In either case, the key is injected into the playbook as a variable that I can then use in a here-string. So if my variable is encryptionpass (I'll use the same var name in the powershell) it looks like

$encryptionpass = @'
{{ encryptionpass }}
'@

Should be all I need to do. Thanks for the help!
mboswell
Service Provider
Posts: 43
Liked: 3 times
Joined: Jul 21, 2022 10:40 pm
Full Name: Matthew Boswell
Contact:

Re: Programmatically decrypting backups

Post by mboswell »

david.domask wrote: Nov 21, 2022 10:19 pm I would be _very_ happy if there's a better way to do this.
My vision of the future is doing this in the REST API :D
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest