在一个命令Powershell多个前景色

我想用一个语句输出许多不同的前景色。

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

这个输出是红色的。

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

这个输出是蓝色的。

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

这个输出是洋红色的,但是我想通过一个命令将颜色设置为红色,对于单词蓝色则是蓝色。 我怎样才能做到这一点?

编辑:用新版本更新,为logging目的添加logging到文件

乔希的方法太棒了,我真的去了,扩大了一点为我的需要。 我写过博客文章如何使用多种颜色对PowerShell进行格式化 (包括截图和全部 – 对于整个故事和用法)。

  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" 

如何使用多种颜色格式化PowerShell

它实际上带来了Josh脚本的额外的检查和function。

您可以推出自己的“写入颜色”命令或查找改变颜色的内联标记的内容。 这是ANSI转义序列用于在BBS日子里工作的方式。

但是你可以通过这样做来达到你想要的:

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

这是一个简单的小function,可以完成你所要求的function。

 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 

这个函数提供了不同的语法糖:

 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 } } 

例子:

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

我知道这个问题已经过了很长时间,但现在可以帮助任何人search。

这是我写的输出彩色文本的一个小函数:(实际上它更小,但是我把它改写成更容易理解)

 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; } 

使用起来非常简单:只需使用“ Write-Color "your text"并在希望文本着色的花括号之间添加一些颜色名称即可。

示例: Write-Color "Hello, {red}my dear {green}friend !" 会输出

脚本截图

你可以把它放在你的$profile文件中,在简单的powershell提示符下使用它,或者把它添加到一些脚本中。

这也可以…

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

此代码可以通过不同数量的Arg:Text / ForeGroundColor / BackGroundColor获得。 每个颜色列表使用白色旋转实现

 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 } 

日志用法:

 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 

在这里输入图像说明

列表使用情况(只有2个backGroundColor和4个foreGroundColor)

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

在这里输入图像说明

标准写主机

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

在这里输入图像说明

我试图在ISE下的Windows Server 2012R2框中运行此function,由于某种原因(Get-Host).UI.RawUII.ForegroundColor为-1,Jesse Chisholm的function失败。 要停止这种情况发生,并简化function,我小小的我修改如下:

 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 } 

我知道这是一个旧post,但希望这是有用的人,并感谢杰西给我这个奇妙的function!

查找下面的高级函数Write-HostColored ,它允许在string中embedded着色指令 ,包括前景色和背景色:

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

以上收益率:

样本输出

除了使用-ForegroundColor-ForegroundColor接受默认的前景色和背景色-ForegroundColor ,还可以使用以下语法在string中embedded一个或多个颜色说明:

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

<fgcolor><bgcolor>必须是有效的[ConsoleColor]值,例如greenwhite (大小写无关紧要)。 遵循颜色规范的所有内容直到下一个#或隐式地直到string的末尾,都以该颜色写入。


Write-HostColored源代码(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, eg, '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 '^([az]*)(:([az]+))?$') { # 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 (eg, 'green'), or a foreground-background color pair (eg, 'green:white'), or just a background color (eg, ':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 } } } 

稍微修改这一个…我采取版本2,删除日志(因为我不想要它),然后添加一个布尔参数,类似于-NoNewLine写入主机。 我特意试图添加更改颜色的function,并在同一行提示用户input,以便在用户不input任何内容时突出显示默认答案。

我意识到这是可用的Write-HostColored(上面)…但有时你只是想更简化的代码…

 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 

我正在尝试完成的示例:

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