Note:
The symptom is likely caused by variables containing the empty string (see below), even though the sample argument values in the question never result in such, given that no string interpolation is performed, because the syntax form $[var]
isn't a valid variable reference.
You also mention special characters as a problem, though that is unlikely, given that PowerShell passes them through correctly, even with variable references not enclosed in "..."
, the latter generally not being necessary in PowerShell (e.g., some.exe $var
is sufficient, no need for some.exe "$var"
).
but the problem is when if one these parameter is empty, one parameter takes the value of another one
You're likely seeing a long-standing bug present in Windows PowerShell and in PowerShell (Core) up to version 7.2.x - it has been fixed in v7.3+, with selective exceptions on Windows - see this answer for details (it focuses on arguments with embedded double-quotes, but the issue at hand is part of the problem).
Trying to pass an empty string (""
, ''
) as an argument to an external program is quietly ignored; that is, no argument is passed at all.
Note that, by contrast, passing $null
is ignored by design.
Examples:
The following uses python
to simply echo the arguments it was passed.
# Pass an empty-string *literal*
python -c 'import sys; print(sys.argv[1:])' '' hi
# Pass an empty string via a *variable*
$someArg=''
python -c 'import sys; print(sys.argv[1:])' $someArg hi
- The expected output is
['', 'hi']
- With the bug present, the output is
['hi']
, indicating that the empty string wasn't passed at all.
Workarounds:
Module-based polyfill:
If you need to write cross-edition, cross-version PowerShell code, the Native
module (Install-Module Native
; authored by me), has an ie
function (short for: Invoke Executable), which is a polyfill that provides workaround-free, cross-edition (v3+), cross-platform, cross-version, forward-compatible behavior in the vast majority of cases, both for passing empty-string arguments and arguments with embedded "
chars. correctly - simply prepend ie
to your external-program calls:
# With the 'Native' module installed, simply prepending `ie`
# to your external-program calls ensures that both empty-string
# arguments and arguments with embedded " chars. are passed correctly.
ie python -c 'import sys; print(sys.argv[1:])' '' hi
[1] Small caveat: unlike true conditionals, this shortcut performs no short-circuiting; that is, both array elements are evaluated up front, before the appropriate element is selected by the index expression.