23

I try to colorise the column RAM in red if the value is greater than 100 MB:

Get-Process | Format-Table @{ Label = "PID"; Expression={$_.Id}},
            @{ Label = "Name"; Expression={$_.Name}},
            @{ Label = "RAM (MB)"; Expression={[System.Math]::Round($_.WS/1MB, 1)}},
            @{ Label = "Responding"; Expression={$_.Responding}}

Enter image description here

I try with Write-Host -nonewline, but the result is wrong.

Get-Process | Format-Table @{ Label = "PID"; Expression={$_.Id}},
            @{ Label = "Name"; Expression={$_.Name}},
            @{ Label = "RAM (MB)"; Expression={write-host -NoNewline $([System.Math]::Round($_.WS/1MB, 1)) -ForegroundColor red}},
            @{ Label = "Responding"; Expression={ write-host -NoNewline $_.Responding -fore red}}

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alban
  • 3,105
  • 5
  • 31
  • 46

6 Answers6

39

Starting with PowerShell 5.1 or later you can use VT escape sequences to add colors to a single column, but only if your console supports VT escape sequences (e.g. Windows 10 Fall Creators Update, Linux or Mac, but not Windows 8 w/o a console emulator like ConEmu).

Here is an example that has the formatting specified in an expression, though the same could be used in a ps1xml file:

dir -Exclude *.xml $pshome | Format-Table Mode,@{
    Label = "Name"
    Expression =
    {
        switch ($_.Extension)
        {
            '.exe' { $color = "93"; break }
            '.ps1xml' { $color = '32'; break }
            '.dll' { $color = "35"; break }
           default { $color = "0" }
        }
        $e = [char]27
       "$e[${color}m$($_.Name)${e}[0m"
    }
 },Length

And the resulting output, note that the column width looks good, there are no extra spaces from the escape sequence characters.

Screenshot of dir output with colored names

Jason Shirk
  • 7,734
  • 2
  • 24
  • 29
  • There was an announcement about (maybe) 16bit support. Is that related to this feature, or something different? – stej Mar 02 '18 at 16:48
  • Yes, 256 and 24bit color is supported by some terminals, the link in my answer describes that as well. – Jason Shirk Mar 02 '18 at 18:01
  • 1
    this is pure gold. thx! what i made from it https://gist.github.com/SeidChr/6dcae356760197d3d9147a3414829945 – Chris Feb 04 '21 at 21:01
  • If anyone's tempted to declare the magic strings & numbers and improve readability, see https://stackoverflow.com/questions/16347214/pass-arguments-to-a-scriptblock-in-powershell. – Zian Choy Dec 28 '21 at 01:23
20

The accepted answer is incorrect, it is possible to colorize columns. The solution to getting conditional column colors is to use Write-PSObject.

Here are some wonderful examples with documented code and explanations.

From the above resource:

Write-PSObject $servers -MatchMethod Exact -Column "Manufacture" -Value "HP" -ValueForeColor Yellow -ValueBackColor Red -RowForeColor White -RowBackColor Blue;

enter image description here

I found this via a GitHub issue to add color formatting to Format-Table, which seems to be a feature PowerShell devs would like to add at some point.

Bjorn
  • 69,215
  • 39
  • 136
  • 164
  • 1
    It seems the links in your answer no longer point to the right place, only the GitHub issue is still correct. – skaravos Oct 21 '22 at 21:58
11

You could colorize the row making use of a regular expression...

filter colorize-row{

    Get-Process | Select-Object Id, Name, WS, Responding | foreach {

        # Print 'red' row if WS greater than 100 MB
        if([System.Math]::Round($_.WS/1MB,1) -match "^([0-9]|[0-9][0-9]|[1-9][0-9]?$|^100$)$"){
            [console]::ForegroundColor="white"; $_;
        } else {
            [console]::ForegroundColor="red"; $_;
        }
    }
}

colorize-row

Output:

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
TheOptimusPrimus
  • 411
  • 2
  • 15
  • 1
    Is there a way to format like when using `Format-Table`? I tried the `@{n=""; e={$_.}; a="left"}` syntax, but it doesn't work. – Adrian Nov 13 '15 at 19:49
  • This answer is no longer true, you can colorize columns, see my answer. – Bjorn Sep 11 '17 at 15:08
4

The quick answer is that you can't. It's possible to use Write-Host with colors, but there's no "output" to send to format-table.

The "output" from Write-Host is a side-effect that sends data directly to the console rather than returning it to the caller like a standard function.

In conjunction with the comment by @David Martin, here's a link with an interesting pattern-matching format-color function.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike Shepard
  • 17,466
  • 6
  • 51
  • 69
0

you can install module PsWrite

Write-color enter image description here

he also has other smart funtions like

Write-logstep enter image description here

Write-ProgressbarreColor enter image description here

Alban
  • 3,105
  • 5
  • 31
  • 46
0

Yes, you can use ANSI Escape colors and have the colors conditional:

Get-Process | Format-Table @{ Label = "PID"; Expression={$_.Id}},
        @{ Label = "Name"; Expression={$_.Name}},
        @{ Label = "RAM (MB)"; Expression={if($_.WS/1MB -gt 100){"$([char]27)[0;31m$([System.Math]::Round($_.WS/1MB, 1))$([char]27)[0m"}else{"$([char]27)[0;32m$([System.Math]::Round($_.WS/1MB, 1))$([char]27)[0m"}}},
        @{ Label = "Responding"; Expression={if($_.Responding -eq $true){"$([char]27)[0;32m$($_.Responding)$([char]27)[0m"}else{"$([char]27)[0;31m$($_.Responding)$([char]27)[0m"}}}