hello
if i add out-default in middle of this expression it return enexpected result but if i add switch "-transcript" it return the exact result why ? i dont understand the use of this switch
PS C:\> Get-Process -Id $PID
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
57 27.50 62.77 6.11 368 6 pwsh
PS C:\> Get-Process -Id $PID | Select-Object name,id
Name Id
---- --
pwsh 368
PS C:\> Get-Process -Id $PID | out-default | Select-Object name,id
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
58 27.82 63.92 6.64 368 6 pwsh
PS C:\> Get-Process -Id $PID | out-default -Transcript | Select-Object name,id
Name Id
---- --
pwsh 368
> $PSVersionTable
Name Value
---- -----
PSVersion 6.1.0
PSEdition Core
GitCommitId 6.1.0
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
thanks
Inserting just Out-Default sends all pipeline input directly to the console, ignoring the remaining pipeline segments - which is expected behavior.
-Transcript is currently undocumented, but, from what I gather, its purpose is to send output _just_ to a transcript (previously started with Start-Transcript), and not also to the host (console/terminal).
The surprising aspect is that it still _passes the objects through_, unlike without -Transcript, but whether the final pipeline segment still produces host output seemingly depends on whether a _cmdlet_ (yes) or a _script block_ (no) tries to produce output.
For instance, the following does _not_ produce output, due to using a script block in the final segment:
# No output.
Get-Process -Id $PID | out-default -Transcript | ForEach-Object { $_.Name }
Note that the script block still _receives_ the input object, but it cannot produce output, neither implicitly nor with Write-Output - you can, however, write to a _different_ stream; e.g.:
# DOES write to the verbose stream.
Get-Process -Id $PID | out-default -Transcript | ForEach-Object { Write-Verbose -vb $_.Name }
My sense is that both behaviors are ultimately the manifestation of a _bug_, because, arguably, Out-Default -Transcript should behave like Out-Default alone and _not_ pass anything on through the pipeline.
thanks for your comments
here another cases:
PS C:\> # why run fast and no output ?
PS C:\> 1..1gb | Out-Default -Transcript | select -First 5
ps C:\> no scriptblock but no output
PS C:\> Get-Process -Id $PID | Out-Default -Transcript | ForEach-Object -MemberName name
-transcript emit output to pipeline if it use with transcription but still remain mysterious cases
rm "$env:temp\transcript.log" -ea 0
$null = Start-Transcript -Path "$env:temp\transcript.log"
1 | Out-Default
2
$null = Stop-Transcript
# in console
2
gc "$env:temp\transcript.log"
# in file
1
2
rm "$env:temp\transcript.log" -ea 0
$null = Start-Transcript -Path "$env:temp\transcript.log"
1 | Out-Default -Transcript
2
$null = Stop-Transcript
# in console
2
gc "$env:temp\transcript.log"
# in file
1
1
2
rm "$env:temp\transcript.log" -ea 0
$null = Start-Transcript -Path "$env:temp\transcript.log"
1..10 | Out-Default -transcript | select -First 5
2
$null = Stop-Transcript
# in console
2
gc "$env:temp\transcript.log"
# in file
1
1
2
2
3
3
4
4
5
2
rm "$env:temp\transcript.log" -ea 0
$null = Start-Transcript -Path "$env:temp\transcript.log"
Get-Process -Id $PID | out-default -Transcript | ForEach-Object { $_.Name }
2
$null = Stop-Transcript
# in console
2
gc "$env:temp\transcript.log"
# in file
pwsh
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
58 28.04 63.11 6.02 2280 1 pwsh
2
i dont see the importance of this switch
@iSazonov given the intended behaviour of Out-Default (output to console, not pipeline) I would be more inclined to think that the fact that adding the -Transcript switch changing that completely is most likely a bug -- unless you or one of the microsoft folks here can speak to what the -Transcript switch is supposed to do (given that it's undocumented).
I peeked at the source code and found this:
While I don't have the full picture, I infer the following:
The switch is used _internally_ , in the context of using the PowerShell SDK (API), and may never have been meant to be used from PowerShell code.
Passing the objects through is intentional.
Sticking an Out-Default in the _middle_ of a pipeline - with or without -Transcript - doesn't make much sense in general, given that Out-* cmdlets are usual the _final_ pipeline stage.
Given that, I wonder if the inconsistency we've observed - with -Transcript present, (at least some) cmdlets still producing output while script blocks aren't - is worth fixing at all.
However, there _is_ a _potentially_ useful application for Out-Default -Transcript (as the last pipeline segment) which I've alluded to before, and it's something that @PetSerAl had pointed out to me:
With a transcript ongoing, you can selectively suppress _console_ output for a given command while still sending the output to the _transcript_.
Given the comments in the source code, this is likely an unintentional feature, however, and, in fact, it is currently _buggy_:
Start-Transcript t.txt
'foo' # outputs to console *and* to the transcript
'bar' | Out-Default -Transcript # outputs to the transcript *only*
Stop-Transcript
In the console, you'll see:
Transcript started, output file is t.txt
foo # Note how only 'foo' was printed to the console, not 'bar'
Transcript stopped, output file is /path/to/t.txt
In the transcript you'll see:
**********************
PowerShell transcript start
Start time: 20181016235404
# ....
**********************
Transcript started, output file is t.txt
foo
bar
bar # !! bug - 'bar' was written *twice*
**********************
PowerShell transcript end
End time: 20181016235404
**********************
It's conceivable that users who have discovered the to-transcript-only behavior are relying on it (the bug notwithstanding), so it's probably worth fixing the bug (and, who knows, perhaps that will implicitly also fix the inconsistent middle-of-the-pipeline behavior).
given that Out-* cmdlets are usual the final pipeline stage.
In middle of pipeline I believe we should use Out-String.
Most helpful comment
@iSazonov given the intended behaviour of Out-Default (output to console, not pipeline) I would be more inclined to think that the fact that adding the -Transcript switch changing that completely is most likely a bug -- unless you or one of the microsoft folks here can speak to what the -Transcript switch is supposed to do (given that it's undocumented).