Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Creating Colorful HTML Disk Reports with PowerShell

Posted on October 11, 2018

I have no idea what possessed me, but the other day I came across an older script that uses PowerShell to create an HTML report showing drive utilization for a group of computers. The utilization is displayed using a color gradient from green to red to provide a visual reference. As I looked at the code I thought about what would be interesting to add and now a day or two later I have something new to show you.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The function could have been revised using commands in the Storage module like Get-Volume and Get-Disk. But I decided to stick to using Get-CimInstance to query traditional Win32_* classes. I also wanted to leverage the use of Get-CimAssociatedInstance to capture additional information. You can find the script file as a gist on Github.

Usage is pretty straightforward. You specify one or more computers and off you go. There is a default value for the resulting HTML file, but you'll likely want to specify your own.   Because the function is generating custom HTML on the fly, I also provided options for you to provide pre and post content HTML material, just as you might with ConvertTo-HTML. I also give you an option to specify a graphics file which is display like a logo at the top of the report. The graphics file will be embedded in the HTML file. The CSS is also embedded in the HTML making the entire file completely self-contained.

$params = @{
Computername = 'bovine320','dom1','think51','srv1','win10'
Path = 'c:\work\r.html'
Precontent = "<H3>Company Confidential</H3>" 
PostContent = "This report is provided <i>as-is</i>. Use commands like <b>Get-Volume</b> to validate."
LogoPath = 'c:\scripts\db.png'
}
New-HTMLDiskReport @params

As you look through the code, notice how I'm using Write-Progress to keep the user informed. This is something I wish more of you used instead of Write-Host. It makes your code much more professional. Let me show you the result.

image

The color gradient is self-evident but let me point out a few other things. Notice the footer.

image

This is something I've started doing in my HTML report scripts and I encourage you to think about. At some point, you might set up a script like this to run as a scheduled job or task. Perhaps emailing a group of Admins. Over time and with staff turnover, you may wonder "Where is this coming from?" Hopefully, the metadata information can help you track it down. I create a custom object and convert it to an HTML fragment.

#add some metadata about this report
[xml]$metadata = [pscustomobject]@{
    "Report Run" = "$((Get-Date).ToUniversalTime()) UTC"
    "Run By"     = "$($env:USERDOMAIN)\$env:username"
    Originated   = $env:Computername
    Command      = $($myinvocation.invocationname)
    Version      = "2.0"
} | ConvertTo-html -as List -Fragment

If you look in the code you'll see additional steps to insert style tags.

The other feature is the use of the Title attribute, or a customized version, to display additional information. If you hover your mouse over the computer name, you'll see a popup with the operating system.

image

Because I save the HTML as XML I can easily parse and update it.

#convert drive objects to HTML but as an XML document
Write-Verbose "Converting to XML"
[xml]$html = $drives | ConvertTo-Html -Fragment

#add the computer name as the table caption
$caption = $html.CreateElement("caption")
$html.table.AppendChild($caption) | Out-Null
$html.table.caption = $data[0].SystemName
$pop = $html.CreateAttribute("title")
$pop.value = (Get-Ciminstance -ClassName Win32_OperatingSystem -Property caption -cimsession $cs).caption
$html.table.item("caption").attributes.append($pop) | Out-Null

I do something similar with physical media information when you hover over the device ID.

image

Getting the information uses Get-CimassociatedInstance. Because a computer might have more than one drive, I create a hashtable using the device ID as the key and the DiskDrive instance as the value.

#initialize a hashtable of for phsyical media
$hash = @{}
#Create a custom object for each drive
$drives = foreach ($item in $data) {
                        
    $Physical = $item | Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition | Get-CimAssociatedInstance -ResultClassName Win32_DiskDrive
    $hash.Add($item.DeviceID,$physical)

    $prophash = [ordered]@{
        Drive         = $item.DeviceID
        Volume        = $item.VolumeName
        SizeGB        = $item.size / 1GB -as [int]
        FreeGB        = "{0:N4}" -f ($item.Freespace / 1GB)
        PercentFree   = [math]::Round(($item.Freespace / $item.size) * 100, 2)
    }
    New-Object PSObject -Property $prophash
} #foreach item

Later I add a custom tip class.

#add physical media as a popup for each device
for ($i=1; $i -le $html.table.tr.count -1;$i++) {
    $id = $html.table.tr[$i].ChildNodes[0]."#text"
    $pop = $html.CreateAttribute("tip")
    $props = ($hash.Item($id) | Select-Object -property Caption,SerialNumber,FirmwareRevision,Size,InterfaceType,SCSI* | Out-String).trim()     
    $pop.Value = $props
    $html.table.tr[$i].ChildNodes[0].Attributes.append($pop) | Out-Null
}

The hardest part, since I am not a web design person, was getting the correct style settings to display the text neatly.

td[tip]:hover {
    color: #ff2283;
    position: relative;
}

td[tip]:hover:after {
    content: attr(tip);
    left: 0;
    top: 100%;
    margin-left: 80px;
    margin-top: 10px;
    width: 400px;
    padding: 3px 8px;
    position: absolute;
    color: #85003a;
    font-family: 'Courier New', Courier, monospace;
    font-size: 10pt;
    background-color: gainsboro;
    white-space: pre-wrap;
}

But I have to say I like the way it turned out.

You may not have a need for this script as it is written, but hopefully, I've given you a few ideas and some code samples to begin working with. Enjoy and I hope you'll let me know what you think.


Behind the PowerShell Pipeline

Share this:

  • Share on X (Opens in new window) X
  • Share on Facebook (Opens in new window) Facebook
  • Share on Mastodon (Opens in new window) Mastodon
  • Share on LinkedIn (Opens in new window) LinkedIn
  • Share on Reddit (Opens in new window) Reddit
  • Print (Opens in new window) Print
  • Email a link to a friend (Opens in new window) Email

Like this:

Like Loading…

Related

10 thoughts on “Creating Colorful HTML Disk Reports with PowerShell”

  1. Ivan says:
    October 11, 2018 at 7:06 pm

    Sweet!

  2. Pingback: Creating Fancy HTML Reports With Powershell – Curated SQL
  3. Pingback: ICYMI: PowerShell Week of 12-October-2018 – PowerShell.org
  4. Pingback: PowerShell Schnipseljagd 42/18 | | PowerShell Usergroup Austria
  5. Yanick says:
    October 20, 2018 at 11:02 am

    Hi
    is there a script to list the ADgroupmember of the same name in different groups of the same OU?
    thanks 🙂

    1. Jeffery Hicks says:
      October 22, 2018 at 9:56 am

      I’m not sure I completely understand your question but there are cmdlets for getting group members from Active Directory so, yes, you could create such a script. If you have the AD module installed take a look at how to use Get-ADGroupMember and start there. Use the forums at PowerShell.org for additional help with your script.

  6. John Edward Strode says:
    October 26, 2018 at 5:27 pm

    Jeff,

    Thank you for publishing a script for checking the system disk free space. I was able to extend it to look at additional properties such a space available in several key folders to create a report showing where files can be deleted. I would like to alter the output from custom properties to an array of PSCustomObjects. So far my attempts have ended in failure. Any insight you could provide would be very helpful.
    Thanks!
    John Edward Strode

    1. Jeffery Hicks says:
      October 27, 2018 at 3:52 pm

      Your best bet is to post what you are trying to do in the forums at PowerShell.org.

  7. Marc Esteve says:
    December 14, 2018 at 9:14 am

    Hello Jeffery,

    thank you for the script, I found it very useful, and I’m already making some customizations.

    However, I experienced some problems with the gradient in the bar displaying the remaining disk space.
    Debugging I found that the line
    [int]$start = $html.table.tr[$i].td[-1]
    was sometimes doing a wrong conversion because of the decimal separator of some european countries (E.g “23,5” in Spanish culture was converted to 235 when doing the cast to int, Therefore, the bar displayed a free space of 235% filling all the bar in green.)

    So I replaced the line with
    $start = [int][System.Math]::Truncate([System.decimal]::Parse($html.table.tr[$i].td[-1]))
    which use operations that take into account the current culture.

    I hope this may be of some help to some one

    Best regards
    Marc

    1. Jeffery Hicks says:
      December 15, 2018 at 10:02 am

      That’s the kind of thing that is very difficult for me to catch. Thanks.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2026 The Lonely Administrator | Powered by SuperbThemes!
%d