How to use RCLONE_PASSWORD_COMMAND with Windows Powershell for config password

Rclone release 1.51 includes support for a new config --password-command, documented at:

https://rclone.org/docs/#configuration-encryption

This article demonstrates how to use the Windows Powershell SecureString type and PSCredential to store your configuration file password securely in a file.

  • Generate your secure password to a disk file (for the purprose of this example, U:\rcpw.txt):

Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -FilePath U:\rcpw.txt

  • Create a Powershell script (for the purpose of this example, C:\xx\rcpw.ps1) to return the decrypted password from the file you created in the previous step (notice how this file is referenced in the -Path parameter). Contents of C:\xx\rcpw.ps1:

(New-Object -TypeName PSCredential -ArgumentList @( 'user', ((Get-Content -Path U:\rcpw.txt) | ConvertTo-SecureString))).GetNetworkCredential().Password

  • Test it:

rclone -vv --password-command "powershell C:\xx\rcpw.ps1" about remote:

  • Once this works, you can default the password-command parameter via setting the environment variable RCLONE_PASSWORD_COMMAND to:

powershell C:\xx\rcpw.ps1

  • From then on you can use the rclone command without having to enter your configuration file password.

Notes

Decryption

Decryption only works under the same WIndows user/PC that created the encrypted file.

UTF8 encoding warning

I tried this with an rclone configuration password that contained 'special characters' (in my case it was some German 'ü's). I would receive the following error from rclone in trying to use the Powershell script:

incorrect password: password contains invalid utf8 characters

I was able to get around this by using the following:

[Console]::OutputEncoding = [Text.Encoding]::Utf8

However, this goes well beyond my limited knowledge of Powershell, so user beware!

References

5 Likes

That is a great document - thank you :smiley: That is exactly why I put that command in, in the hope that people would figure out how to use it on all the platforms I know nothing about!

Would you mind writing it up on the rclone wiki then we can link to it from the docs docs/content/docs.md as an example of how to use --password-command on Windows. You could send a PR linking it in if you wanted too :slight_smile:

Thank you for the tip!

I have successfully used the same PowerShell trick in other cases. Did not notice the new password command flag in latest rclone version, and your post made me realize I could utilize this for hazzle-free configuration encryption.

Your version probably works great, but hope you don't mind me sharing my variation. It is an all-in-one code block that checks if the password file exists, if it does not then prompts the user to enter the configuration password which is then stored encrypted in the file. Later it will just read and decrypt this file without user interaction. The code can be stored in a PowerShell script file and referred to like your example, but also it can be specified directly as command line argument to powershell.exe.

Base PowerShell code:

[Console]::OutputEncoding = [Text.Encoding]::UTF8
if (-not (Test-Path -LiteralPath 'C:\Path\To\Password.sec'))
{
    Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline
}
New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath 'C:\Path\To\Password.sec' -Raw | ConvertTo-SecureString) | Select-Object -ExpandProperty Password

It can be condensed into a single-liner that can be supplied as command line argument to rclone, although not very convenient in every day use:

rclone lsd remote: --password-command "powershell -NoProfile -Command [Console]::OutputEncoding = [Text.Encoding]::UTF8; if (-not (Test-Path -LiteralPath 'C:\Path\To\Password.sec')) { Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline } New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath 'C:\Path\To\Password.sec' -Raw | ConvertTo-SecureString) | Select-Object -ExpandProperty Password"

More convenient is to store it in environment variable:

SET RCLONE_PASSWORD_COMMAND=powershell -NoProfile -Command [Console]::OutputEncoding = [Text.Encoding]::UTF8; if (-not (Test-Path -LiteralPath 'C:\Path\To\Password.sec')) { Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString ^| ConvertFrom-SecureString ^| Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline } New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath 'C:\Path\To\Password.sec' -Raw ^| ConvertTo-SecureString) ^| Select-Object -ExpandProperty Password

Edit: Added setting of [Console]::OutputEncoding, like you did. It may be needed (only) if you have non-ascii characters in your password, because PowerShell by default writes to standard output using the legacy OEM code page for compatibility with the windows console, and rclone assumes the data is UTF-8 encoded when reading the command output.

Edit 2: I took the liberty to update the wiki page that was already created based on the original post.

5 Likes

Glad there's someone here who really knows Powershell to improve this!

A couple of (minor) notes:

  • the ^| is required in the DOS SET command, but if you use
Windows 10 Settings : Edit environment variables for your account

you only need the one '|' character

  • I use your version now on a couple of PCs (my environment variable xxUSB1 is a USB thumbdrive for storage of rclone config password files based on the COMPUTERNAME) :
powershell -NoProfile -Command [Console]::OutputEncoding=[Text.Encoding]::UTF8; $pwF='{0}\BAK\rclone.confPW{1}' -f $env:xxUSB1,$env:COMPUTERNAME;if (-not (Test-Path -LiteralPath $pwF)) { Read-Host -Prompt 'Enter Rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -LiteralPath $pwF -NoNewline } New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath $pwF -Raw | ConvertTo-SecureString) | Select-Object -ExpandProperty Password

Thanks again for your reply, and updating the wiki!

You are absolutely right, regarding the ^| escaping. I updated the wiki text.

I just use gpg2 in Windows. Created a text file with my password, encrypted it using a symmetric cipher (gpg -c), and set RCLONE_PASSWORD_COMMAND as gpg -d ...
gpg-agent stores passwords in its cache. It also has a nice pinentry. Very convenient.

2 Likes

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.