Модуль PowerShell PSWriteColor уже хорошо справляется с выводом нескольких цветов на одной строке.Либо вы загружаете его непосредственно из GitHub и импортируете его с помощью Import-Module <PATH-TO>\PSWriteColor.psd1
, либо устанавливаете его непосредственно из галереи PowerShell с помощью Install-Module -Name PSWriteColor
.
Краткий синтаксис: Write-Color -Text "GreenText","RedText","BlueText" -Color Green,Red,Blue
.Поэтому нам нужно добавить аргумент [String[]]$Text
строкой, содержащей необходимые пробелы, чтобы центрировать сообщение на экране и соответствующим образом добавить цвет к аргументу [ConsoleColor[]]$Color
.
Вот небольшая вспомогательная функция дляcentering.
#Requires -Modules @{ ModuleName="PSWriteColor"; ModuleVersion="0.8.5" }
function WriteColor-Centered {
param(
[Parameter(Mandatory=$true)][string[]]$Text,
[Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
$messageLength = 0
$Text | ForEach-Object { $messageLength += $_.Length }
[String[]] $centeredText = "{0}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($messageLength / 2))))
$centeredText += $Text
[ConsoleColor[]]$OutColor = @([ConsoleColor]::White)
$OutColor += $Color
Write-Color -Text $centeredText -Color $OutColor
# Alt.: use WriteColor-Core, see below
# WriteColor-Core -Text $centeredText -Color $OutColor
}
Я скопировал вычисление пробелов из этого ответа stackoverflow .
EDIT: меня спрашивали, возможно ли сделать эту работу без импорта модуля,Честно говоря, сейчас я чувствую себя немного грязно, потому что я вошел в исходный код хорошо написанного модуля, убрал из него всю функциональность и обработку ошибок и вставил его сюда.
В любом случае - если вы замените вызов Write-Color
в функции-обертке выше и вызовете следующее WriteColor-Core
, вместо этого вы можете отказаться от загрузки модуля PSWriteColor.
function WriteColor-Core {
param(
[Parameter(Mandatory=$true)][string[]]$Text,
[Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
# Fallback defaults if one of the values isn't set
$LastForegroundColor = [console]::ForegroundColor
# The real deal coloring
for ($i = 0; $i -lt $Text.Count; $i++) {
$CurrentFGColor = if ($Color[$i]) { $Color[$i] } else { $LastForegroundColor }
$WriteParams = @{
NoNewLine = $true
ForegroundColor = $CurrentFGColor
}
Write-Host $Text[$i] @WriteParams
# Store last color set, in case next iteration doesn't have a set color
$LastForegroundColor = $CurrentFGColor
}
Write-Host
}