I have a script that accepts two strings, each are delimited by '|-|'
. The second string can contain any character other than '
.
To call the script I do:
PowerShell .\script.ps1 -arg1 'Hello|-|World' -arg2 'random|-|dwua0928]43d}'
It raises an error on the character }
. How can I resolve this?
Edit:
It also has an issue with the -
from the delimiters and raises the same error:
At line:1 char:54
.\Script.ps1 -arg2 <redacted>|-|<redacted> ...
~
Missing expression after unary operator '-'.
At line:1 char:53
.\Script.ps1 -arg1 <redacted>|-|<redacted> ...
~
Expressions are only allowed as the first element of a pipeline.
It does that at every instance of |-|
. It does it with the brackets if I change the delimiter to /-/
:
At line:1 char:168
... <redacted>/-/<redacted>!OW}:Lj<redacted> ...
~
Unexpected token '}' in expression or statement.
At line:1 char:181
... /-/<redacted>cO0}e]k<redacted> ...
~
Unexpected token '}' in expression or statement.
The beginning of the script is this:
Param
(
[switch] $enable,
[string] $arg1,
[string] $arg2
)
CodePudding user response:
There's generally no need to call the PowerShell CLI (
powershell.exe
for Windows PowerShell,pwsh
for PowerShell (Core) 7 ) from inside PowerShell.Assuming you're running Windows PowerShell (or, to generalize, the same edition of PowerShell), you can invoke your script directly:
.\script.ps1 -arg1 'Hello|-|World' -arg2 'random|-|dwua0928]43d}'
If you still want to call the CLI - which is expensive, because it involves creating a child process, and also results in a loss of type fidelity - use a script block (
{ ... }
), but note that this works only from inside PowerShell (though it works across both PowerShell editions, i.e., you can callpwsh.exe
from Windows PowerShell, andpowershell.exe
from PowerShell (Core) 7 )powershell { .\script.ps1 -arg1 'Hello|-|World' -arg2 'random|-|dwua0928]43d}' }
If you were to call from outside PowerShell, it is best to use the
-File
CLI parameter rather than the (implied in Windows PowerShell)-Command
parameter:powershell -File .\script.ps1 -arg1 "Hello|-|World" -arg2 "random|-|dwua0928]43d}"
While this works from inside PowerShell too, the disadvantage compared to the
{ ... }
approach is that the output is only ever text, whereas the{ ... }
approach is - within limits - capable of preserving the original data types - see this answer for more information.In order to make a
-Command
-based command line work, enclose the PowerShell code in"..."
as a whole, in which case the embedded'...'
strings are passed as such:powershell -Command ".\script.ps1 -arg1 'Hello|-|World\' -arg2 'random|-|dwua0928]43d}'"
For a comprehensive overview of the PowerShell CLI, see this post.
As for what you tried:
You called
powershell.exe
with neither-File
(-f
) nor-Command
(-c
), which defaults to-Command
(note that, by contrast,pwsh
, the PowerShell (Core) 7 CLI, defaults to-File
).When
-Command
is used, PowerShell's command-line processing first strips all subsequent arguments of any syntactic (i.e., unescaped)"
characters, namely from"..."
-enclosed arguments, joins the resulting tokens with spaces, and then interprets the resulting string as PowerShell code.In your case, the fact that you used
'...'
quoting around the arguments is irrelevant:- PowerShell invariably translates the original quoting into
"..."
quoting when calling external programs (as they can only be expected to"..."
quoting, not also'...'
quoting) - However, it only uses
"..."
quoting if needed, which is solely based on whether the argument at hand contains spaces.
- PowerShell invariably translates the original quoting into
Neither of your arguments, verbatim Hello|-|World
and random|-|dwua0928]43d}
, contained spaces, so they were placed as-is on the command line for powershell.exe
(though note that even if they did contain spaces and had been enclosed in "..."
as a result, PowerShell's command-line processing would have stripped the "
chars.)
The net result was that the powershell.exe
child process tried to execute the following PowerShell code, which predictably breaks with the errors shown in your question:
# !! Note the absence of quoting around the -arg1 and -arg2 values.
.\script.ps1 -arg1 Hello|-|World -arg2 random|-|dwua0928]43d}
You can easily provoke the error you saw as follows from a PowerShell session:
# -> Error "Missing expression after unary operator '-'."
Write-Output Hello|-|World