Search code examples
powershellgnupg

Powershell: gpg command parameters with embedded double quotes


I'm trying to call gpg2 from a Powershell script. I need to pass parameters with embedded quotes but I get some very odd behavior when I look at the results from echoargs or the executable directly.

$Passphrase = "PassphraseWith!$#" #don't worry, real passphrase not hardcoded!
$Filename = "\\UNC\path\with\a space\mydoc.pdf.pgp"
$EncyptedFile = $Filename  -replace "\\", "/"
$DecryptedFile = $EncyptedFile -replace ".pgp" , ""

$args = "--batch", "--yes", "--passphrase `"`"$PGPPassphrase`"`"", "-o `"`"$DecryptedFile`"`"", "-d `"`"$EncyptedFile`"`""
& echoargs $args
& gpg2 $args

gpg requires me to use double quotes for the passphrase because it has symbols and for the paths because of a space (confirmed this works when I run a sample single command directly from command prompt). Also, gpg wants UNC paths with forward slashes (confirmed this works too).

As you can see I am trying to wrap the passphrase and file paths with paired escaped double quotes because echoargs seems to indicate the outer quotes are being stripped off. Here is what i get from echoargs:

Arg 0 is <--batch>
Arg 1 is <--yes>
Arg 2 is <--passphrase "PassphraseWith!$#">
Arg 3 is <-o "//UNC/path/with/a space/mydoc.pdf">
Arg 4 is <-d "//UNC/path/with/a space/mydoc.pdf.pgp">

Command line:
"C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\PSCX\Apps\EchoArgs.exe" --batch --yes "--pass
phrase ""PassphraseWith!$#""" "-o ""//UNC/path/with/a space/mydoc.pdf""" "-d ""//UNC/path/with/a space/mydo
c.pdf.pgp"""

However, gpg2 gives the following result (whether run from ISE or PS directly):

gpg2.exe : gpg: invalid option "--passphrase "PassphraseWith!$#""

If I try & gpg2 "$args" to convert the array to a string then I get the following similar result:

gpg2.exe : gpg: invalid option "--batch --yes --passphrase "PassphraseWith!$#"

Any ideas on this one?


Solution

  • @PetSerAl's solution: You need to tokenize the flag/parameter and its value, so split out into two elements in the array:

    "--passphrase", "`"$Passphrase`""
    

    not combined as:

    "--passphrase `"`"$Passphrase`"`""
    

    Note that regular Powershell escaping quotes using backticks works fine here. Full example below:

    $Passphrase = "PassphraseWith!$#" #don't worry, real passphrase not hardcoded!
    $Filename = "\\UNC\path\with\a space\mydoc.pdf.pgp"
    $EncyptedFile = $Filename  -replace "\\", "/"
    $DecryptedFile = $EncyptedFile -replace ".pgp" , ""
    
    $params = "--batch", "--quiet", "--yes", "--passphrase", "`"$Passphrase`"", "-o", "`"$DecryptedFile`"", "-d", "`"$EncyptedFile`""
    & echoargs $params
    & gpg2 $params