1

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?

2
  • 1
    Change { -noexit -file "$a" } to '-noexit','-file',$a Commented Jun 21, 2021 at 8:26
  • 1
    Good point re script blocks, @MathiasR.Jessen, but I suggest always recommending a single string that encodes all arguments, for the reasons stated in my answer. For instance - as unfortunate as that is - if $a happens to contain a path with spaces, -ArgumentList '-noexit', '-file', $a fails. Commented Jun 21, 2021 at 13:29

2 Answers 2

4

tl;dr

To pass pass-through arguments to Start-Process's -ArgumentList (-Args) parameter:

$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.

  • Note: While passing pass-through arguments individually to -ArgumentList, as the elements of an array (-ArgumentList '-noexit', '-file', $a), may conceptually be preferable, it is unfortunately marred by a long-standing bug in Start-Process that will not be fixed as such, so as not to break backward compatibility - see GitHub issue #5576; in short, array elements that (may) contain spaces must unexpectedly be enclosed in embedded double quotes (-ArgumentList '-noexit', '-file', "`"$a`"")
    For now, using a single string that encodes all arguments, each enclosed in embedded "..." quoting if necessary (as shown above), is therefore preferable.
    As discussed in the linked GitHub issue, an alternative -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.

  • Note: You can use script blocks when you invoke 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
Sign up to request clarification or add additional context in comments.

Comments

0

A good way to pass the Start-Process argument list is:

-argumentlist @("argument1", "argument2", ...)

This syntax makes use of the fact that ArgumentList by default expects a string array:

Start-Process
     [-FilePath] <string>
     [[-ArgumentList] <string[]>]

2 Comments

While passing pass-through arguments individually to -ArgumentList, as the elements of an array may conceptually be preferable, it is unfortunately marred by a long-standing bug in Start-Process that will not be fixed as such, so as not to break backward compatibility; in short, array elements that (may) contain spaces must unexpectedly be enclosed in embedded double quotes (-ArgumentList '-noexit', '-file', "`"$a`"").
For now, using a single string that encodes all arguments, each enclosed in embedded "..." quoting if necessary (-ArgumentList "-noexit -file `"$a`""), is therefore preferable. As discussed in the original bug report, GitHub issue #5576, an alternative -ArgumentArray parameter that supports robust array-based argument passing may be introduced in the future.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.