0

My scripts runs an external command without any issue:

$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
& "C:\Program Files\7-Zip\7z.exe" a "$Target" @C:\Webs\Scripts\include.txt -w

But it totally breaks when I add further switches:

$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
& "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf -i@C:\Webs\Scripts\include.txt -x@C:\Webs\Scripts\exclude.txt -w
7z.exe : ERROR: X:\Backup 2017-12-27.7z
At C:\Webs\Scripts\backup.ps1:50 char:1
+ & "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf -i@C:\Webs\Scripts\include.t ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (ERROR: X:\Backup 2017-12-27.7z:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

X:\Backup 2017-12-27.7z
Open ERROR: Can not open the file as [7z] archive
ERRORS:
Headers Error
System ERROR:
Incorrect function.

The command runs fine from cmd. What PowerShell syntax am I breaking and how do I fix it?

3
  • 2
    EchoArgs parses the command nicely. As a wild guess, what happens if you use an underscore instead of a space? $Target= "X:\Backup_2017-12-27.7z" ? Commented Dec 27, 2017 at 9:38
  • 3
    I seem to remember having a similar problem, I fixed it by having each parameter as a string. Something like & $command $p1 $p2 $p3 $p4 . This should work, I can't explain why, could be to do with how PS interprets all the syntax Commented Dec 27, 2017 at 9:42
  • @vonPryz Awesome, that seems to do the trick... I hardly have any experience with PowerShell, is there a way to have spaces in arguments? Commented Dec 27, 2017 at 9:54

2 Answers 2

2

Sometimes PowerShell's parameter parsing interferes with parameters you want to pass to an external program. that's why you want to make sure that PowerShell sees those parameters as mere strings and not as parameters it's supposed to handle itself. You do that by putting quotes around the whole argument:

$program = 'C:\path\to\your.exe'
& $program '-a' '-b:foo'

and/or putting the argument in a variable:

$program = 'C:\path\to\your.exe'
$param1  = '-a'
$param2  = '-b:foo'
& $program $param1 $param2

An even better approach is to collect all parameters in an array and splat that array onto the program:

$program = 'C:\path\to\your.exe'
$params  = '-a', '-b:foo'
& $program @params

Starting with PowerShell v3 you could also use the "magic parameter" (--%) to prevent PowerShell from parsing the arguments:

$program = 'C:\path\to\your.exe'
& $program --% -a -b:foo

Note, however, that PowerShell won't evaluate anything right of the --%, meaning that everything (including variables) will be passed as literals.

$program = 'C:\path\to\your.exe'
& $program --% $foo

In the above code snippet the program would be called with a literal string '$foo' rather than the value of the variable $foo.

For further information on running external commands from PowerShell see here.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is caused by the spaces in $Target. I have no idea why it's a problem or not depending on the presence of other switches. As @TimTharratt points out, the workaround of moving text to variables works for me. Injected variables don't even need to be quoted:

$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
$Include = "-i@C:\Webs\Scripts\include.txt"
$Exclude = "-x@C:\Webs\Scripts\exclude.txt"
& "C:\Program Files\7-Zip\7z.exe" a $Target -spf $Include $Exclude -w

I'd gladly accept any answer that provides a proper fix or (if that's even possible without a full CS major) explains the syntax of PowerShell regarding spaces. Meanwhile, here's a hack to get things done.

1 Comment

Just as an aside, the $Include and $Exclude variables are not needed and will work on the command line directly if you quote their contents as parameters. (The general rule is that - parameters that have an attached argument need to be quoted.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.