In some cases, if I try to pause or sleep after a Select-Object
command, the pause/sleep occurs before the command.
For example, with
Get-NetAdapter | Select-Object Name,Status
Pause
or
Get-NetAdapter | Select-Object Name,Status | Where-Object {$_ -ne $null}
Pause
the output is:
Press Enter to continue...: Name Status ---- ------ Wi-Fi Up Ethernet Disconnected
Whereas with
Get-NetAdapter | Select-Object Name,Status | Format-Table
Pause
the output is:
Name Status ---- ------ Wi-Fi Up Ethernet Disconnected Press Enter to continue...:
What's going on here? Is this a bug or a feature?
Format-Table
has nothing to do with that I just try the following in PowerSell V 4.0 and PowerShel V5.0 and the problem can be reproduced :a turn arround is :
Here again pause is run first :
But not here
For me, in PowerShell V5.0 everything works like if the host is not needed in instructions that are pipelined then these instructions are run asynchronosly.
I would have like that people as @Keith Hill have a look to this behavior.
What you see is a consequences of new PowerShell v5 feature.
Format-Table
now collect input for 300 milliseconds to find better column width. It work this way even if you explicitly specify-AutoSize:$false
.When you type command in command prompt, that command implicitly piped to single instance of
Out-Default
command. TheOut-Default
command then decide how to format objects and print them on PowerShell host (console). So that, even if you does not useFormat-Table
directly in your code, that does not mean that you does not haveFormat-Table
in your pipeline.Out-Default
can decide to format objects as table and useFormat-Table
internally.Custom objects with four or less properties and without custom formatting defined for them in format files are formatted as table. By using
Select-Object
with two properties you produce exactly that objects.PowerShell pipeline is single-threaded. That means that
Format-Table
can not just output all collected objects when 300 milliseconds interval elapsed.Format-Table
have to wait till you pipe next item to it (process block invoked) or end of pipeline reported (end block invoked).Implicit
Format-Table
does not print anything (strictly saying it print empty line) before firstPause
because it still waiting for more input objects (300 milliseconds not yet elapsed) to decide on column width. When first object (#1) come after 300 milliseconds interval (assuming that you are not to fast on pressing Enter), thenFormat-Table
decide on column width and print all collected objects. Any further objects will be printed without delay, but them can not affect column width anymore. If value is to big for column it will be truncated.With this code, end block of explicit
Format-Table
will be executed beforePause
. In end blockFormat-Table
know that it already got all the input, so it can decide on column width and output all collected objects right away. ImplicitOut-Default
see that formatting objects fromFormat-Table
output, andOut-Default
know that them does not need any addition formatting and print them on host (console) right away as well. So whole table got printed beforePause
invoked.Notice the difference in placement of end of table mark (two empty lines). In first example it placed after last
Pause
. It is because implicitFormat-Table
still active and still wait, that you pass additional object to it. Only when your command fully completedFormat-Table
acknowledge end of input and output end of table mark. In second example, explicitFormat-Table
completes beforePause
, so whole table (including end of table mark) got printed beforePause
command.The difference in placement of end of table mark can be noticed it previous versions of PowerShell as well.