Multiple foreground colors in PowerShell in one command
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
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:
- GitHub Repository
- GitHub Reporting Issues
- PowerShellGallery Module
- Module description and a starting point.
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"
It actually brings additional checks and features over Josh script.
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
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.