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
{ -noexit -file "$a" }to'-noexit','-file',$a$ahappens to contain a path with spaces,-ArgumentList '-noexit', '-file', $afails.