I have a command similar to the following that I need to run as part of a PowerShell script:
gfpca -run.config default.conf
However, I receive the error Command not found: .conf
on the output. This happens if I run with Invoke-Expression
as well. I have also tried escaping the character, but don't see a difference:
Invoke-Expression('gfpca -run`.config default.conf')
How can I run this command within PowerShell?
CodePudding user response:
Use the &
invocation operator to invoke the program and use regular '
single-quotes to qualify the argument boundaries:
& gfpca '-run.config' 'default.conf'
Now, PowerShell will pass -run.config
and default.conf
to gfpca
as-is without attempting to interpret them as native parameters
CodePudding user response:
tl;dr
Due to an unfortunate bug, present up to at least PowerShell 7.1.2, escaping or quoting of the argument that starts with -
and contains .
is required, which in the simplest case means:
# Note the ` before -
gfpca `-run.config default.conf
Mathias R. Jessen's answer provides an effective solution, but let me add some context:
You only need to escape or quote one of your arguments,
-run.config
, due to a PowerShell bug, where passing an unquoted argument that starts with-
and contains a.
to an external program is mistakenly passed as two arguments.In other words: Without escaping or quoting such an argument (see below), PowerShell mistakenly passes
-run.config
as separate arguments-run
and.config
The bug, present up to at least PowerShell 7.2.1, has been reported in GitHub issue #6291, where it was acknowledged as such, but is awaiting a fix; it is one of several bugs relating to
-
-prefixed tokens.
While using
&
, the call operator, unconditionally for command invocations is a robust approach, it is important to note that it is only necessary if the command name or path is quoted and/or contains variable references - which isn't the case here.- See this answer for details.
Invoke-Expression
(iex
) should generally be avoided - see this answer. Specifically, do not use it to invoke an external program or PowerShell script - see this answer.- As an aside: Your call,
InvokeExpression('...')
, uses pseudo method syntax, which is to be avoided: PowerShell functions, cmdlets, scripts, and external programs must be invoked like shell commands -Invoke-Expression '...'
- not like C# methods. That is, don't put ((...)
around the argument list, and separate argument with whitespace, not with,
. See this answer for more information.
- As an aside: Your call,
While `
(PowerShell's escape character), which you tried to use, is (a) key to the solution, it must be applied to the initial -
, which prevents PowerShell from (inappropriately) parsing the argument according to the rules of PowerShell-native parameter names.[1]
# Note the ` before -
gfpca `-run.config default.conf
As shown in Mathias' answer, using a quoted string around the whole argument (e.g. '-run.config'
) is another alternative.
[1] Because parameter names aren't expected to require escaping, what follows -
is parsed verbatim, up to the first .
. Therefore, your attempt to `
-escape the .
character was ineffective: `
wasn't recognized as an escape character and therefore retained, and the bug still kicked in. By contrast, `
-escaping the initial -
prevents PowerShell from parsing the entire token as a parameter, which bypasses the bug