Jordan
Jordan

Reputation: 25

Why is the "Read-host" section running before the code?

I just wanted a .ps1 file that will run a simple line of powershell but not close instantly.

Ive tried to do "read-host -prompt " " " but it is displaying before the code is run and then still closes instantly

get-appxpackage -allusers | select name 

read-host -prompt "Press enter to exit"

I expect the outcome to be I run the file and then get a chance to read the output within the powershell window before pressing something to exit. But the actual output is prompts to exit before the code is run and then it runs through the output and closes

Upvotes: 1

Views: 1999

Answers (2)

postanote
postanote

Reputation: 16116

Tagging on to what the Lee and Moerwald have said.

Another way to stream real-time is using ForEach or ForEach-Object, it's also a bit more performant than the Out-Host approach, because of the not defaulting to writing to the screen. If that latter performance v screen write is important to you. If you don't want the screen output of Out-Host, send it to Null.

# Using Out-Host

Measure-Command {
    get-appxpackage -allusers | 
    select name | Out-Host
}



Name                                             
----                                             
1527c705-...            
...           
InputApp                                         
Microsoft.AAD.BrokerPlugin                       
Microsoft.AccountsControl                        
...                            


# Results

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
*** Milliseconds      : 643 ***
Ticks             : 6431627
TotalDays         : 7.44401273148148E-06
TotalHours        : 0.000178656305555556
TotalMinutes      : 0.0107193783333333
TotalSeconds      : 0.6431627
TotalMilliseconds : 643.1627



# User ForEach in a script Block

Measure-Command {
    & { foreach ($item in get-appxpackage -allusers | select name)
    { "processing $item"}}
}


# Results

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
*** Milliseconds      : 385 ***
Ticks             : 3858318
TotalDays         : 4.46564583333333E-06
TotalHours        : 0.0001071755
TotalMinutes      : 0.00643053
TotalSeconds      : 0.3858318
TotalMilliseconds : 385.8318



# Standard ForEach-Object

Measure-Command {
    get-appxpackage -allusers | 
    ForEach-Object {select name}
}


# Results

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
*** Milliseconds      : 498 ***
Ticks             : 4988494
TotalDays         : 5.77371990740741E-06
TotalHours        : 0.000138569277777778
TotalMinutes      : 0.00831415666666667
TotalSeconds      : 0.4988494
TotalMilliseconds : 498.8494

Upvotes: 0

Moerwald
Moerwald

Reputation: 11304

After executing this line of code:

get-appxpackage -allusers | select name 

You'll have some "pending" objects ready to return to the Powershell pipelines output stream. The objects can't be sent to the pipeline until Read-Host has finished (since Powershell will treat these objects as "output" of your ps1 file). After Read-Host has finished the objects are sent to the pipeline (via the output stream). Since there is no other cmdlet there (using the output of you ps1 file), Powershells default behavior is to output the pipeline content to the Powershell host.

As @Lee_Daily already mentioned in above comment, adding Out-Host will send the output of get-appxpackage -allusers | select name to the Powershell host. So get-appxpackage -allusers | select name | out-host no objects are queued in the output stream for further pipeline actions.

I would recommend you check following sources:

These are essential Powershell concepts you've to understand.

Hope that helps.

Upvotes: 3

Related Questions