1

Im running the code below and it works:

Get-ChildItem -Path T: -Filter *.pfx | ForEach-Object { 
    Import-PfxCertificate -FilePath $_.FullName -CertStoreLocation Cert:\CurrentUser\My -Password ****** -Force -AsPlainText) -Exportable 
} |
Format-Table -Property @{Label="Computador"; Expression={$env:computername}},
    @{Label="Nome"; Expression={$_.FriendlyName}},
    @{Label="Validade"; Expression={$_.NotAfter}},
    @{Label="Impressão digital"; Expression={$_.Thumbprint}} -AutoSize

I'm trying to write each line with expiring certificates with red color. If I try this:

Get-ChildItem -Path T: -Filter *.pfx | ForEach-Object { 
    Import-PfxCertificate -FilePath $_.FullName -CertStoreLocation Cert:\CurrentUser\My -Password ****** -Force -AsPlainText) -Exportable 
} |
Format-Table -Property @{Label="Computador"; Expression={$env:computername}},
    @{Label="Nome"; Expression={$_.FriendlyName}},
    @{Label="Validade"; Expression={$_.NotAfter}},
    @{Label="Impressão digital"; Expression={$_.Thumbprint}} -AutoSize |
Out-String | Write-Host -ForegroundColor Red

All lines become red. If I try to pass $_ value to a If, the console says that is a Null value.

Any suggestions?


The solution for what I wanted to do was provided by mklement0. I will leave what I did here, if someone has the same question:

Get-ChildItem -Path T: -Filter *.pfx | ForEach-Object {
Import-PfxCertificate -FilePath $_.FullName -CertStoreLocation Cert:\CurrentUser\My -Password ****** -Force -AsPlainText) -Exportable
            } | Format-Table -Property @{Label="Computador"; Expression={$env:computername}}, @{Label="Nome"; Expression={$_.FriendlyName}}, @{Label="Validade"; Expression={$_.NotAfter}}, @{Label="Status"; Expression={if (($_.NotAfter).subtract([DateTime]::Now).days -lt 0){"Expirado"} elseif (($_.NotAfter).subtract([DateTime]::Now).days -lt 30){"Expirando"}}},@{Label="Impressão digital"; Expression={$_.Thumbprint}} -AutoSize | Out-String -Stream |
            ForEach-Object {
                $fgArg = if ($_ -match 'Expirado') { @{ 'BackgroundColor' = 'Red'; 'ForegroundColor' = 'Black'} } elseif ($_ -match 'Expirando') { @{ 'BackgroundColor' = 'Yellow'; 'ForegroundColor' = 'Black'} } else { @{} }
                Write-Host @fgArg $_
            }
Raphael Souza
  • 17
  • 1
  • 6
  • 2
    Note that there is [feature request on GitHub that asks for conditional coloring of `Format-Table` output](https://github.com/PowerShell/PowerShell/issues/3886). – mklement0 Jul 27 '18 at 19:28
  • 1
    That would be perfect. Now we just need to wait to be implemented. – Raphael Souza Jul 30 '18 at 18:08

2 Answers2

6

The key is to use Out-String's -Stream switch, which enables line-by-line processing; by default, Out-String outputs a single multiline string.

Here's a simple example that colors those lines that contain the substring expired in red (as usual in PowerShell, matching is case-insensitive by default):

'A valid certificate', 'An expired certificate', 'A valid certificate' | 
   Out-String -Stream | ForEach-Object {
     $fgArg = if ($_ -match 'expired') { @{ 'ForegroundColor' = 'Red' } } else { @{} }
     Write-Host @fgArg $_
   }

The above yields:

enter image description here


If you're looking for this functionality packaged as an advanced function, see function
Out-HostColored in this answer of mine.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

You are trying to accomplish something that is quite difficult for PowerShell. I have written a script that would help you accomplish your goal https://gallery.technet.microsoft.com/scriptcenter/Highlight-String-and-45525e27

It isn't terribly elegant, but you would use it like this

gci cert: -Recurse | Format-Table -Property @{Label="Computador"; Expression={$env:computername}},@{Label="Exp"; Expression={if($_.NotAfter -le (get-date)){"Expired"}}}, @{Label="Nome"; Expression={$_.FriendlyName}}, @{Label="Validade"; Expression={$_.NotAfter}}, @{Label="Impressão digital"; Expression={$_.Thumbprint}},-AutoSize | ho '.*Expired.*'

Good Luck!

Shane

Neossian
  • 695
  • 4
  • 14