Reputation: 31
I want to run multiple Powershell commands sequentially in their own Powershell windows and do not want those windows to be closed after running.
Example:
Start-Process powershell {Write-Host "hello"}; Start-Process powershell
{Write-Host "hello"}; Start-Process powershell {Write-Host "hello"}
Powershell windows get closed right after running. I want them to remain open.
Edit: Multiple commands are not always same and they may vary in number.
Upvotes: 2
Views: 3231
Reputation: 437082
# Asynchronously starts 3 new PowerShell windows that
# print "hello #<n>" to the console and stay open.
1..3 | ForEach-Object {
Start-Process powershell -Args '-noexit', '-command', "Write-Host 'hello #$_'"
}
-noexit
is required to keep a PowerShell session open after executing a command with -command
(run powershell.exe -?
to see all CLI parameters)
Note how the arguments are specified individually, as ,
-separated elements of an array that is passed to
-Args
(short for -ArgumentList
, though the parameter name can be omitted altogether in this case).
Note how the Write-Host
command is passed as a string - script blocks aren't supported as such in this scenario; you can pass one, as you tried, but it will be quietly converted to a string, which simply means that its literal content is used (everything between {
and }
).
In other words: passing {Write-Host "hello"}
is the same as 'Write-Host "hello"'
, but to avoid confusion you should pass a string.
You can only pass a script block as such if you invoke powershell.exe
directly, not via Start-Process
; you need Start-Process
, however, to run the new session in a new window and to start it asynchronously.
Also, the string was changed to a double-quoted string ("..."
) with embedded single-quoting ('...'
) to ensure that the reference to $_
- the automatic variable representing the pipeline object at hand (1
, 2
, or 3
) - is expanded (interpolated).
Using the pipeline (|
) with an array of inputs (1..3
, which evaluates to array 1, 2, 3
) with the ForEach-Object
cmdlet is just an example - you can still invoke the individual commands individually, one after the other, on individual lines, or separated with ;
- thanks to Start-Process
they'll still launch asynchronously.
However, if the individual commands share logic, the pipeline approach can simplify matters; you can put the shared logic in the body of the ForEach-Object
call and pass the variable parts as input via the pipeline.
Upvotes: 3
Reputation: 647
Put a read-host at the end of the command sequence - it will wait for you to input something before continuing execution (and presumably exiting?). To copy/paste the example in this link, you could anything like this which will pause execution until you enter something: $Age = Read-Host "Please enter your age"
-> Ref: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/read-host?view=powershell-6
Upvotes: 0