Using --password-command on Windows with PowerShell

I just started using restic on Windows and cannot figure out what special treatment it expects from a PowerShell script when using either --password-command or environment variable RESTIC_PASSWORD_COMMAND.

The commands below are just examples, the actual script is more complex (involving decrypting the password). But it wasn’t working for me, so I started with the basics below.

# This works.
--password-command "powershell echo "test""
# This doesn't.
--password-command "powershell cat c:\Users\user\pass.txt"
Resolving password failed: exit status 1

Using the variable I get a different error.

set RESTIC_PASSWORD_COMMAND="powershell cat c:\Users\user\pass.txt"
restic.exe snapshots d:\test\restic
Resolving password failed: exec: "powershell cat c:\\Users\\user\\pass.txt": file does not exist

Adding -vv to restic doesn’t give me more details. Particularly interesting that it complains about non-existing file. Running the command as is from cmd works.

That is likely a quoting issue. Apparently cmd does not interpret the quotes and includes them in the environment variable. This means that from restic’s point of view, it is supposed to execute a program named powershell cat c:\Users\user\pass.txt (not powershell!).

What happens if you run that command directly from within cmd? The command parser should split that into "powershell", "cat", "c:\Users\user\pass.txt". I’m wondering whether there could be a quoting problem in regards to the backslashes. (correctly quoting arguments when calling other processes is an unmitigated disaster on Windows)

There’s unfortunately no way to get more detailed debug information here. (Except by modifying the code)

Michael, I really appreciate your comments.

But then why “powershell echo test” works?

However, when you said quoting, you got me thinking. After a number of tries I arrived to the solution. All of these work correctly:

"powershell cat 'C:\Users\user\text.txt'"
"powershell cat \"C:\Users\user\text.txt\""
# What I was really after
"powershell -executionpolicy bypass -file 'C:\Users\user\test.ps1' "

It appears that file paths must be quoted even though there are no spaces. It works with either single quotes around the path or escaped double-quote.

To confirm this, I switched working directory and used a relative path. This works too:

"powershell cat text.txt"

I suspect there is something about the backslashes. Everywhere else it’s the escape character, but in Windows it’s part of the path.

On a side note, I want to thank you for working on this great piece of software. I just recently started to look for a cloud backup solution. Tried almost everything I could find, including some commercial offerings. Not only restic has pretty much all the features I ever wanted, it was also the only tool that passed my favourite test: deleting some random blobs at the target and seeing what happens. Some tools didn’t detect the issue until a restore attempt (too late); some detected the issue during checks but couldn’t repair it no matter what I tried, despite all data still being on the source. Restic detected the issue during the check, and then I used the very helpful troubleshooting guide - the first suggested command fixed the problem. I know, it might be a silly test, but that gave me additional confidence in the tool.

2 Likes

A quick follow-up. I found out that it is backslashes that restic doesn’t like with this flag. Another way to avoid all this quoting is simply to use forward slashes. PowerShell understands them properly.

"powershell -executionpolicy bypass -file C:/Users/user/test.ps1"
1 Like