resticprofile icon indicating copy to clipboard operation
resticprofile copied to clipboard

PowerShell Command Execution in `run-before` Hook on Windows

Open Mykhailo-Roit opened this issue 3 months ago • 1 comments

Bug Report: PowerShell Command Execution in run-before Hook

Description

PowerShell commands containing nested quotes fail to execute correctly when defined in the run-before section of the resticprofile configuration file (test.yml). The command appears to be parsed incorrectly by the shell invoking it, leading to execution failures or syntax errors.

Reproduction Steps

  1. Configuration: Create a test.yml with the following content:
    version: "1"
    
    test:
      repository: "c:\restic\temp\repo"
      password-file: "password.txt"
      initialize: true
      run-before:
        - powershell -Command "New-Item -Path 'c:\restic\temp\testfile.txt' -ItemType File -Value 'This is a test file.' -Force"
      backup:
        source:
          - c:\restic\temp\testfile.txt
    
  2. Execution: Run the backup profile:
    resticprofile -v --config C:\restic\test.yml --name test backup
    

Observed Behavior

  • The command does not execute successfully.
  • The file c:\restic\temp\testfile.txt is not created.
  • No clear error message is always displayed in the resticprofile output, but manual reproduction via cmd /c shows parsing errors.

Root Cause Analysis

resticprofile likely executes shell commands using the system's default shell (e.g., cmd.exe on Windows). When passing a command string that includes double quotes (") for the -Command argument and single quotes (') for PowerShell parameters, the outer shell (cmd.exe) may misinterpret the quotes.

For example, cmd.exe might strip the outer quotes or fail to handle the nested quotes, causing powershell.exe to receive a malformed command string.

Workaround / Solution

To avoid quoting and escaping issues between shells, use the -EncodedCommand parameter of PowerShell. This accepts a Base64-encoded string of the command.

Example Fix

  1. Generate Base64 Command:
    $cmd = "New-Item -Path 'c:\restic\temp\testfile.txt' -ItemType File -Value 'This is a test file.' -Force"
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
    $encoded = [Convert]::ToBase64String($bytes)
    Write-Host $encoded
    
  2. Update Configuration:
    run-before:
      - powershell -EncodedCommand <Base64String>
    

Alternatively, placing the command in a separate .ps1 file and executing it with -File also resolves the issue:

run-before:
  - powershell -File path\to\script.ps1

Mykhailo-Roit avatar Nov 21 '25 16:11 Mykhailo-Roit

Hi,

Thank you for this very detailed description of the issue, along with potential fixes. I wasn't aware of the base64 form and I do like this idea.

I'll see if I automatically convert a command line with quote into the base64 form 👍🏻

creativeprojects avatar Dec 02 '25 22:12 creativeprojects