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.exefor Windows PowerShell,pwshfor 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.exefrom Windows PowerShell, andpowershell.exefrom 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
-FileCLI parameter rather than the (implied in Windows PowerShell)-Commandparameter: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.exewith neither-File(-f) nor-Command(-c), which defaults to-Command(note that, by contrast,pwsh, the PowerShell (Core) 7 CLI, defaults to-File).When
-Commandis 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
