Search code examples
htmlcsspowershellcolors

PowerShell: Change cell color in HTML table based on value or IF statements


Evening guys. I've got a function I've been working on as part of a script I've got that creates a nested hashtable of software information and creates an HTML table. I've got the table working and I like how it is, but I'd like to have a cell (or maybe just the text colors in certain cells) change color based on if certain values match.

My thoughts are either a Status column and having the background color change, or have the text in Installed Version & Expected Version columns change color.I don't know if it's possible with how I'm compiling the table, and it isn't a end of the world thing if it won't work, more of a "be cool if it could" kind of thing.

My Overall Question is: How can I change the background color of a cell in the "Status" column based on if two certain values match. Or alternatively have the text color change in a cell for the "Installer Version" and "Expected Versions" columns. Below is my function

Note: I am extremely new to HTML/CSS languages. This is what I've been able to put together with a lot of googling and reading.

Function Get-SoftwareVersions{
<#
.DESCRIPTION
Function used to gather the software application version information in the section above.
Collects the information from the InstallerVersion and ExeVersion properties and reports them into a HTML table.
#>
$AdminTools = [ordered]@{
    "Notepad" = [PSCustomObject]@{
        Application = "Notepad++"
        "Installed Version" = $Notepad.ExeVersion
        "Expected Version" = $Notepad.InstallerVersion
        "Status" = ""
    }
    "PowerShell7" = [PSCustomObject]@{
        Application = "PowerShell 7"
        "Installed Version" = $PowerShell7.ExeVersion
        "Expected Version" = $PowerShell7.InstallerVersion
        "Status" = ""
    }
    "PuTTY" = [PSCustomObject]@{
        Application = "PuTTY"
        "Installed Version" = $Putty.ExeVersion
        "Expected Version" = $Putty.InstallerVersion
        "Status" = ""
    }
    "MTPuTTY" = [PSCustomObject]@{
        Application = "MTPuTTY"
        "Installed Version" = $Putty.MTPuttyVersion
        "Expected Version" = $Putty.MTPuttyVersion
        "Status" = ""
    }
    "Rufus" = [PSCustomObject]@{
        Application = "Rufus"
        "Installed Version" = $Rufus.ExeVersion
        "Expected Version" = $Rufus.ExeVersion
    }
    "TFTP Server" = [PSCustomObject]@{
        Application = "TFTP Server"
        "Installed Version" = $TFTP.ExeVersion
        "Expected Version" = $TFTP.InstallerVersion
    }
    "VLC Media Player" = [PSCustomObject]@{
        Application = "VLC Media Player"
        "Installed Version" = $VLC.ExeVersion
        "Expected Version" = $VLC.InstallerVersion
    }
    "WinMerge" = [PSCustomObject]@{
        Application = "WinMerge"
        "Installed Version" = $WinMerge.ExeVersion
        "Expected Version" = $WinMerge.InstallerVersion
    }
    "WinSCP" = [PSCustomObject]@{
        Application = "WinSCP"
        "Installed Version" = $WinSCP.ExeVersion
        "Expected Version" = $WinSCP.InstallerVersion
    }
    "WireShark" = [PSCustomObject]@{
        Application = "WireShark"
        "Installed Version" = $WireShark.ExeVersion
        "Expected Version" = $WireShark.InstallerVersion
    }
    "NPCap" = [PSCustomObject]@{
        Application = "NPCap"
        "Installed Version" = $NPCap.ExeVersion
        "Expected Version" = $NPCap.InstallerVersion
    }
}
$Browsers = [ordered]@{
    "Microsoft Edge" = [PSCustomObject]@{
        Application = "Microsoft Edge"
        "Installed Version" = $MSEdge.ExeVersion
        "Expected Version" = $MSEdge.InstallerVersion
        "Status" = ""
    }
}
$VMWare = [ordered]@{

    "OVFTool" = [PSCustomObject]@{
        Application = "OVFTool"
        "Installed Version" = $OVFTool.ExeVersion
        "Expected Version" = $OVFTool.InstallerVersion
    }
    "PowerCLI" = [PSCustomObject]@{
        Application = "PowerCLI PowerShell Module"
        "Installed Version" = $PowerCLI.ModuleVersion
        "Expected Version" = $PowerCLI.InstallerVersion
    }
    "VMware Workstation" = [PSCustomObject]@{
        Application = "VMware Workstation"
        "Installed Version" = $Workstation.ExeVersion
        "Expected Version" = $Workstation.InstallerVersion
    }
    "VMRC" = [PSCustomObject]@{
        Application = "VMware Remote Console"
        "Installed Version" = $VMRC.ExeVersion
        "Expected Version" = $VMRC.InstallerVersion
    }
}
$Satcom = [ordered]@{
    "Airbus M&C" = [PSCustomObject]@{
        Application = "Airbus Monitor & Control"
        "Installed Version" = $AirbusMC.ExeVersion
        "Expected Version" = $AirbusMC.InstallerVersion
    }
    "Airbus KA-Band SSPB Software" = [PSCustomObject]@{
        Application = "Mission Microwave UserGUI"
        "Installed Version" = $AirbusKA.InstallerVersion
        "Expected Version" = $AirbusKA.InstallerVersion
    }
    "Airbus Spec Any" = [PSCustomObject]@{
        Application = "EVO Spectrum Analyzer"
        "Installed Version" = $AirbusSpecAny.InstallerVersion
        "Expected Version" = $AirbusSpecAny.InstallerVersion
    }
    "Wavestream" = [PSCustomObject]@{
        Application = "Wavestream UserGUI"
        "Installed Version" = $Wavestream.InstallerVersion
        "Expected Version" = $Wavestream.InstallerVersion
    }

}
$SDCApps = [ordered]@{
    "NetBanner" = [PSCustomObject]@{
        Application = "NetBanner"
        "Installed Version" = $NetBanner.ExeVersion
        "Expected Version" = $NetBanner.InstallerVersion
    }
    "Axway" = [PSCustomObject]@{
        Application = "Axway"
        "Installed Version" = $Axway.ExeVersion
        "Expected Version" = $Axway.InstallerVersion
    }
    "ActivClient" = [PSCustomObject]@{
        Application = "ActivClient"
        "Installed Version" = $ActivClient.ExeVersion
        "Expected Version" = $ActivClient.InstallerVersion
    }
    "90Meter" = [PSCustomObject]@{
        Application = "90Meter"
        "Installed Version" = $90Meter.ExeVersion
        "Expected Version" = $90Meter.InstallerVersion
    }
    "Titus Classification" = [PSCustomObject]@{
        Application = "Titus Classification"
        "Installed Version" = $Titus.ExeVersion
        "Expected Version" = $Titus.InstallerVersion
    }
}


Switch ($Enclave){
    NIPR {
        $SDCApps.Remove("90Meter")
        $SDCApps.Remove("Titus Classification")
        $PreContentHeader = "<h2>TDC Management Laptop Application Baseline Versioning Table - <span style='color:green'>NIPR</span></h2> 
        <h3>Report Run: <span style='color:red'>$(Get-Date)</span> by <span style='color:red'>$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)</span></h3>"
    }

    SIPR {
        $SDCApps.Remove("ActivClient")
        $PreContentHeader = "<h2>TDC Management Laptop Application Baseline Versioning Table - <span style='color:red'>SIPR</span></h2> <h3><p id='ReportDate'>Report Run: $(Get-Date) by $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)</h3>"
    }
}

$Header = @'
<style>
    body {
        background-color: Gainsboro;
        font-family:      "Calibri";
    }

    table {
        border-width:     1px;
        border-style:     solid;
        border-color:     black;
        border-collapse:  collapse;
        width:            75%;
    }

    col {
        width: 20%;
    }

    th {
        border-width:     1px;
        padding:          5px;
        border-style:     solid;
        border-color:     black;
        background-color: #98C6F3;
    }

    td {
        border-width:     1px;
        padding:          5px;
        border-style:     solid;
        border-color:     black;
        background-color: White;
    }

    td[value="wrong"]{
        background-color: #ff0000;
    }

    tr {
        text-align: left;
        background-color: #00ff00;
    }
   
</style>
'@


$Title = "<h1>TDC Management Laptop Application Baseline Versioning Table - <span style='color:green'>NIPR</span></h1>
<h3>Report Run: <span style='color:red'>$(Get-Date)</span> by <span style='color:red'>$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)</span></h3>"

$Admin = $Admintools.Values | ConvertTo-Html -Fragment -precontent "<h3>Administrator Tools</h3>"
$Browser = $Browsers.Values | ConvertTo-Html -Fragment -PreContent "<h3>Web Browsers</h3>"
$VMWareApps = $VMWare.Values | ConvertTo-Html -Fragment -PreContent "<h3>VMware Applications</h3>"
$SatcomApps = $Satcom.Values | ConvertTo-Html -Fragment -PreContent "<h3>SATCOM Applications</h3>"
$SDC = $SDCApps.Values | ConvertTo-Html -Fragment -PreContent "<h3>SDC Applications</h3>"




ConvertTo-Html -Body "$Title $Admin $Browser $VmWareApps $SatcomApps $SDC" -Head $Header | Out-File "C:\Source\BuildSource\Laptop\Application_Verification.html"



Invoke-Item "C:\Source\BuildSource\Laptop\Application_Verification.html"

}

Solution

  • There is no way to reproduce your code without having all variables defined beforehand hence I'll use below example object to demonstrate how this can be done.

    $adminTools = @(
        [ordered]@{
            "Application"       = "PowerShell 7"
            "Installed Version" = [version] '5.1'
            "Expected Version"  = [version] '7.2.6'
        }
        [ordered]@{
            "Application"       = "PuTTY"
            "Installed Version" = [version] '0.77'
            "Expected Version"  = [version] '0.77'
        }
    )
    

    I have added these 2 classes to your current CSS:

    .bad {
      background-color: #ffc7ce;
      color: #9c0006;
      font-weight: bold;
    }
    
    .good {
      background-color: #c6efce;
      color: #006100;
      font-weight: bold;
    }
    

    First part is adding the status column based on the condition if Installed Version is lower than Expected Version:

    $export = foreach($item in $adminTools) {
        $item['Status'] = 'Up to Date'
        if($item['Installed Version'] -lt $item['Expected Version']) {
            $item['Status'] = 'Needs Update'
        }
        [pscustomobject] $item
    }
    

    Now we can use Regex.Replace(String, String, MatchEvaluator) combined with a hashtable that we can use to replace the <td> tag for the the <td> tags with the clases depending on the matched value in the capturing group:

    $map = @{
        'Up to Date'   = '<td class="good">'
        'Needs Update' = '<td class="bad">'
    }
    
    $html = $export | ConvertTo-Html -PreContent $style -Head '<h1>Hello world</h1>'
    [regex]::Replace($html, '(?i)<td>(Needs Update|Up to Date)', {
        param($s)
        $map[$s.Groups[1].Value] + $s.Groups[1].Value
    }) | Set-Content test.html
    
    Invoke-Item test.html
    

    Demo of how this would look using the example objects

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <h1>Hello world</h1>
      </head>
      <body>
        <style>
          body {
            background-color: Gainsboro;
            font-family: "Calibri";
          }
    
          table {
            border-width: 1px;
            border-style: solid;
            border-color: black;
            border-collapse: collapse;
            width: 75%;
          }
    
          col {
            width: 20%;
          }
    
          th {
            border-width: 1px;
            padding: 5px;
            border-style: solid;
            border-color: black;
            background-color: #98C6F3;
          }
    
          td {
            border-width: 1px;
            padding: 5px;
            border-style: solid;
            border-color: black;
            background-color: White;
          }
    
          .bad {
            background-color: #ffc7ce;
            color: #9c0006;
            font-weight: bold;
          }
    
          .good {
            background-color: #c6efce;
            color: #006100;
            font-weight: bold;
          }
    
          tr {
            text-align: left;
            background-color: #00ff00;
          }
        </style>
        <table>
          <colgroup>
            <col />
            <col />
            <col />
            <col />
          </colgroup>
          <tr>
            <th>Application</th>
            <th>Installed Version</th>
            <th>Expected Version</th>
            <th>Status</th>
          </tr>
          <tr>
            <td>PowerShell 7</td>
            <td>5.1</td>
            <td>7.2.6</td>
            <td class="bad">Needs Update</td>
          </tr>
          <tr>
            <td>PuTTY</td>
            <td>0.77</td>
            <td>0.77</td>
            <td class="good">Up to Date</td>
          </tr>
        </table>
      </body>
    </html>