Is it possible to stop `powershell` wrapping output in ANSI sequences?

Viewed 1073

I CreateProcess(win32) powershell and read raw bytes from it. And I see that it produces a lot of invisible chars. For example \u{1b}[2J\u{1b}[m\u{1b}[

Is there any way how to stop it?

*Exactly it's possible to strip them manually but I do hope there other way.

2 Answers
  • You mention powershell (powershell.exe), i.e. the CLI of Windows PowerShell.

  • Windows PowerShell (unlike PowerShell (Core) 7+, see below) itself does not use coloring / formatting based on VT / ANSI escape sequences.

  • The implication is that third-party code is producing the VT sequences in your case, so you must deactivate (or reconfigure) it to avoid such sequences in the output.

    • A prime candidate is a custom prompt function; such functions often involve coloring for a better command-line experience.

    • In programmatic use of powershell.exe, however, you would only see what the prompt function prints if you feed PowerShell commands to the CLI's stdin, accompanied by passing argument -File - to the CLI (to instruct it to read commands from stdin) or by default.

    • To exclude the prompt-function output from the output altogether, use -Command -, as discussed in the answer to your previous question.

    • If you do want it, but want to use the default prompt string, suppress $PROFILE loading with the -NoProfile parameter, which is generally preferable in programmatic processing.


Controlling use of colored output (VT / ANSI escape sequences) in PowerShell (Core) 7.2+

In PowerShell (Core) 7+ (pwsh.exe) - but not in Windows PowerShell (powershell.exe) - PowerShell itself situationally uses VT (ANSI) escape sequence to produce formatted/colored output, such as in the output of Select-String and, in v7.2+, in formatted output in general (column headers in tabular output / property names in list output).

  • In PowerShell 7.2+ you can categorically suppress these as follows:

    • Note: Categorically disabling VT (ANSI) sequences is generally not necessary, because PowerShell automatically suppresses them when output is not sent to the host (display); that is, $PSStyle.OutputRendering defaults to Host[1].

      • This amounts to the same behavior that may Unix utilities (sensibly) exhibit: coloring is by default only applied when printing to the display (terminal), not when piping to another command or redirecting to a file.
    • From outside PowerShell, before launching it:

      • By defining the NO_COLOR environment variable, with any value, such as 1.

        • This causes PowerShell to set $PSStyle.OutputRendering to PlainText on startup, which instructs PowerShell not to use VT / ANSI escape sequences.

        • A growing number of external programs also respect this env. variable - see no-color.org

      • Alternatively, by setting the TERM environment variable to xtermm / xterm-mono:

        • Note that value dumb, at least as of PowerShell Core 7.2.0-preview.9 (the most recent version as of this writing), doesn't work: while it does cause $host.UI.SupportsVirtualTerminal to then reflect $false, as documented, $PSStyle.OutputRendering remains at its default, Host, and actual formatted output (such as from Get-Item /) still uses colors.
        • However, setting TERM may be more effective than NO_COLOR in getting external programs not to emit VT sequences - ultimately, there's no guarantee however.
        • That said, modifying TERM, especially setting it to value dumb, is best avoided in general, because external programs (on Unix-like platforms) may rely on the TERM variable for inferring (also non-color-related) capabilities of the hosting terminal application (which setting the variable to dumb takes away altogether and - at least hypothetically - value xtermm / xterm-mono may misrepresent the true fundamental terminal type).
    • From inside PowerShell:

      • With $PSStyle.OutputRendering = 'PlainText'
        • Note that this alone - unlike the environment variables discussed above - does not affect the behavior of external programs.

Note that third-party PowerShell code that uses VT sequences, especially if it predates PowerShell (Core) 7+, may not respect any of the standard mechanisms described above for disabling them (though may conceivably offer a custom mechanism).


[1] This applies since v7.2.0-preview.9, where Host was made the default and the previous default, Automatic, was removed altogether.

Related