Multiple foreground colors in PowerShell in one command

PowershellColors

Powershell Problem Overview


I want to output many different foreground colors with one statement.

PS C:\> Write-Host "Red" -ForegroundColor Red
Red

This output is red.

PS C:\> Write-Host "Blue" -ForegroundColor Blue
Blue

This output is blue.

PS C:\> Write-Host "Red", "Blue" -ForegroundColor Red, Blue
Red Blue

This output is magenta, but I want the color to be red for the word red, and blue for the word blue via the one command. How can I do that?

Powershell Solutions


Solution 1 - Powershell

You could roll your own Write-Color command or something that looks for inline tokens that change the color. This is how ANSI escape sequences used to work back in the BBS days.

But you could achieve what you want by doing:

Write-Host "Red " -f red -nonewline; Write-Host "Blue " -f blue;

Here's a simple little function that does what you asked.

function Write-Color([String[]]$Text, [ConsoleColor[]]$Color) {
    for ($i = 0; $i -lt $Text.Length; $i++) {
        Write-Host $Text[$i] -Foreground $Color[$i] -NoNewLine
    }
    Write-Host
}

Write-Color -Text Red,White,Blue -Color Red,White,Blue

Solution 2 - Powershell

Edit (7th May 2018): I've updated Write-Color to 0.5 and published it as module. Also code is now published on github.

Changes in 0.5:

  • added backgroundcolor
  • added aliases T/B/C to shorter code
  • added alias to function (can be used with “WC”)
  • fixes to module publishing

Changes in 0.4

  • fixed small issues
  • published as module

Links to resources:

Thanks to published module you can easily use the code as below:

Install-Module PSWriteColor
Write-Color -Text "Some","Text" -Color Yellow,Red

There is no more need to copy/paste code. Enjoy.

Old code is below. It's highly advised to use links above for newest code:

Edit (9th April 2018): I've updated Write-Color to v0.3. Feel free to get it at my site where I'm maintaining Write-Color. There are few small changes. Inluded -NoNewLine and -ShowTime option.

Edit (Jun 2017): updated with new version, added logging to file for logging purposes

Josh method was so great that I actually went and expanded it a bit for my needs. I've written blog post How to format PowerShell with Multiple Colors about it (with screenshots and all - for the whole story and usage).

    function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = "White", [int]$StartTab = 0, [int] $LinesBefore = 0,[int] $LinesAfter = 0, [string] $LogFile = "", $TimeFormat = "yyyy-MM-dd HH:mm:ss") {
    # version 0.2
    # - added logging to file
    # version 0.1
    # - first draft
    # 
    # Notes:
    # - TimeFormat https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
 
    $DefaultColor = $Color[0]
    if ($LinesBefore -ne 0) {  for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host "`n" -NoNewline } } # Add empty line before
    if ($StartTab -ne 0) {  for ($i = 0; $i -lt $StartTab; $i++) { Write-Host "`t" -NoNewLine } }  # Add TABS before text
    if ($Color.Count -ge $Text.Count) {
        for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine } 
    } else {
        for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
        for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -NoNewLine }
    }
    Write-Host
    if ($LinesAfter -ne 0) {  for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host "`n" } }  # Add empty line after
    if ($LogFile -ne "") {
        $TextToFile = ""
        for ($i = 0; $i -lt $Text.Length; $i++) {
            $TextToFile += $Text[$i]
        }
        Write-Output "[$([datetime]::Now.ToString($TimeFormat))]$TextToFile" | Out-File $LogFile -Encoding unicode -Append
    }
}


Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow
 
Write-Color -Text "This is text in Green ",
                   "followed by red ",
                   "and then we have Magenta... ",
                   "isn't it fun? ",
                   "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan
 
Write-Color -Text "This is text in Green ",
                   "followed by red ",
                   "and then we have Magenta... ",
                   "isn't it fun? ",
                   "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1
 
Write-Color "1. ", "Option 1" -Color Yellow, Green
Write-Color "2. ", "Option 2" -Color Yellow, Green
Write-Color "3. ", "Option 3" -Color Yellow, Green
Write-Color "4. ", "Option 4" -Color Yellow, Green
Write-Color "9. ", "Press 9 to exit" -Color Yellow, Gray -LinesBefore 1



Write-Color -LinesBefore 2 -Text "This little ","message is ", "written to log ", "file as well." -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" -TimeFormat "yyyy-MM-dd HH:mm:ss"
Write-Color -Text "This can get ","handy if ", "want to display things, and log actions to file ", "at the same time." -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt"

How to format PowerShell with Multiple Colors

It actually brings additional checks and features over Josh script.

Solution 3 - Powershell

This function provides different syntactic sugar:

function color-Write
{
    # DO NOT SPECIFY param(...)
    #    we parse colors ourselves.

    $allColors = ("-Black",   "-DarkBlue","-DarkGreen","-DarkCyan","-DarkRed","-DarkMagenta","-DarkYellow","-Gray",
                  "-Darkgray","-Blue",    "-Green",    "-Cyan",    "-Red",    "-Magenta",    "-Yellow",    "-White")
    $foreground = (Get-Host).UI.RawUI.ForegroundColor # current foreground
    $color = $foreground
    [bool]$nonewline = $false
    $sofar = ""
    $total = ""

    foreach($arg in $args)
    {
        if ($arg -eq "-nonewline") { $nonewline = $true }
        elseif ($arg -eq "-foreground")
        {
            if ($sofar) { Write-Host $sofar -foreground $color -nonewline }
            $color = $foregrnd
            $sofar = ""
        }
        elseif ($allColors -contains $arg)
        {
            if ($sofar) { Write-Host $sofar -foreground $color -nonewline }
            $color = $arg.substring(1)
            $sofar = ""
        }
        else
        {
            $sofar += "$arg "
            $total += "$arg "
        }
    }
    # last bit done special
    if (!$nonewline)
    {
        Write-Host $sofar -foreground $color
    }
    elseif($sofar)
    {
        Write-Host $sofar -foreground $color -nonewline
    }
}

Examples:

color-Write This is normal text
color-Write Normal -Red Red -White White -Blue Blue -ForeGround Normal

Solution 4 - Powershell

I found a much easier option at https://blogs.technet.microsoft.com/heyscriptingguy/2011/05/17/writing-output-with-powershell/

Basically, the first write-host includes the option -NoNewLine. This prevents the new line from forming. The next write-host will be added immediately after the previous text. And each of the separate write-host can have -foregroundcolor options. That can be repeated for each color change you need.

Example with one line of text with three colors:

write-host "Your text here " -ForeGroundColor Red -NoNewLine
write-host "some other text here " -ForeGroundColor Yellow -NoNewLine
write-host "And the last text here."

Notice that there is a space after the text in the first and second write-host. PowerShell is not concatenating or combining the text, it is simply not moving the cursor to the next line.

Solution 5 - Powershell

Here is small a function I wrote to output colored text (it is actually smaller, but I rewrote it to be more understandable):

function Write-Color() {
    Param (
        [string] $text = $(Write-Error "You must specify some text"),
        [switch] $NoNewLine = $false
    )

    $startColor = $host.UI.RawUI.ForegroundColor;

    $text.Split( [char]"{", [char]"}" ) | ForEach-Object { $i = 0; } {
        if ($i % 2 -eq 0) {
            Write-Host $_ -NoNewline;
        } else {
            if ($_ -in [enum]::GetNames("ConsoleColor")) {
                $host.UI.RawUI.ForegroundColor = ($_ -as [System.ConsoleColor]);
            }
        }

        $i++;
    }

    if (!$NoNewLine) {
        Write-Host;
    }
    $host.UI.RawUI.ForegroundColor = $startColor;
}

It's quite simple to use: just use Write-Color "your text" and add some color name between curly brackets where you want the text to be colored.

Examples:

`Write-Color "Hello, {red}my dear {green}friend !"` will output

Script screenshot

You can put it in your $profile file to use it in a simple PowerShell prompt, or just add it to some scripts.

Solution 6 - Powershell

Find advanced function Write-HostColored below, which allows embedding coloring instructions in a string, both for the foreground and the background color:

Write-HostColored "I'm #green#green#, I'm #red#red#, and I'm #blue:white#blue on white#."

The above yields:

sample output

In addition to accepting a default foreground and background color with -ForegroundColor and -BackgroundColor, you can embed one or more color specifications in the string to write, using the following syntax:

#<fgcolor>[:<bgcolor>]#<text>#

<fgcolor> and <bgcolor> must be valid [ConsoleColor] values, such as green or white (case does not matter). Everything following the color specification up to the next #, or implicitly up to the end of the string, is written in that color.


Write-HostColored source code (PSv2+):
<#
.SYNOPSIS
A wrapper around Write-Host that supports selective coloring of
substrings via embedded coloring specifications.

.DESCRIPTION
In addition to accepting a default foreground and background color,
you can embed one or more color specifications in the string to write,
using the following syntax:
#<fgcolor>[:<bgcolor>]#<text>#

<fgcolor> and <bgcolor> must be valid [ConsoleColor] values, such as 'green' or 'white' (case does not matter).
Everything following the color specification up to the next '#', or impliclitly to the end of the string,
is written in that color.

Note that nesting of color specifications is not supported.
As a corollary, any token that immediately follows a color specification is treated
as text to write, even if it happens to be a technically valid color spec too.
This allows you to use, e.g., 'The next word is #green#green#.', without fear
of having the second '#green' be interpreted as a color specification as well.

.PARAMETER ForegroundColor
Specifies the default text color for all text portions
for which no embedded foreground color is specified.

.PARAMETER BackgroundColor
Specifies the default background color for all text portions
for which no embedded background color is specified.

.PARAMETER NoNewline
Output the specified string withpout a trailing newline.

.NOTES
While this function is convenient, it will be slow with many embedded colors, because,
behind the scenes, Write-Host must be called for every colored span.

.EXAMPLE
Write-HostColored "#green#Green foreground.# Default colors. #blue:white#Blue on white."

.EXAMPLE
'#black#Black on white (by default).#Blue# Blue on white.' | Write-HostColored -BackgroundColor White

#>
function Write-HostColored() {
    [CmdletBinding()]
    param(
        [parameter(Position=0, ValueFromPipeline=$true)]
        [string[]] $Text
        ,
        [switch] $NoNewline
        ,
        [ConsoleColor] $BackgroundColor = $host.UI.RawUI.BackgroundColor
        ,
        [ConsoleColor] $ForegroundColor = $host.UI.RawUI.ForegroundColor
    )

    begin {
        # If text was given as a parameter value, it'll be an array.
        # Like Write-Host, we flatten the array into a single string
        # using simple string interpolation (which defaults to separating elements with a space,
        # which can be changed by setting $OFS).
        if ($Text -ne $null) {
            $Text = "$Text"
        }
    }

    process {
        if ($Text) {

            # Start with the foreground and background color specified via
            # -ForegroundColor / -BackgroundColor, or the current defaults.
            $curFgColor = $ForegroundColor
            $curBgColor = $BackgroundColor

            # Split message into tokens by '#'.
            # A token between to '#' instances is either the name of a color or text to write (in the color set by the previous token).
            $tokens = $Text.split("#")

            # Iterate over tokens.
            $prevWasColorSpec = $false
            foreach($token in $tokens) {

                if (-not $prevWasColorSpec -and $token -match '^([a-z]*)(:([a-z]+))?$') { # a potential color spec.
                    # If a token is a color spec, set the color for the next token to write.
                    # Color spec can be a foreground color only (e.g., 'green'), or a foreground-background color pair (e.g., 'green:white'), or just a background color (e.g., ':white')
                    try {
                        $curFgColor = [ConsoleColor] $matches[1]
                        $prevWasColorSpec = $true
                    } catch {}
                    if ($matches[3]) {
                        try {
                            $curBgColor = [ConsoleColor] $matches[3]
                            $prevWasColorSpec = $true
                        } catch {}
                    }
                    if ($prevWasColorSpec) {
                        continue
                    }
                }

                $prevWasColorSpec = $false

                if ($token) {
                    # A text token: write with (with no trailing line break).
                    # !! In the ISE - as opposed to a regular PowerShell console window,
                    # !! $host.UI.RawUI.ForegroundColor and $host.UI.RawUI.ForegroundColor inexcplicably
                    # !! report value -1, which causes an error when passed to Write-Host.
                    # !! Thus, we only specify the -ForegroundColor and -BackgroundColor parameters
                    # !! for values other than -1.
                    # !! Similarly, PowerShell Core terminal windows on *Unix* report -1 too.
                    $argsHash = @{}
                    if ([int] $curFgColor -ne -1) { $argsHash += @{ 'ForegroundColor' = $curFgColor } }
                    if ([int] $curBgColor -ne -1) { $argsHash += @{ 'BackgroundColor' = $curBgColor } }
                    Write-Host -NoNewline @argsHash $token
                }

                # Revert to default colors.
                $curFgColor = $ForegroundColor
                $curBgColor = $BackgroundColor

            }
        }
        # Terminate with a newline, unless suppressed
        if (-not $NoNewLine) { write-host }
    }
}

Solution 7 - Powershell

This works too...

Write-Host "Don't forget to " -ForegroundColor Yellow -NoNewline; Write-Host "CALL YOUR MOM " -ForegroundColor Red -NoNewline; Write-Host "every day!" -ForegroundColor Yellow

Solution 8 - Powershell

This code is available with a different number of arguments: Text, ForeGroundColor, and BackGroundColor.

Each colorlist is used with a rotate implementation:

function Write-Color([String[]]$Text, [ConsoleColor[]]$ForeGroundColor, [ConsoleColor[]]$BackGroundColor) {
    for ($i = 0; $i -lt $Text.Length; $i++) {
        $Color = @{}
        if ($ForeGroundColor -and $BackGroundColor){
            $Color = @{
                ForegroundColor = $ForeGroundColor[$i%($ForeGroundColor.count)]
                BackgroundColor = $BackGroundColor[$i%($BackGroundColor.count)]
            }
        } elseif ($ForeGroundColor) {
            $Color = @{
                ForegroundColor = $ForeGroundColor[$i%($ForeGroundColor.count)]
            }
        } elseif ($BackGroundColor) {
            $Color = @{
                BackgroundColor = $BackGroundColor[$i%($BackGroundColor.count)]
            }
        }
        Write-Host $Text[$i] @color -NoNewLine
    }
    Write-Host
}

Log usage:

Write-Color "Check color list...".PadRight(50), '[', '   OK   ', ']' -fore cyan, White, green, white
Write-Color "Red Check is good...".PadRight(50), '[' ,' ERROR! ', ']' -fore cyan, White, red, white
Write-Color "Write-Color is cool !".PadRight(50), '[', '  WARN  ', ']' -fore cyan, White, Yellow, white

Enter image description here

List Usage (just 2 backGroundColor and 4 foreGroundColor):

Write-Color (@(100..115) | %{" -> $_ : ".PadRight(30) + "`n"}) -ForeGroundColor cyan, yellow, magenta, red -BackGroundColor gray, black

Enter image description here

Standard Write-Host

Write-Host (@(100..115) | %{" -> $_ : ".PadRight(30) + "`n"}) -BackgroundColor gray

Enter image description here

Solution 9 - Powershell

Slight modification to this one... I took version 2, removed the logging (because I don't want it), and then added a Boolean parameter, similar to -NoNewLine for Write-Host. I was specifically trying to add the ability to change the colors and prompt for user input on the same line so that I could highlight the default answer if the user does not enter anything.

I realize this was available in Write-HostColored (in a previous answer)... but sometimes you just want simpler code...

function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = "White", [int]$StartTab = 0, [int] $LinesBefore = 0,[int] $LinesAfter = 0, [bool] $NewLine = $True) {

    # Notes:
    # - TimeFormat https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
    #
    # Example:  Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow -NewLine $False
    #
    $DefaultColor = $Color[0]
    if ($LinesBefore -ne 0) {
        for ($i = 0; $i -lt $LinesBefore; $i++) {
            Write-Host "`n" -NoNewline
        }
    } # Add empty line before

    if ($StartTab -ne 0) {
        for ($i = 0; $i -lt $StartTab; $i++) {
            Write-Host "`t" -NoNewLine
        }
    }  # Add TABS before text

    if ($Color.Count -ge $Text.Count) {
        for ($i = 0; $i -lt $Text.Length; $i++) {
            Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine
        }
    }
    else {
        for ($i = 0; $i -lt $Color.Length ; $i++) {
            Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine
        }
        for ($i = $Color.Length; $i -lt $Text.Length; $i++) {
            Write-Host $Text[$i] -ForegroundColor $DefaultColor -NoNewLine
        }
    }

    if ($NewLine -eq $False) {
        Write-Host -NoNewLine
    }
    else {
        Write-Host
    }

    if ($LinesAfter -ne 0) {
        for ($i = 0; $i -lt $LinesAfter; $i++) {
            Write-Host "`n"
        }
    }  # Add empty line after

}  # END FUNCTION Write-Color

Sample of what I was trying to accomplish:

Write-Color -Text "Is this correct? ","[y]","/n" -Color White, Magenta, White -NewLine $False ; Read-Host " "

Solution 10 - Powershell

So here's something I came up with. Hope it helps someone out.

$e = "$([char]27)"

enum ANSIFGColors {
  Black   = 30
  Red     = 91
  Green   = 92
  Yellow  = 93
  Blue    = 94
  Magenta = 95
  Cyan    = 96
  White   = 97
}

enum ANSIBGColors {
  Black   = 40
  Red     = 41
  Green   = 42
  Yellow  = 103
  Blue    = 44
  Magenta = 105
  Cyan    = 46
  White   = 107
}

function Colorize-Text {
  param (
    [string]$StringToColor,
    [ANSIFGColors]$TextColor,
    [ANSIBGColors]$BackgroundColor
  )
  
  $retValue = $null

  if ($BackgroundColor -ne $null ) { $retValue = [string]"$e[$($TextColor.value__);$($BackgroundColor.value__)m$StringToColor$e[0m" }
  else                             { $retValue = [string]"$e[$($TextColor.value__)m$StringToColor$e[0m" }

  return $retValue

}

Can be used thus;

$FirstVar = Colorize-Text -StringToColor "This is Green" -TextColor Green

$SecondVar = Colorize-Text -StringToColor "This is NOT Green" -TextColor Cyan -BackgroundColor Red

Write-host $FirstVar $SecondVar

Or whatever other combination you choose.

Solution 11 - Powershell

Here is a simplistic way to do this

if ($help)
{

	Write-Host "     For the switch " -NoNewline; Write-Host " -userUniqueId" -ForegroundColor Green -NoNewline; Write-Host ", enter an email address or samaccountname (pin) so '-userUniqueId 123456' "
	Write-Host "";
	Write-Host "     For the switch " -NoNewline; Write-Host " -disableMFAForUser" -ForegroundColor Green -NoNewline; Write-Host ", enter an email address or samaccountname (pin) with the -userUniqueId and then '-disableMFAForUser $true' "
	Write-Host "";
	Write-Host "     For the switch " -NoNewline; Write-Host "-enableMFAForUser" -ForegroundColor Green -NoNewline; Write-Host ", enter an email address or samaccountname (pin) with the -userUniqueId and then '-enableMFAForUser $true' "
	Write-Host "";
	Write-Host "     For the switch " -NoNewline; Write-Host "-verifyAllMFAEnabled" -ForegroundColor Green -NoNewline; Write-Host ", enter '-verifyAllMFAEnabled $true' "
	Write-Host "";
	Write-Host "     For the switch " -NoNewline; Write-Host " -verifyAllMFADisabledSpecificUser" -ForegroundColor Green -NoNewline; Write-Host ", enter an email address or samaccountname (pin) and then '-verifyAllMFADisabledSpecificUser $true' "
	Write-Host "";

	return;
}

Solution 12 - Powershell

I was trying to run this on a Windows Server 2012R2 box under ISE and the function by Jesse Chisholm was failing because for some reason (Get-Host).UI.RawUII.ForegroundColor was -1. To stop this happening and to simplify the function I little I modified it as follows:

function Write-ColorText
{
    # DO NOT SPECIFY param(...)
    #    we parse colors ourselves.

    $allColors = ("-Black",   "-DarkBlue","-DarkGreen","-DarkCyan","-DarkRed","-DarkMagenta","-DarkYellow","-Gray",
                  "-Darkgray","-Blue",    "-Green",    "-Cyan",    "-Red",    "-Magenta",    "-Yellow",    "-White",
                   "-Foreground")
    
    $color = "Foreground"
    $nonewline = $false

    foreach($arg in $args)
    {
        if ($arg -eq "-nonewline")
        { 
            $nonewline = $true 
        }
        elseif ($allColors -contains $arg)
        {
            $color = $arg.substring(1)
        }
        else
        {
            if ($color -eq "Foreground")
            {
                Write-Host $arg -nonewline
            }
            else
            {
                Write-Host $arg -foreground $color -nonewline
            }
        }
    }

    Write-Host -nonewline:$nonewline
}

I know this is an old post but hopefully this is useful to somebody and thanks Jesse for giving me this wonderful function!!

Solution 13 - Powershell

If you are in my situation, I've found a plain vanilla way from microsoft docs to set console mode. So here is an easy way to start and end 256 colors ansi console support in both cmd and powershell:

// https://docs.microsoft.com/en-us/windows/console/setconsolemode
#include <Windows.h>
#include <iostream>
struct  console_data {
	HANDLE hstdin;
	DWORD  mode;

	DWORD start()
	{
		hstdin = GetStdHandle(STD_OUTPUT_HANDLE);
		GetConsoleMode(hstdin, &mode);
		if (!SetConsoleMode(hstdin, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
			DWORD E = GetLastError();
			std::cout << " Error #" << E << "in:"  __FUNCTION__ "\n";
			return GetLastError();
		}
		std::cout << "\033[1;14mReady.\e[0m\n";
		return 0;
	}

	void end()
	{
		SetConsoleMode(hstdin, mode);
	}
	~console_data() {
		end();
	}
	//...
}RTConsole;

//...
int main()
{
   //... 
   RTConsole.start();
   std::cout << "\033[38;5;192m Should be 'Orange'\n";
   RTConsole.end();
   return 0;
}

https://docs.microsoft.com/en-us/windows/console/setconsolemode

Note: I did not find how to get 256 colors support into VS Code's poswershell extension.

Solution 14 - Powershell

Yet another "write color" function, this one:

  1. Has a helper function Get-WriteColors to help make a color array. (Otherwise you have to do [ConsoleColor]::White, [ConsoleColor]::Red, etc...)
  2. Repeatedly cycles independently through both ForeColor and BackColor.
  3. By default uses the '~' marker in the text to indicate a color change.
  4. If given 2 strings before color parameters, the second string replaces '~' as the color change marker.
  5. Includes a -NoNewLine switch.
function Get-WriteColors {
    param(
        [Parameter(Mandatory, Position = 0)]
        [ConsoleColor[]]$ColorSet
    )
    return $ColorSet
}
function Write-Colors {
    [CmdletBinding(DefaultParameterSetName = 'NoCCMarker')]
    param(
        [Parameter(Mandatory, Position = 0)]
        [string]$Text,
        [Parameter(Mandatory, Position = 1, ParameterSetName = 'HasCCMarker')]
        [string]$ColorChangeMarker,
        [Parameter(Mandatory, Position = 1, ParameterSetName = 'NoCCMarker')]
        [Parameter(Mandatory, Position = 2, ParameterSetName = 'HasCCMarker')]
        [ConsoleColor[]]$ForeColor,
        [Parameter(Position = 2, ParameterSetName = 'NoCCMarker')]
        [Parameter(Position = 3, ParameterSetName = 'HasCCMarker')]
        [ConsoleColor[]]$BackColor = @([ConsoleColor]::Black),
        [switch]$NoNewLine
    )
    $Marker = if($PsCmdlet.ParameterSetName -eq 'NoCCMarker') {'~'} else {$ColorChangeMarker}
    $TextList = $Text -Split $Marker
    for($t = 0; $t -lt $TextList.Count; $t++) {
        $f = $t % $ForeColor.Count
        $b = $t % $BackColor.Count
        Write-Host $TextList[$t] -ForegroundColor $ForeColor[$f] -BackgroundColor $BackColor[$b] -NoNewLine
    }
    if( -not $NoNewLine ) {Write-Host}
}

Example use, the second call to Write-Colors replaces the default '~' with '#':

$f = 'C:\Temp\TestPath\TestFile.TXT'
$d =[System.IO.Path]::GetPathRoot($f)
$p = [System.IO.Path]::GetDirectoryName($f).SubString($d.Length)
$n = [System.IO.Path]::GetFileNameWithoutExtension($f)
$x = [System.IO.Path]::GetExtension($f)
$dp = $d + $p
$nx = $n + $x
#    Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow,  Gray
# DarkGray,     Blue,     Green,     Cyan,     Red,     Magenta,     Yellow, White
$ForeColors = Get-WriteColors Yellow, White, Cyan, Yellow, Red
$BackColors = Get-WriteColors DarkBlue, black, black, black, black
Write-Colors "f:~ [~$f~]" $ForeColors $BackColors
Write-Colors "dp:#[#$dp#]#, #nx:#[#$nx#]" '#' $ForeColors $BackColors
Write-Colors "d:~ [~$d~]~, ~p:~[~$p~]~, ~n:~[~$n~]~, ~x:~[~$x~]" $ForeColors $BackColors

Output:

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMark TomlinView Question on Stackoverflow
Solution 1 - PowershellJoshView Answer on Stackoverflow
Solution 2 - PowershellMadBoyView Answer on Stackoverflow
Solution 3 - PowershellJesse ChisholmView Answer on Stackoverflow
Solution 4 - PowershellCliffordView Answer on Stackoverflow
Solution 5 - PowershellRaphaël GomesView Answer on Stackoverflow
Solution 6 - Powershellmklement0View Answer on Stackoverflow
Solution 7 - PowershellAbraham LincolnView Answer on Stackoverflow
Solution 8 - PowershellAlbanView Answer on Stackoverflow
Solution 9 - PowershellEricMView Answer on Stackoverflow
Solution 10 - PowershellStanView Answer on Stackoverflow
Solution 11 - PowershellBbbView Answer on Stackoverflow
Solution 12 - PowershellpaubyView Answer on Stackoverflow
Solution 13 - PowershellBretzelusView Answer on Stackoverflow
Solution 14 - PowershellDarinView Answer on Stackoverflow