Powershell: Call operator (&) with escape param (--%) not working with non-static args Powershell: Call operator (&) with escape param (--%) not working with non-static args powershell powershell

Powershell: Call operator (&) with escape param (--%) not working with non-static args


Ok, probably weird to be answering my own question, but after spending another day on this problem yesterday, I might have realized the answer myself. At least, this is what I found that works. But I post here to get further feedback, in case I'm really doing something that isn't recommended ...using Invoke-Expression :-)

I had sorta realized early on, and some of you confirmed this in your responses, that the --% prevents all further expansions (including my $variables). And my problem is that I'm still needing to expand lots of things when trying to use the Call operator (&). My problem would be solved if my command line was all ready to go before using --%, so that's what I did.

I created a new string, composed of:

$fullCommand = '& "other.exe" --% ' + $commandArgs

(The EXE path actually has spaces in it, hence the quotes.) Then, with it all built up (including the --% where it needs to be), I invoke it as a new piece of script:

Invoke-Expression $fullCommand

So far, I'm having very good results. But I know in my search up to this point that Invoke-Expression sounded like this bad thing people shouldn't use. Thoughts, everyone?


The purpose of --% is to suppress argument processing, so there's no expansion of variables after that parameter on behalf of PowerShell. You can work around this by using environment variables, though:

$env:UserMode = 'foo'$env:UserArgs = 'bar baz'& other.exe --% action /mode %UserMode% /path:"location with spaces" /fancyparam { /dothis /dothat:"%userArgs%" } /verbose


I always recommend that people build their command line arguments into a variable, and then pass that variable into the -ArgumentList parameter of the Start-Process cmdlet.

$Program = '{0}\other.exe' -f $PSScriptRoot;$UserMode = 'fast';$Path = 'c:\location with\spaces';$ArgWithSpaces = 'arg with spaces';$ArgumentList = 'action /mode {0} /path:"{1}" /fancyparam { /dothis /dothat:"{2}" } /verbose' -f $UserMode, $Path, $ArgWithSpaces;$Output = '{0}\{1}.log' -f $env:Temp, [System.Guid]::NewGuid().ToString();Start-Process -Wait -FilePath $Program -ArgumentList $ArgumentList -RedirectStandardOutput $Output;