Skip to content

PowerShell Command Execution in run-before Hook on Windows #582

@Mykhailo-Roit

Description

@Mykhailo-Roit

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestwindowsConcerns only Windows OS

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions