powershell

Diskspace Report HTML Text Color Output


I'm trying to modify the text color output of this awesome script.

I just want the text for Critical Red background cells to be white.

What am I doing wrong here?

If I get flamed for posting huge glob of code, I totally understand.

I've tried earnestly to update this but I'm horrific at coding.

 
# Set your warning and critical thresholds 
$percentWarning = 90; #wildly increased for testing critical threshold
$percentCritcal = 95; #wildly increased for testing
 
 
# REPORT PROPERTIES 
 # Path to the report 
  $reportPath = "C:\scripts\diskspace\Report\"; 
 
 # Report name 
  $reportName = "DiskSpaceRpt_$(get-date -format ddMMyyyy).html"; 
 
# Path and Report name together 
$diskReport = $reportPath + $reportName 
 
#Set colors for table cell backgrounds 
$redColor = "#FF0000" 
$orangeColor = "#FBB917" 
$FontColor = "#000000"
$fontcolorwhite = "#FFFFFF"

 
# Count if any computers have low disk space.  Do not send report if less than 1. 
$i = 0; 
 
# Get computer list to check disk space 
$computers = Get-Content "C:\scripts\diskspace\servers.txt"; 
$datetime = Get-Date -Format "MM-dd-yyyy_HHmmss"; 
 
# Remove the report if it has already been run today so it does not append to the existing report 
If (Test-Path $diskReport) 
    { 
        Remove-Item $diskReport 
    } 
 
# Cleanup old files.. 
$Daysback = "-7" 
$CurrentDate = Get-Date; 
$DateToDelete = $CurrentDate.AddDays($Daysback); 
Get-ChildItem $reportPath | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item; 
 
# Create and write HTML Header of report 
$titleDate = get-date -uformat "%m-%d-%Y - %A" 
$header = " 
  <html> 
  <head> 
  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'> 
  <title>DiskSpace Report</title> 
  <STYLE TYPE='text/css'> 
  <!-- 
  td { 
   font-family: Tahoma; 
   font-size: 11px; 
   border-top: 1px solid #999999; 
   border-right: 1px solid #999999; 
   border-bottom: 1px solid #999999; 
   border-left: 1px solid #999999; 
   padding-top: 0px; 
   padding-right: 0px; 
   padding-bottom: 0px; 
   padding-left: 0px; 
  } 
  body { 
   margin-left: 5px; 
   margin-top: 5px; 
   margin-right: 0px; 
   margin-bottom: 10px; 
   table { 
   border: thin solid #000000; 
  } 
  --> 
  </style> 
  </head> 
  <body> 
  <table width='100%'> 
  <tr bgcolor='#CCCCCC'> 
  <td colspan='7' height='25' align='center'> 
  <font face='tahoma' color='#003399' size='4'><strong>ghostinthewires Internal DiskSpace Report for $titledate</strong></font> 
  </td> 
  </tr> 
  </table> 
" 
 Add-Content $diskReport $header 
 
# Create and write Table header for report 
 $tableHeader = " 
 <table width='100%'><tbody> 
 <tr bgcolor=#CCCCCC> 
    <td width='10%' align='center'>Server</td> 
 <td width='5%' align='center'>Drive</td> 
 <td width='15%' align='center'>Drive Label</td> 
 <td width='10%' align='center'>Total Capacity(GB)</td> 
 <td width='10%' align='center'>Used Capacity(GB)</td> 
 <td width='10%' align='center'>Free Space(GB)</td> 
 <td width='5%' align='center'>Freespace %</td> 
 </tr> 
" 
Add-Content $diskReport $tableHeader 
  
# Start processing disk space reports against a list of servers 
  foreach($computer in $computers) 
 {  
 $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3" 
 $computer = $computer.toupper() 
  foreach($disk in $disks) 
 {         
  $deviceID = $disk.DeviceID; 
        $volName = $disk.VolumeName; 
  [float]$size = $disk.Size; 
  [float]$freespace = $disk.FreeSpace;  
  $percentFree = [Math]::Round(($freespace / $size) * 100, 2); 
  $sizeGB = [Math]::Round($size / 1073741824, 2); 
  $freeSpaceGB = [Math]::Round($freespace / 1073741824, 2); 
        $usedSpaceGB = $sizeGB - $freeSpaceGB; 
        $color = $whiteColor; 
        $fontcolor = $FontColorBlack
 
# Set background color to Orange if just a warning 
 if($percentFree -lt $percentWarning)       
  { 
    $color = $orangeColor  
 
# Set background color to Orange if space is Critical 
      if($percentFree -lt $percentCritcal) 
        { 
        $color = $redColor
        $fontcolor = $fontcolorwhite
       }         
  
 # Create table data rows  
    $dataRow = " 
  <tr> 
        <td width='10%'>$computer</td> 
  <td width='5%' align='center'>$deviceID</td> 
  <td width='15%' >$volName</td> 
  <td width='10%' align='center'>$sizeGB</td> 
  <td width='10%' align='center'>$usedSpaceGB</td> 
  <td width='10%' align='center'>$freeSpaceGB</td> 
  <td width='5%' font face='tahoma' font color=`'$FontColor`' size='4' bgcolor=`'$color`' align='center'>$percentFree</td> 
  </tr> 
" 
Add-Content $diskReport $dataRow; 
Write-Host -ForegroundColor DarkYellow "$computer $deviceID percentage free space = $percentFree"; 
    $i++   
  } 
 } 
} 
 
# Create table at end of report showing legend of colors for the critical and warning 
 $tableDescription = " 
 </table><br><table width='20%'> 
 <tr bgcolor='White'> 
    <td width='10%' align='center' bgcolor='#FBB917'>Warning less than 15% free space</td> 
 <td width='10%' align='center' bgcolor='#FF0000'>Critical less than 10% free space</td> 
 </tr> 
" 
  Add-Content $diskReport $tableDescription 
 Add-Content $diskReport "</body></html>" 
 

Setting #FontColor variables for text color to dynamically change output.


Solution

  • NEW ANSWER 2024-12-18

    I basically rewrote half the code lol.
    Now it's quite commented on why and how.
    It should be easy to understand.
    ## mark my specific comments.
    I stand my opinion that making the HTML template its own file would make this script much easier on eyes.

    # Set your warning and critical thresholds 
    $percentWarning = 90; #wildly increased for testing critical threshold
    $percentCritcal = 95; #wildly increased for testing
    
    
    # REPORT PROPERTIES 
    # Path to the report 
    $reportPath = 'C:\scripts\diskspace\Report\' 
    
    ## Renamed for clarity of content.   
    ## Also it's now a DateTime object so you can use it instead of calling the function multiple times.   
    $CurrentDate = Get-Date #-Format 'MM-dd-yyyy_HHmmss' 
    
    
    
    # Report name 
    ## Restructured to use the variable instead of calling again the cmdlet.  
    $reportName = 'DiskSpaceRpt_{0}.html' -f $CurrentDate.ToString('ddMMyyy')
    
    # Path and Report name together 
    ## Renamed for clarity of content.   
    ## Used 
    $DiskReportPath = Join-Path -Path $reportPath -ChildPath $reportName 
    
    ## If the file doesn't exist, creates it(and its directory ).  
    ## If the file does exist, overwrites it.  
    ## In both cases, save the link to the file as a FileInfo object to reuse it.   
    $DiskReportFile = New-Item -ItemType File -Path $DiskReportPath -Force
    
    
    # Count if any computers have low disk space.  Do not send report if less than 1. 
    ## Removed because we can use a calculated value later
    # $NumberLowSpaceComputers = 0 
    
    # Get computer list to check disk space   
    ## Renamed for clarity of content.   
    ## Also force-casted into a String Array, also for clarity.   
    [string[]]$ComputersArray = Get-Content 'C:\scripts\diskspace\servers.txt' 
    
    
    
    
    # Cleanup old files.. 
    $Daysback = '-7' 
    $DateToDelete = $CurrentDate.AddDays($Daysback) 
    ## Evaluate adding the parameters -File to Get-ChildItem if you are not intersted in deleting the directories.  
    ## If you ARE interested in deleting the directories, I suggest to add the parameter -Recourse to Remove-Item.   
    ## If you are making a simple comparison of a property in Where-Object, the scriptblock is useless.  
    Get-ChildItem $reportPath | Where-Object -Property LastWriteTime -LT $DatetoDelete | Remove-Item 
    
    # Create and write HTML Header of report 
    ## Using the already existing variable instead of calling Get-Date AGAIN.  
    ## Why was it using the Unix Format to format it though?   
    $titleDate = $CurrentDate.ToString('MM-dd-yyyy - dddd')
    
    
    <#
            Here a longer comment. Basically: most of the page is static. The only parts
            changing are the date in the title and the lines of the disks. So I made a
            Template in 3 parts:   
                #   The main HTML.   
                #   A template for the disk rows.   
                #   The CSS, because its curly brackets don't play well with templates
                    and it's also complex enough it's better to keep it separated for
                    easier reading.   
    
    
    
            Anyway: this makes writing the HTML+CSS much easier, but I suggest
            evaluating moving the template in its own files to dynamically    load by
            Get-Content if this becomes complex enough.  
    
            Especially because I pretty much rewrote it all to be HTML5-compliant.  
            Most properties now are managed by CSS.   
            More about them in the CSS variable, commented to be read even after being
            compiled.
    
        #>
    $Css = '
        /* This will be the base value for all Table Rows */
        tr {
            background-color: #cccccc;
        }
    
        /* This will be the base value for all Table Cells, both Header Cells<TH> and Data Cells<TD> */
        td, th {
            width: 10%;
            text-align: center;
        }
    
        /* This will be the base value for all Table Header Cells<TH> */
        /* Its values combine with those set in the previous declaration */
        /* In case of overlapping property settings, the successive overrides the previous */
        th {
            font-family: Tahoma, sans-serif;
            font-weight: bold;
            color: #003399;
        }
    
        /* This will affect Table Header Cells with the "Main" class */
        th.main {
            width: 100%;
            font-size: larger;
        }
    
        /* This will affect ANY element with the "Warning" class */
        .Warning {
            background-color: #FBB917;
        }
    
        /* This will affect ANY element with the "Critical" class */
        .Critical {
            background-color: #ff0000;
            color: #ffffff;
        }
    
    
        /* This will affect Table Data Cells that are inside Table Rows that are inside the Table Footer */
        tfoot tr {
            background-color: #ffffff;
        }
    
        /* This will affect ANY element with the "Warning" class inside the Table Footer<TFOOT> element */
        tfoot .Warning {
            width: 10%;
            color: unset;
        }
    
        /* This will affect ANY element with the "Warning" class inside the Table Footer<TFOOT> element */
        tfoot .Critical {
            width: 10%;
            color: unset;
        }
    
        /* This will affect ANY element with the "NoCenter" class */
        .NoCenter {
            /* This specifically resets the text alignment to the default */
            text-align: unset;
        }
    
    
    
        /* This will affect ANY element with the "FivePercent" class */
        .FivePercent {
            width: 5%;
        }
    
        /* This will affect ANY element with the "FifteenPercent" class */
        .FifteenPercent {
            width: 15%;
        }
    
        '
    
    
    $HtmlTemplate = " 
        <!doctype html>
        <html lang='en'>
    
        <head>
            <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
            <title>DiskSpace Report ({0} )</title>
            <STYLE>
            {1}
            </style>
        </head>
    
        <body>
            <table>
                <thead>
                    <tr>
                        <th colspan='7' class='main'> ghostinthewires Internal DiskSpace Report for {0} </th>
                    </tr>
                    <tr>
                        <th>Server</th>
                        <th class='FivePercent'>Drive</th>
                        <th class='FifteenPercent'>Drive Label</th>
                        <th>Total Capacity(GB)</th>
                        <th>Used Capacity(GB)</th>
                        <th>Free Space(GB)</th>
                        <th class='FivePercent'>Freespace %</th>
                    </tr>
                </thead>
                <tbody>
        {2}
                </tbody> 
                <tfoot>
                    <tr> 
                        <td class='Warning'>Warning less than 15% free space</td> 
                        <td class='Critical'>Critical less than 10% free space</td> 
                        <td colspan='5'></td>
                    </tr> 
            </tfoot>
            </table>
        </body>
        </html>
        " 
    
    $TableRowTemplate = " 
                    <tr> 
                        <td >{0}</td> 
                        <td class='FivePercent' >{1}</td> 
                        <td  class='FifteenPercent NoCenter'>{2}</td> 
                        <td  >{3:n2}</td> 
                        <td  >{4:n2}</td> 
                        <td  >{5:n2}</td> 
                        <td class='FivePercent {6}' >{7}</td> 
                    </tr> 
        "
    
    
    
    
    # Start processing disk space reports against a list of servers 
    ## I wrote it so every Success Stream output will be added to the $HtmlTableRowArray array.  
    ## And the Success Stream is obviously a string formatted from $TableRowTemplate.   
    ## It also means you don't need a dedicated variable to keep track of how many disks have issues: 
    ## you can simply use the .Count property of $HtmlTableRowArray.   
    $HtmlTableRowArray = foreach ($computer in $ComputersArray) {  
        ## Using Get-CimInstance because the Wmi cmdlets are obsolete.   
        $disks = Get-CimInstance -ComputerName $computer -Class Win32_LogicalDisk -Filter 'DriveType = 3' 
            
        ## just use the disk property as needed for the computer name.  
        # $computer = $computer.toupper() 
            
        foreach ($disk in $disks) {         
            ## Removed because you can simply call the object properties directly.   
            ## $deviceID = $disk.DeviceID 
            ## $volName = $disk.VolumeName 
            [float]$size = $disk.Size 
            [float]$freespace = $disk.FreeSpace  
            $percentFree = [Math]::Round(($freespace / $size) * 100, 2) 
    
            ## by using /1GB you can automagically convert to Gigabyte values.
            ## replace GB with MB, kB and others for different scale.   
            $sizeGB = $size / 1GB
            $freeSpaceGB = $freespace / 1GB
            $usedSpaceGB = $sizeGB - $freeSpaceGB 
    
            ## Three possibilities, so a Switch is a little better.  
            ## Especially in the scenario of adding further values, you never know.   
            $Class = switch ($percentFree) {
                { $_ -lt $percentCritcal } { 'Critical'; break }         
                { $_ -lt $percentWarning } { 'Warning' ; break }
                default { $null }
            }
    
            ## Compiles the $TableRowTemplate with the following values, then sends the results to the Success Stream where it gets added to $HtmlTableRowsArray.   
            $TableRowTemplate -f $disk.SystemName.ToUpper(), $disk.deviceID, $disk.VolumeName, $sizeGB, $usedSpaceGB, $freeSpaceGB, $Class, $percentFree
    
            ## Tell the user through the terminal about it
            Write-Host -ForegroundColor DarkYellow "$($disk.SystemName.ToUpper()) | $($disk.DeviceID) | percentage free space = $percentFree" 
                    
        } 
    } 
    
    
    ## Just to let the user know... or whatever you need.  
    Write-Host "number of disk with problem is: $($HtmlTableRowArray.Count)"
    
    ## Compiles the $HtmlTeplate with the values for the title date, the CSS and the disk rows.   
    ## because $HtmlTableRowArray is an array, it needs to be converted to a single string through -Join.  
    ## The resulting string is then set on the report file
    $HtmlTemplate -f $titleDate, $css, ($HtmlTableRowArray -join [System.Environment]::NewLine) | Set-Content -Path $DiskReportFile
    

    OLD ANSWER

    here, it took me 3e124^(googol) years in notepad.exe to write this down (read: triple check it because I didn't bother beyond basic functionality and I have no doubt I used some obsolete HTML properties)

    # Set your warning and critical thresholds 
    $percentWarning = 90; #wildly increased for testing critical threshold
    $percentCritcal = 95; #wildly increased for testing
    
    
    # REPORT PROPERTIES 
    # Path to the report 
    $reportPath = 'C:\scripts\diskspace\Report\' 
    
    # Report name 
    $reportName = "DiskSpaceRpt_$(Get-Date -Format ddMMyyyy).html" 
    
    # Path and Report name together 
    $diskReport = Join-Path -Path $reportPath -ChildPath $reportName 
    
    # Count if any computers have low disk space.  Do not send report if less than 1. 
    $i = 0 
    
    # Get computer list to check disk space 
    $computers = Get-Content 'C:\scripts\diskspace\servers.txt' 
    $datetime = Get-Date -Format 'MM-dd-yyyy_HHmmss' 
    
    
    $null = New-Item $diskReport -Force
    
    # Cleanup old files.. 
    $Daysback = '-7' 
    $CurrentDate = Get-Date 
    $DateToDelete = $CurrentDate.AddDays($Daysback) 
    Get-ChildItem $reportPath | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item 
    
    # Create and write HTML Header of report 
    $titleDate = Get-Date -UFormat '%m-%d-%Y - %A' 
    $Html = " 
    <!doctype html>
    <html> 
    <head> 
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> 
    <title>DiskSpace Report</title> 
    <STYLE TYPE='text/css'> 
    tr {
        background-color: #cccccc;
    }
    
    td,
    th {
        text-align: center;
    }
    
    th {
        font-family: Tahoma, sans-serif;
        font-weight: bold;
        color: #003399;
    }
    
    th.main{
        font-size: larger;
    }
    
    tfoot tr {
        background-color: #ffffff;
    }
    
    tfoot tr td:first-child {
        background-color: #FBB917;
    }
    
    tfoot tr td:last-child {
        background-color: #ff0000;
    }
    
    
    
    .NoCenter {
        text-align: unset;
    }
    
    .Warning {
        color: #FBB917;
    }
    
    .Critical {
        color: #ff0000;
        background-color: #ffffff;
    }
    </style> 
    </head> 
    <body> 
    <table width='100%'> 
    <thead>  
        <tr >
            <th colspan='7' class='main'>   ghostinthewires Internal DiskSpace Report for $titledate  </th>
        </tr>   
        <tr> 
            <th width='10%' >Server</th> 
            <th width='5%' >Drive</th> 
            <th width='15%' >Drive Label</th> 
            <th width='10%' >Total Capacity(GB)</th> 
            <th width='10%' >Used Capacity(GB)</th> 
            <th width='10%' >Free Space(GB)</th> 
            <th width='5%' >Freespace %</th> 
        </tr> 
    </thead>
    <tbody>
    "
    
    $HtmlFooter = "
    </tbody> 
    <tfoot>
        <tr> 
            <td width='10%'>Warning less than 15% free space</td> 
            <td width='10%'>Critical less than 10% free space</td> 
        </tr> 
    </tfoot>
    </table>
    </body>
    </html>
    " 
    
    $dataRow = " 
        <tr> 
            <td width='10%'>{0}</td> 
            <td width='5%' >{1}</td> 
            <td width='15%' class='NoCenter'>{2}</td> 
            <td width='10%' >{3:n2}</td> 
            <td width='10%' >{4:n2}</td> 
            <td width='10%' >{5:n2}</td> 
            <td width='5%' class='{6}' >{7}</td> 
        </tr> 
    "
    
    
    
    
    # Start processing disk space reports against a list of servers 
    foreach ($computer in $computers) {  
        $disks = Get-CimInstance -ComputerName $computer -Class Win32_LogicalDisk -Filter 'DriveType = 3' 
        # $computer = $computer.toupper() 
        foreach ($disk in $disks) {         
            $deviceID = $disk.DeviceID 
            $volName = $disk.VolumeName 
            [float]$size = $disk.Size 
            [float]$freespace = $disk.FreeSpace  
            $percentFree = [Math]::Round(($freespace / $size) * 100, 2) 
            $sizeGB = $size / 1GB
            # $sizeGB.gettype(); pause
            $freeSpaceGB = $freespace / 1GB
            $usedSpaceGB = $sizeGB - $freeSpaceGB 
            $Class = $Null
    
            # Set background color to Orange if just a warning 
            if ($percentFree -lt $percentWarning) { 
                $Class = '.Warning'
    
                # Set background color to Orange if space is Critical 
                if ($percentFree -lt $percentCritcal) { 
                    $class = '.Critical'
                }         
    
    
                $Html += $dataRow -f $computer, $deviceID, $volName, $sizeGB, $usedSpaceGB, $freeSpaceGB, $Class, $percentFree
    
                
                Write-Host -ForegroundColor DarkYellow "$computer $deviceID percentage free space = $percentFree" 
                $i++   
            } 
        } 
    } 
    
    # A table at end of report showing legend of colors for the critical and warning 
    $Html += $HtmlFooter
    
    # Export to the file.   
    $Html | Set-Content -Path $diskReport