Updated Windows PowerShell use rclone password command for config file password (markdown)

albertony
2025-07-08 21:42:12 +02:00
parent 25493b4db5
commit ab48d2e1ff

@ -12,8 +12,9 @@ As of release 1.51, rclone can be configured to execute a command and read the p
**Step 1: Store encrypted password file** **Step 1: Store encrypted password file**
Create a file containing your password in encrypted form (for the purpose of this example, `C:\Path\To\Password.sec`): Create a file containing your password in encrypted form (for the purpose of this example, `C:\Path\To\Password.sec`), by entering entering it interactively in a secure prompt:
```
```pwsh
Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline
``` ```
@ -21,31 +22,39 @@ Read-Host -Prompt 'Enter rclone configuration password' -AsSecureString | Conver
Create a PowerShell script (for the purpose of this example, `C:\Path\To\Password.ps1`), to return the decrypted password from the file you created in the previous step (notice how the same file is referenced in the -LiteralPath parameter): Create a PowerShell script (for the purpose of this example, `C:\Path\To\Password.ps1`), to return the decrypted password from the file you created in the previous step (notice how the same file is referenced in the -LiteralPath parameter):
``` ```pwsh
New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath 'C:\Path\To\Password.sec' -Raw | ConvertTo-SecureString) | Select-Object -ExpandProperty Password New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content -LiteralPath 'C:\Path\To\Password.sec' -Raw | ConvertTo-SecureString) | Select-Object -ExpandProperty Password
``` ```
**Step 3: Test** **Step 3: Encrypt rclone configuration file**
We can now instruct rclone to use powershell to execute the script created in the previous step instead of prompting for the password for decrypting the configuration file: If you already have encrypted your rclone configuration file using the password entered in step 1, you can move directly to step 3. If not, you can now enable encryption. When doing that, you can instruct rclone to run powershell and execute the script created in the previous step, i.e. let it automatically read and decrypt the password from the encrypted file, with the command:
```cmd
rclone --password-command "powershell -NoProfile -File C:\Path\To\Password.ps1" config encryption set
``` ```
**Step 4: Test**
Run a test command, where you instruct rclone to run powershell and execute the script created in step 2 instead of prompting for the password when decrypting the configuration file:
```cmd
rclone -vv --password-command "powershell -NoProfile -File C:\Path\To\Password.ps1" about remote: rclone -vv --password-command "powershell -NoProfile -File C:\Path\To\Password.ps1" about remote:
``` ```
**Step 4: Use** **Step 5: Use**
As tested in previous step the password command can be supplied as a command-line argument, which is appropriate for your rclone commands in other scripts. But for your interactive use it is not very convenient (unless you have a very long password it would probably be quicker just to drop it and enter the password when rclone prompts for it). To make sure the command is automatically included in your every rclone commands you can store it in environment variable `RCLONE_PASSWORD_COMMAND` instead - set it to value `powershell C:\Path\To\Password.ps1` As tested in previous step, the password command can be supplied as a command-line argument, which is appropriate for your rclone commands in other scripts. But for your interactive use it is not very convenient (unless you have a very long password it would probably be quicker just to drop it and enter the password when rclone prompts for it). To make sure the command is automatically included in your every rclone commands you can store it in environment variable `RCLONE_PASSWORD_COMMAND` instead - set it to value `powershell C:\Path\To\Password.ps1`
From now on you can execute rclone commands without having to enter your configuration file password ever again. From now on you can execute rclone commands without having to enter your configuration file password ever again.
# Example 2 # Example 2
Instead of separating the two operations of (1) encrypting password and storing in file, and (2) reading file and decrypting the password, we can write a combined all-in-one PowerShell code block: It 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 in example 1 above, but also it can be specified directly as command line argument to powershell.exe. Instead of doing as in example 1 above, separating the two operations of (1) encrypting password and storing it in file, and (2) reading the file and decrypting the password, we can write a combined all-in-one PowerShell code block: It 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 in example 1 above, but also it can be specified directly as command line argument to powershell.exe.
Base PowerShell code: Base PowerShell code:
``` ```pwsh
[Console]::OutputEncoding = [Text.Encoding]::UTF8 [Console]::OutputEncoding = [Text.Encoding]::UTF8
if (-not (Test-Path -LiteralPath 'C:\Path\To\Password.sec')) if (-not (Test-Path -LiteralPath 'C:\Path\To\Password.sec'))
{ {
@ -56,18 +65,37 @@ New-Object -TypeName System.Net.NetworkCredential -ArgumentList '', (Get-Content
It can be condensed into a single-liner that can be supplied directly as command-line argument powershell.exe: It can be condensed into a single-liner that can be supplied directly as command-line argument powershell.exe:
``` ```cmd
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 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
``` ```
To make sure the command is automatically executed for every rclone command, you can now just store this entire string as the value of environment variable `RCLONE_PASSWORD_COMMAND`. You can also supply it to rclone command-line argument --password-command with double quotes around it: `rclone lsd remote: --password-command "powershell -NoProfile -Command [Console]::OutputEncoding ..."`. If you want to set the environment variable from command prompt or a batch script remember to escape the `|'`characters into `^|`, like this: To make sure the command is automatically executed for every rclone command, you can now just store this entire string as the value of environment variable `RCLONE_PASSWORD_COMMAND`. You can also supply it to rclone command-line argument --password-command with double quotes around it: `rclone lsd remote: --password-command "powershell -NoProfile -Command [Console]::OutputEncoding ..."`. If you want to set the environment variable from command prompt or a batch script remember to escape the `|'`characters into `^|`, like this:
``` ```cmd
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 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
``` ```
# Notes # Notes
## Alternative password input
Looking back at example 1 step 1, instead of relying on interactively prompting for the password when creating the encrypted file, an alternative approach is to use a command where the password (for the purpose of this example, `password123`) is given in plain text:
```pwsh
ConvertTo-SecureString -String "password123" -AsPlainText -Force | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline
```
This is obviously a less secure approach, as the plain text password is visible on your shell, and will probably also be recorded in your shell history.
Another alternative is to, instead of run a command with the actual password, run a command that generates a password for you. In the following example we use a .NET method for generating secure passwords, and we are requesting a password of length 12 with 2 non-alphanumeric characters in it:
```pwsh
Add-Type -AssemblyName System.Web
ConvertTo-SecureString -String ([System.Web.Security.Membership]::GeneratePassword(12, 2)) -AsPlainText -Force | ConvertFrom-SecureString | Out-File -LiteralPath 'C:\Path\To\Password.sec' -NoNewline
```
Since you don't know the password in advance with this approach, you obviously cannot encrypt the rclone configuration first, but need to use the password decrypted from the file when doing that, exactly how it is described in step 3.
## Encryption ## Encryption
Encryption is based on the [Data Protection API (DPAPI)](https://en.wikipedia.org/wiki/Data_Protection_API) component in Windows, which it uses to protect various passwords, certificate private keys, and other sensitive data. It is a symmetric encryption using key derived from the current user account. One of the main advantages of using DPAPI, is that it handles the otherwise difficult problem of explicitly generating and storing a cryptographic key. Encryption is based on the [Data Protection API (DPAPI)](https://en.wikipedia.org/wiki/Data_Protection_API) component in Windows, which it uses to protect various passwords, certificate private keys, and other sensitive data. It is a symmetric encryption using key derived from the current user account. One of the main advantages of using DPAPI, is that it handles the otherwise difficult problem of explicitly generating and storing a cryptographic key.
@ -80,11 +108,15 @@ If your password contain non-ascii characters (like German 'ü' or Norwegian 'ø
Rclone will report the following error if a mismatch occurs: Rclone will report the following error if a mismatch occurs:
`incorrect password: password contains invalid utf8 characters` ```
incorrect password: password contains invalid utf8 characters
```
The solution is to execute the following statement in your PowerShell script to ensure UTF-8 encoded output: The solution is to execute the following statement in your PowerShell script to ensure UTF-8 encoded output:
`[Console]::OutputEncoding = [Text.Encoding]::UTF8` ```pwsh
[Console]::OutputEncoding = [Text.Encoding]::UTF8
```
# References # References