Trial #20: Passing a Scriptblock with Arguments to a New Powershell Instance
Problem:
Its quite hard to Pass a Scriptblock with Arguments to a new powershell instance.
In a normal process the following works perfectly:
However the following and hundred of similar more complex variations produced odd string based output and useless errors.
I spent at least an hour trying lots of slightly different syntax arrangements, escaped characters. I even tried passing a command “-“ as I haven’t bothered learning all the meanings of this syntax.
PowerShell[.exe]
[-Command { - | <script-block> [-args <arg-array>]
| <string> [<CommandParameters>] } ]
Also SS64 have a more descriptive but equally elusive, to me, description:
-Command Execute the specified commands (and any parameters) as though they
were typed at the PowerShell prompt, and then exit, unless NoExit is specified.
The value of Command can be "-", a string. or a script block.
If the value of Command is "-", the command is read from standard input.
Anyway there are lots of ways to get this wrong and lots of bad workarounds.
Solution:
I finally found an acceptable syntax for passing arguments to a new powershell instance. It is actually in line with the above quoted syntax -Command <script-block> [-args <arg-array>]
.
After many different variations with odd output and useless errors. I did finally get a useful type error using an variation including an “Invoke-Command”.
As this stated that my $command parameter was of type string and must be a script-block I tried to through on another set of curly braces.
In addition to getting better error messages, using the Invoke-Command gives you the recognisable “-ArgumentList” parameter to operate against the given Command that you are missing with the standard powershell.exe parameters.
No need for any extra complex escaping or unwanted persisted variables. Just keep the script block in curly braces so it remains a script block on arrival in the new session. At least in this simple case. It also works without the invoke-command as follows
Update 10/9/2020
Following a comment from Boris Andonov.
I should reinforce that the second last example using Invoke-Command
is more powerful than & and will allow you to pass several arguments for example
Furthermore although $arg = "HAM"
is acceptable $arg = "HAM SANDWICH"
is not. “If the string contain spaces it must be encapsulated with double quotes and single quotes.” So we must write, $arg = "'HAM SANDWICH'"
.
And amazingly if you want to escape double quotes inside a string requires 8 double quotes:
Leave a comment