Monitoring with PowerShell: Monitoring SMART status using SmartCTL.

Some time ago I wrote a blog about monitoring SMART status with CrystalDiskInfo. After bringing this script over to our production RMM environment everything seemed good. But when I looked a little deeper I found that the script failed on NVME drives. NVME drives handle SMART-Status different from ‘regular’ SATA drives.

This started me on a quest for a solution that also worked on NVME drives. I’ve decided to use SmartMonTools as it has the same benefits as crystaldiskmark – It’s portable, does not require an installation, and is small enough to be downloaded on demand.

The script is fairly straightforward, it downloads the utility from a host, extracts the utility and runs an update for SmartCTL so it can fill in the data correctly. After this for each HDD in the system it will run a compare to the thresholds you’ve setup.

I’ve also had a request for disk monitoring on specifically the available spare count. The script can be edited to monitor this too – that way you can decide your own thresholds over what the manufacturer said is default for the disk.

The script

############ Thresholds #############
$PowerOnTime = 35063 #about 4 years constant runtime.
$PowerCycles = 4000 #4000 times of turning drive on and off
$Temperature = 60 #60 degrees celcius
############ End Thresholds #########
$DownloadURL = "/uploads/2020/02/Smartmontools.zip"
$DownloadLocation = "$($Env:ProgramData)\SmartmonTools"
try {
    $TestDownloadLocation = Test-Path $DownloadLocation
    if (!$TestDownloadLocation) { new-item $DownloadLocation -ItemType Directory -force }
    $TestDownloadLocationZip = Test-Path "$DownloadLocation\Smartmontools.zip"
    if (!$TestDownloadLocationZip) { Invoke-WebRequest -UseBasicParsing -Uri $DownloadURL -OutFile "$($DownloadLocation)\Smartmontools.zip" }
    $TestDownloadLocationExe = Test-Path "$DownloadLocation\smartctl.exe"
    if (!$TestDownloadLocationExe) { Expand-Archive "$($DownloadLocation)\Smartmontools.zip" -DestinationPath $DownloadLocation -Force }
}
catch {
    write-host "The download and extraction of SMARTCTL failed. Error: $($_.Exception.Message)"
    exit 1
}
#update the smartmontools database
start-process -filepath "$DownloadLocation\update-smart-drivedb.exe" -ArgumentList "/S" -Wait
#find all connected HDDs
$HDDs = (& "$DownloadLocation\smartctl.exe" --scan -j | ConvertFrom-Json).devices
$HDDInfo = foreach ($HDD in $HDDs) {
    (& "$DownloadLocation\smartctl.exe" -t short -a -j $HDD.name) | convertfrom-json
}
$DiskHealth = @{}
#Checking SMART status
$SmartFailed = $HDDInfo | Where-Object { $_.Smart_Status.Passed -ne $true }
if ($SmartFailed) { $DiskHealth.add('SmartErrors',"Smart Failed for disks: $($SmartFailed.serial_number)") }
#checking Temp Status
$TempFailed = $HDDInfo | Where-Object { $_.temperature.current -ge $Temperature }
if ($TempFailed) { $DiskHealth.add('TempErrors',"Temperature failed for disks: $($TempFailed.serial_number)") }
#Checking Power Cycle Count status
$PCCFailed = $HDDInfo | Where-Object { $_.Power_Cycle_Count -ge $PowerCycles }
if ($PCCFailed ) { $DiskHealth.add('PCCErrors',"Power Cycle Count Failed for disks: $($PCCFailed.serial_number)") }
#Checking Power on Time Status
$POTFailed = $HDDInfo | Where-Object { $_.Power_on_time.hours -ge $PowerOnTime }
if ($POTFailed) { $DiskHealth.add('POTErrors',"Power on Time for disks failed : $($POTFailed.serial_number)") }

if (!$DiskHealth) { $DiskHealth = "Healthy" }

And that’s it! as always, Happy PowerShelling.

Recent Articles

Automating with PowerShell: making stolen tokens useless with Global Secure Access

Last week I watched Merill Fernando talk to Alex Pavlovsky and Marilee Tuscak from the Entra team about something I’d kinda put under the “needs a GSA licence” branch and i’d check it out later, turns out that like most people, I half-assed the documentation and it turns out it doesn’t. There’s two features that come with any P1 license; Compliant network check and Source IP Restoration. So BP, P1, or even frontline worker licenses already have this.

CIPP ❤️ #IntuneForMSPs

We’re Joining #IntuneForMSPs 🎉

Being invited by Microsoft to join a global initiative is a big moment for us, and we want to be clear about why it matters. #IntuneForMSPs is Microsoft’s program to help MSPs deliver Microsoft 365, Intune, and Copilot services at scale, and CIPP is now part of it, bringing the largest MSP community in the channel directly to Microsoft.

The return of CyberDrain CTF

CyberDrain CTF returns! (and so do I!)

It’s been since september that I actually picked up a digital pen equivalent and wrote anything down. This was due to me being busy with life but also my side projects like CIPP. I’m trying to get back into the game of scripting and blogging about these scripts. There’s still so much to automate and so little time, right? ;)