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.
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
To start, I suggest you to add the HTML
and CSS
tags.
Especially because this code is using quite old HTML.
It's much easier to use better CSS for your scope.
Get-WmiObject
is obsolete and has been removed from Powershell 6+.
Replace it with Get-CimInstance
, it works the same(in this case)
You don't need to escape single quotes '
while encapsuled in double quotes "
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