Powershell seems to tie select cmdlets to the default output stream, and not release it after a command finishes, affecting future command in unexpected ways. It is not consistent in how it does this, which makes generating predictable output impossible without explicitly directing output when writing the script.
This weirdness happens if you put the commands on separate lines, mix in different object generation cmdlets, etc. It doesn't happen if you run the commands on separate lines interactively, and it doesn't happen with objects automatially created on the command line, unless you mix in objects not automatically created on the command line.
I give command line interactive examples, but it happens if you put these commands into a script with each command on a spearate line and then run the script.
PS /home/dennis> get-date|select dayofweek ; get-date
DayOfWeek
---------
Monday
Monday
PS /home/dennis> "string1"|select length ; "string2"
Length
------
7
string2
And for fun, check out this one:
S /home/dennis> "string0" ;"string1"|select length ; get-host ;"string2" ;get-date; 567 ; get-host
string0
Length
------
7
1
string2
1
567
1
PS /home/dennis> cat test.ps1
"string0"
"string1"|select length
get-host
"string2"
get-date
567
(1..5)
get-host
PS /home/dennis> ./test.ps1
string0
Length
------
7
1
string2
1
567
1
2
3
4
5
1
...
This also affects objects which are not of the same type, and in fact, it affects objects which do not even have the properties in the select statement. Delaying is not an option, and explictly forcing the output with out-host or write-host will directly write to the powershell output device, making it useless to create a script that will be used to produce objects in a pipeline. It also messes up variables. Observe:
PS /home/dennis> $d = get-date | select dayofweek ; $e = get-date ; $d ; $e
DayOfWeek
---------
Monday
Monday
PS /home/dennis> $d
DayOfWeek
---------
Monday
PS /home/dennis> $e
Monday, August 5, 2019 12:33:47 PM
For those who are thinking, it is only a display issue, and the script can be written to display it correctly, I say again, this makes scripts useless as tools you can reuse in other scripts. Observe how a pipeline inside a script affects commands in an independent interactive shell.
PS /home/dennis> cat test.ps1
"string0"
"string1"|select length
get-host
"string2"
get-date
567
get-host
PS /home/dennis> ./test.ps1|% {$_}
string0
Length
------
7
1
string2
1
567
1
PS /home/dennis> ./test.ps1|% {write-host $_}
string0
@{Length=7}
System.Management.Automation.Internal.Host.InternalHost
string2
8/5/19 12:50:54 PM
567
System.Management.Automation.Internal.Host.InternalHost
PS /home/dennis> ./test.ps1|% {$_|out-host}
string0
Length
------
7
Name : ConsoleHost
Version : 6.2.2
InstanceId : 4e46c643-1a9d-4c55-9151-b311f287a9cb
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
string2
Monday, August 5, 2019 1:20:24 PM
567
Name : ConsoleHost
Version : 6.2.2
InstanceId : 4e46c643-1a9d-4c55-9151-b311f287a9cb
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
In any shell script I expect that a command will execute independently of the previous command. WhatTheFortran is the logic behind this behaviour? What is the official recommendation to avoid this unpredictability?