FatalBulletHit
FatalBulletHit

Reputation: 842

Why does pwsh.exe in combination with Start-Process not accept a script block directly?

Why does Start-Process powershell.exe { Read-Host } work, but Start-Process pwsh.exe { Read-Host } does not?

I'm aware of the -ArgumentList switch of Start-Process, but it makes things more complicated when it comes to escaping quotation marks:

PowerShell 7.0.3 and 7.2.0-preview.3:

Start-Process pwsh.exe -ArgumentList '-Command "& {
    ''Hello World.''
    Read-Host
}"' -Verb RunAs

PowerShell 5.1:

Start-Process powershell.exe { 
    'Hello World.'
    Read-Host
} -Verb RunAs

On the other hand, when creating a new PowerShell session (without Start-Process), it is still possible to use a script block:

pwsh.exe {
    'Hello World.'
    Read-Host
}

Am I missing something here or is there a better/different approach which allows a script block to be executed parallel to the rest of a script?

Upvotes: 3

Views: 3945

Answers (4)

Kitten Wizard Jr
Kitten Wizard Jr

Reputation: 90

This launches a ScriptBlock in a new window, which is from groser's comment

Start-Process pwsh.exe -ArgumentList "-c", {
    'Hello World.'
    Read-Host
}, "-noexit" -WindowStyle Maximized

The following launch's a script from an open PowerShell window

Start-Process pwsh.exe -ArgumentList "-c", ".\Child-Script.ps1", "-noexit" -WindowStyle Maximized

This launches a child .ps1 in the same directory as the parent .ps1 script in a new window

Parent-Script.ps1

Start-Process pwsh.exe -ArgumentList "-c", ("$PSScriptRoot\Child-Script.ps1"), "-noexit" -WindowStyle Maximized

Upvotes: 0

Julian
Julian

Reputation: 11

Here is a working example of sending a script block to new pwsh window with start-process (powershell 7)

while(1)
{
    $script ={ write-host 'Hello World.' 
    pause
    }
    start-process -Filepath pwsh.exe -ArgumentList "-Command $script"
    pause
}

Upvotes: 1

js2010
js2010

Reputation: 27516

You don't show the error message. Pwsh defaults to -file while powershell defaults to -command. Running from cmd:

pwsh { 'hi there' }
The argument '{' is not recognized as the name of a script file. Check the spelling of 
the name, or if a path was included, verify that the path is correct and try again.

pwsh -command { 'hi there' } 
hi there

With start-process -nonewwindow you can see the error:

Start-Process -NoNewWindow pwsh.exe { Read-Host }

The argument 'Read-Host' is not recognized as the name of a script file. Check the
spelling of the name, or if a path was included, verify that the path is correct and try 
again.

Usage: pwsh[.exe] [-Login] [[-File] <filePath> [args]]
                  [-Command { - | <script-block> [-args <arg-array>]
                                | <string> [<CommandParameters>] } ]
                  [-ConfigurationName <string>] [-CustomPipeName <string>]
                  [-EncodedCommand <Base64EncodedCommand>]
                  [-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}]
                  [-Interactive] [-MTA] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile]
                  [-OutputFormat {Text | XML}] [-SettingsFile <filePath>] [-SSHServerMode]
[-STA]
                  [-Version] [-WindowStyle <style>] [-WorkingDirectory <directoryPath>]

       pwsh[.exe] -h | -Help | -? | /?

PowerShell Online Help https://aka.ms/powershell-docs

All parameters are case-insensitive.

"pwsh { 'hi there' } works within powershell. I'm not sure why.

.\echoargs { 'hi there' }

Arg 0 is <-encodedCommand>
Arg 1 is <IAAnAGgAaQAgAHQAaABlAHIAZQAnACAA>
Arg 2 is <-inputFormat>
Arg 3 is <xml>
Arg 4 is <-outputFormat>
Arg 5 is <text>

It seems to automatically run this?

pwsh -encodedCommand IAAnAGgAaQAgAHQAaABlAHIAZQAnACAA -inputFormat xml -outputFormat text

Upvotes: 5

groser
groser

Reputation: 389

pwsh get a filename by default in arguments.
If you try to run it in CMD you will see this:

CMD> pwsh { 'Hello!' }
The argument '{' is not recognized as the name of a script file. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Usage: pwsh[.exe] [-Login] [[-File] <filePath> [args]]
                  [-Command { - | <script-block> [-args <arg-array>]
                                | <string> [<CommandParameters>] } ]
(.. other help from pwsh ..)

It meant if you want to run some command you must write -Command { ... } in arguments.

But you can write more short command for run pwsh like this:

Start-Process pwsh.exe '-c', {
    'Hello World.'
    Read-Host
}
  1. -c is shorter equivalent for -Command
  2. Script block will converted to valid string in arguments

Upvotes: 6

Related Questions