Skip to content

Inconsistent Start-Transcript behavior with respect to the error and information streams #4645

@mklement0

Description

@mklement0

I'm making the following assumptions about how Start-Transcript is designed to work (can't tell from the documentation):

  • Whatever streams are neither captured nor redirected are transcribed, and preference variables with respect to which Write-* cmdlets should actually produce output are honored; another way of putting it: Whatever output displays in the console, across all streams, is also what should get transcribed.

Currently, Start-Transcript doesn't always work that way:

  • Even with *>$null applied to a script that uses Start-Transcript, which should keep all streams out of the transcript, errors (stream 2) and Write-Host output (stream 6) are still transcribed.

    • You can partially keep error output out of the transcript If you use $ErrorActionPreference = 'SilentlyContinue': outside of a transcript that would silence all errors (non-terminating, statement-terminating, script-terminating - albeit the latter two against documented behavior), but in a transcript cmdlet-triggered statement-terminating errors are unexpectedly still transcribed.

    • Errors that do get transcribed are transcribed twice by default.

    • Cmdlet-triggered statement-terminating errors are preceded by an extra line repeating the error message, with a prefix such as >>TerminatingError(<command>): <message>
      It is this line that shows in the transcript even with $ErrorActionPreference = 'SilentlyContinue' in effect.

    • Unlike outside of a transcript, with $ErrorActionPreference at its default, $Continue:

      • a cmdlet-triggered statement-terminating error acts like a script-terminating one.
      • a script-terminating error prints neither to the console nor records the error in the transcript.
      • the transcript is aborted in both cases, however.
  • Even though Write-Information output (stream 6) is by default not printed to the console $InformationAction is 'SilentlyContinue' by default), it is still transcribed. [Update: This appears to have been fixed, but I don't know where and when (the problem persists in Windows PowerShell)]

Steps to reproduce

Create script t.ps1 with the following content:

$null = Start-Transcript t.log

write-warning 'warn'
write-verbose 'verbose'

write-information 'info'
write-host 'host'

write-output 'data'

# Generate a non-terminating error
Write-Error 'error'

# Generate an expression-based statement-terminating error.
1/0

# Generate a cmdlet-based statement-terminating error.
Get-Item -NoSuchParam

$null = Stop-Transcript

Then run the following commands, one after the other:

A)

./t.ps1

B)

./t.ps1 *>$null

C)

& { $ErrorActionPreference = 'SilentlyContinue'; ./t.ps1 }

Expected behavior

Inspect output file t.log:

A)
Coloring aside, whatever printed to the console should appear in the transcript (sandwiched between a header and a footer).

B)
Except for the header and footer, the transcript should be empty (all streams were suppressed).

C)
No errors of any kind should be transcribed.

Actual behavior

A)

  • INFO: info shows in the transcript, even though it doesn't show in the console (with $InformationPreference at its default value, SilentlyContinue).
    As an aside: Non-suppressed Write-Information output in the console has no INFO: prefix , but does in the transcript (whereas Write-Warning, Write-Verbose and Write-Debug print a prefix in both scenarios).

[Update: This appears to have been fixed, but I don't know where and when (the problem persists in Windows PowerShell)]

  • All errors show twice in the transcript.
    • The first instance of the cmdlet-triggered statement-terminating error is preceded by an extra line duplicating the regular error representation:
      >> TerminatingError(Get-Item): "A parameter cannot be found that matches parameter name 'NoSuchParam'."

B)

  • host (Write-Host output) still shows in the transcript.

  • All errors still show in the transcript (now only once).

C)

While the non-terminating error and the expression-triggered error were successfully suppressed, the cmdlet-triggered terminating error still shows in the transcript, but only by the extra line:
PS>TerminatingError(Get-Item): "A parameter cannot be found that matches parameter name 'NoSuchParam'."

Environment data

PowerShell Core v6.0.0-beta.5 on macOS 10.12.6
PowerShell Core v6.0.0-beta.5 on Ubuntu 16.04.3 LTS
PowerShell Core v6.0.0-beta.5 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.483 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Cmdlets-Corecmdlets in the Microsoft.PowerShell.Core module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions