c:\test.ps1 exists and is an empty file.
Start-Process -filepath powershell -argumentlist { -noexit -file "c:\test.ps1" }
opens a new powershell window and keeps it open (which is what I want).
$a = "c:\test.ps1"
Start-Process -filepath powershell -argumentlist { -noexit -file "$a" }
briefly flashes a new Powershell window and then closes it immediately. I wonder why?
tl;dr
To pass pass-through arguments to Start-Process
's -ArgumentList
(-Args
) parameter:
DO NOT use a script block ({ ... }
).
DO use a single, expandable string ("..."
):
$a = "c:\test.ps1"
Start-Process powershell "-noexit -file `"$a`""
Note: Parameter names -FilePath
and -ArgumentList
are positionally implied in this command; that is, the command is equivalent to Start-Process -FilePath powershell -ArgumentList "-noexit -file `"$a`""
As for what you tried:
Start-Process
's -ArgumentList
(-Args
) parameter is [string[]]
typed, i.e. it expects an array of string arguments to pass to the external program being launched - given that strings are the only supported data type when passing arguments to external programs.
-ArgumentList
(-ArgumentList '-noexit', '-file', $a
) is conceptually the best approach, it is unfortunately ill-advised due to a long-standing bug in Start-Process
, still present as of this writing (v7.2) - see GitHub issue #5576."..."
quoting if necessary (as shown above), is the only robust approach.-ArgumentArray
parameter that supports robust array-based argument passing may be introduced in the future.When you pass a script block ({ ... }
), it is stringified (its .ToString()
method is implicitly called, and a script block's stringification is its verbatim contents (excluding the enclosing {
and }
), which means that no expansion (string interpolation) takes place;
try { $HOME }.ToString()
, for instance.
powershell.exe
directly, synchronously (rather than via Start-Process
), but only from PowerShell, and such script blocks are executed by the callee, and therefore also do not see the caller's variables; you can, however, pass arguments to them; e.g.:powershell { "args passed: $args" } -args 1, 2