Exercise: The PC Health Report

Finish a module that makes a one-page health report for a Windows PC, with its disks in gigabytes, its restarts in plain words and everything on one web page, gathered with Get-CimInstance and Get-WinEvent -FilterHashtable, while a Pester check tries it with stand-in objects instead of your real PC.

Journeyman · PowerShell · Operating System · Updated

Every help desk has a version of this: before anyone looks at a slow or crashing PC, someone runs a health check. Which Windows, how long since the last restart, how full the disks are, and whether it restarted on its own lately. This exercise builds that check as a module that writes a one-page report you could email to the person who asked. HealthReport.psm1 runs, but its report isn't one you'd hand to anyone yet. Your job is to finish it with this chapter's commands, and a Pester check tries it on stand-in objects and tells you which jobs are done.

This exercise is Windows only, like the chapter.

Get the exercise code

Open this lesson's GitHub repository, github.com/ask-codey/exercise-powershell-the-pc-health-report, also linked from the Exercise box beside the lesson. Click Code, then Download ZIP, and unzip it into your terminal-practice folder. Or clone it with Git.

The folder holds:

  • HealthReport.psm1: the report's commands, for you to finish.
  • answers.txt: three questions, each with a numbered line for your answer.
  • Check.Tests.ps1: the check. You don't need to change it.

What to do

Open PowerShell 7 in the exercise folder, the one with answers.txt in it, and open it in VS Code with code .. Load the module and try one of its commands on your C: drive:

Import-Module .\HealthReport.psm1 -Force
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'" | ConvertTo-DiskReport
C: 865301544960 of 1999288397824 bytes free

Your numbers are your own disk's. Then make the whole report with Invoke-HealthReport -Path .\health-report.html and open it with Invoke-Item .\health-report.html: it takes a few seconds, may print red lines about a resource type while it reads every event in the System log, and the page in your browser has one table of sentences and no heading. After every change you save, run Import-Module .\HealthReport.psm1 -Force again.

  1. Disks in gigabytes. ConvertTo-DiskReport hands back an object for each disk, with Drive, SizeGB, FreeGB, PercentFree and a Status of Low under 15 percent free.
  2. Restarts in plain words. ConvertTo-RestartReport hands back the day, the event ID and what it means, and leaves out any event that isn't one of the five restart IDs.
  3. Gather only what you need. Invoke-HealthReport asks for the disks inside the PC only, reads the restart events of the last 30 days with Get-WinEvent -FilterHashtable, and makes a report even when there were none.
  4. One page, three parts. New-HealthReport puts three tables, This PC, Disks and Restarts, under one heading on one page, with a low disk's cell marked so it shows in red.

The README in the folder says each job in detail, with the five meanings to use. Then answer the three questions in answers.txt, using The Registry as a Drive, Users and Groups on This PC and A New PC from One File: winget export and import.

Check your work

The check uses Pester. If you haven't installed it yet, install it once:

Install-PSResource Pester

Then, from the exercise folder:

Invoke-Pester

At first most tests fail. That's expected: each job you finish turns its tests green. A failing test names the job and says what to look at, for example Expected 'Low', because a disk under 15 percent free should say Low.

The check never reads your own PC. Your disks, your restarts and your Windows version are different from everyone else's, so a test that read them couldn't know the right answer. Instead it hands your commands stand-in objects: made-up disks, events and Windows facts with the same property names as the real ones, such as a C: drive of 512 GB with 50 GB free. Your commands can't tell the difference, because they only read the properties. For Invoke-HealthReport, Pester's Mock stands in for Get-CimInstance and Get-WinEvent and notes how they were called, so it can check that you asked for -FilterHashtable with the System log and the five IDs.

If PowerShell says the check can't be loaded because it is not digitally signed, Windows has marked the downloaded files as coming from the internet: from the exercise folder, run Get-ChildItem -Recurse | Unblock-File once, then Invoke-Pester again.

Hints

  • Bytes to gigabytes: divide by 1GB and round with [math]::Round(..., 1), as in Your Computer's Facts: Get-CimInstance.
  • The five IDs and how to read them are in Event Logs: Why Did It Restart? A hashtable of ID and meaning, from Lists and Lookups: Arrays and Hashtables, keeps the meanings in one place.
  • Nothing found is normal: -ErrorAction SilentlyContinue turns No events were found into an empty answer.
  • Three tables, one page: ConvertTo-Html -Fragment makes a table alone, and -PostContent puts more HTML after the first table, as in Reports: ConvertTo-Html and Out-GridView.

When you're done

Every test is green, and Pester's last line says:

Tests Passed: 18, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0

Load the module again and try the two commands on your own PC:

Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'" | ConvertTo-DiskReport
Get-WinEvent -FilterHashtable @{ LogName = 'System'; Id = 41, 1074, 6005, 6006, 6008 } -MaxEvents 3 | ConvertTo-RestartReport
Drive       : C:
SizeGB      : 1862
FreeGB      : 805.9
PercentFree : 43
Status      : OK


Date         Id Meaning
----         -- -------
2026-11-03 6005 Windows started
2026-11-03 6006 Windows shut down cleanly
2026-11-03 1074 A person or a program asked for a restart or shutdown

Then run Invoke-HealthReport -Path .\health-report.html and open the page: it takes a second now, and shows This PC, Disks and Restarts under one heading. The report describes your own PC, so look it over before you send it to anyone; the repo's .gitignore already keeps it out of what you hand in.

Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

  1. On GitHub, click +, then New repository. Name it (for example exercise-powershell-the-pc-health-report), choose Public, and click Create repository. Leave out the README: your folder already has one.

  2. In a terminal in your exercise folder (PowerShell works), send your work to your new repo. If you downloaded the ZIP:

    git init -b main
    git add .
    git commit -m "My solution"
    git remote add origin https://github.com/your-name/exercise-powershell-the-pc-health-report.git
    git push -u origin main
    

    If you cloned the starter instead, point your copy at your own repo, then commit and push:

    git remote set-url origin https://github.com/your-name/exercise-powershell-the-pc-health-report.git
    git add .
    git commit -m "My solution"
    git push -u origin main
    
  3. Paste your repo's address, such as https://github.com/your-name/exercise-powershell-the-pc-health-report, into Submit your exercise on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

So what

A health check is the chapter in one page: facts from CIM, the story from the event log, and a report someone else can read. Because each piece hands back objects, a test can hand it stand-ins, and the same module works on every PC you look after.

Key terms

Related