Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Import-Module $env:SyncroModule -DisableNameChecking
- #Requires -Version 3.0
- <# Version 1.1
- .DESCRIPTION
- Obtain and evaluate SMART data from drives and alert based on ID value thresholds.
- Uses WMI so no outside tools are needed but ome hardware/configuration may not be compatible.
- The threshold values used below are guesstimates as to what might be concerning. Sometimes
- manufacturers use the same attribute number for different purposes, calculate things differently,
- or use Worst vs RawValue. If you come across these exceptions, please report them or do a pull request
- so the script can improve. Don't take any one value as critical and adjust as you feel appropreiate for
- your environment and risk level, or even remove attributes from monitoring entirely.
- .NOTES
- Created by Isaac Good with data processing function from https://github.com/Fantastitech/GetSmartWin/blob/master/getsmartwin.ps1
- v1.0 - 2018-11-05
- v1.1 - 2022-02-25
- Added - description, changlog and comments
- Added - if statements for SSD and spinner specific IDs
- Changed - split out ID 233 for Intel (and maybe others?) as they use Worst value instead of RawValue
- #>
- # If this is a virtual machine, we don't need to continue
- $Computer = Get-CimInstance -ClassName 'Win32_ComputerSystem'
- if ($Computer.Model -like 'Virtual*') {
- exit
- }
- # Clear our variable so we have good output when testing
- $Warnings = @()
- # Grab the instance names for disks that have WMI SMART data available
- # This is where the "Not supported" error can be generated from, which we check for later
- $disks = (Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_FailurePredictStatus' | Select-Object 'InstanceName').InstanceName
- foreach ($disk in $disks) {
- # Since MSStorageDriver_FailurePredictStatus and Get-PhysicalDisk don't share any values to
- # uniquely identify a disk so we can check if SSD, we have to go through an intermediate step
- # of getting the serial number to match against. Maybe there's a better way that I'm missing. #>
- # Strip instance name down to a value we can match against
- $product = [regex]::Matches($disk,"(?<=Prod_).*(?=\\)").Value
- # Grab the serial for the disk that matches the instance name
- $serial = (Get-CimInstance -ClassName Win32_DiskDrive | Where-Object { $_.PNPDeviceID -match "$product"}).SerialNumber
- # Use the serial to check if the disk is an SSD
- $ssd = Get-PhysicalDisk | Where-Object { $_.SerialNumber -eq $serial } | Where-Object -Property MediaType -eq SSD
- # Retrieve SMART data
- $SmartData = (Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_ATAPISMartData' | Where-Object 'InstanceName' -eq $disk)
- [Byte[]]$RawSmartData = $SmartData | Select-Object -ExpandProperty 'VendorSpecific'
- # Starting at the third number (first two are irrelevant)
- # get the relevant data by iterating over every 12th number
- # and saving the values from an offset of the SMART attribute ID
- [PSCustomObject[]]$Output = for ($i = 2; $i -lt $RawSmartData.Count; $i++) {
- if (0 -eq ($i - 2) % 12 -and $RawSmartData[$i] -ne 0) {
- # Construct the raw attribute value by combining the two bytes that make it up
- [Decimal]$RawValue = ($RawSmartData[$i + 6] * [Math]::Pow(2, 8) + $RawSmartData[$i + 5])
- $InnerOutput = [PSCustomObject]@{
- DiskID = $disk
- ID = $RawSmartData[$i]
- #Flags = $RawSmartData[$i + 1]
- #Value = $RawSmartData[$i + 3]
- Worst = $RawSmartData[$i + 4]
- RawValue = $RawValue
- }
- $InnerOutput
- }
- }
- # Display table of values
- $Output | Sort-Object ID | Out-String
- # Spinner-specific ID's
- if (-not $ssd) {
- # Spin Retry Count
- $Warnings += $Output | Where-Object ID -eq 10 | Where-Object RawValue -ne 0 | Format-Table
- # Recalibration Retries
- $Warnings += $Output | Where-Object ID -eq 11 | Where-Object RawValue -ne 0 | Format-Table
- # High Fly Writes
- $Warnings += $Output | Where-Object ID -eq 189 | Where-Object RawValue -ne 0 | Format-Table
- }
- # Reallocated Sectors Count / Retired NAND Blocks
- $Warnings += $Output | Where-Object ID -eq 5 | Where-Object RawValue -gt 1 | Format-Table
- # Spare Blocks Available
- $Warnings += $Output | Where-Object ID -eq 16 | Where-Object RawValue -lt 100 | Format-Table
- # Remaining Spare Blocks
- $Warnings += $Output | Where-Object ID -eq 17 | Where-Object RawValue -lt 100 | Format-Table
- # Unexpected Power Loss Count (Unsafe Shutdowns Count on PCIe SSDs)
- $Warnings += $Output | Where-Object ID -eq 174 | Where-Object RawValue -gt 300 | Format-Table
- # Used Reserved Block Count Total
- $Warnings += $Output | Where-Object ID -eq 178 | Where-Object RawValue -gt 1 | Format-Table
- # Used Reserved Block Count Total
- $Warnings += $Output | Where-Object ID -eq 179 | Where-Object RawValue -gt 1 | Format-Table
- # Unused Reserved Block Count or Percentage Remaining (Available Spare Blocks on PCIe SSDs)
- $Warnings += $Output | Where-Object ID -eq 180 | Where-Object RawValue -lt 30 | Format-Table
- # Erase Failure Count
- $Warnings += $Output | Where-Object ID -eq 182 | Where-Object RawValue -gt 1 | Format-Table
- # SATA Downshift Error Count or Runtime Bad Block (may indicate bad cable)
- $Warnings += $Output | Where-Object ID -eq 183 | Where-Object RawValue -gt 2 | Format-Table
- # End-to-End error / IOEDC
- $Warnings += $Output | Where-Object ID -eq 184 | Where-Object RawValue -ne 0 | Format-Table
- # Reported Uncorrectable Errors
- $Warnings += $Output | Where-Object ID -eq 187 | Where-Object RawValue -gt 1 | Format-Table
- # Command Timeout
- $Warnings += $Output | Where-Object ID -eq 188 | Where-Object RawValue -gt 1 | Format-Table
- # Temperature Celcius
- $Warnings += $Output | Where-Object ID -eq 194 | Where-Object RawValue -gt 50 | Format-Table
- # Reallocation Event Count
- $Warnings += $Output | Where-Object ID -eq 196 | Where-Object RawValue -gt 1 | Format-Table
- # Current Pending Sector Count
- $Warnings += $Output | Where-Object ID -eq 197 | Where-Object RawValue -ne 0 | Format-Table
- # Uncorrectable Sector Count
- $Warnings += $Output | Where-Object ID -eq 198 | Where-Object RawValue -ne 0 | Format-Table
- # UltraDMA CRC Error Count
- $Warnings += $Output | Where-Object ID -eq 199 | Where-Object RawValue -ne 0 | Format-Table
- # Soft Read Error Rate
- $Warnings += $Output | Where-Object ID -eq 201 | Where-Object Worst -lt 95 | Format-Table
- # SSD-specific ID's
- if ($ssd) {
- # SSD Percentage Lifetime Used % (Crucial/Micron)
- $Warnings += $Output | Where-Object ID -eq 202 | Where-Object Worst -gt 95 | Format-Table
- # SSD RAIN Successful Recovery Page Count (Crucial Brand)
- $Warnings += $Output | Where-Object ID -eq 210 | Where-Object Worst -gt 10 | Format-Table
- # SSD Life Left %
- $Warnings += $Output | Where-Object ID -eq 231 | Where-Object Worst -lt 20 | Format-Table
- # SSD Endurance Remaining or Available Reserved Space %
- $Warnings += $Output | Where-Object ID -eq 232 | Where-Object Worst -lt 20 | Format-Table
- # SSD Media Wear Out Indicator %
- if ($disk -match 'intel') {
- $Warnings += $Output | Where-Object ID -eq 233 | Where-Object Worst -lt 20 | Format-Table
- }
- else {
- $Warnings += $Output | Where-Object ID -eq 233 | Where-Object RawValue -lt 20 | Format-Table
- }
- }
- } # End foreach
- # Check FailurePredictStatus
- $Warnings += Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_FailurePredictStatus' |
- Select-Object InstanceName, PredictFailure, Reason |
- Where-Object {$_.PredictFailure -ne $False} | Format-Table
- # Check general disk status and health
- $Warnings += Get-PhysicalDisk |
- Select-Object FriendlyName, Size, MediaType, OperationalStatus, HealthStatus |
- Where-Object {$_.OperationalStatus -ne 'OK' -or $_.HealthStatus -ne 'Healthy'} | Format-Table
- if ($Warnings) {
- $Warnings = $warnings | Out-String
- $Warnings
- Rmm-Alert -Category 'Monitor - Drive SMART Values' -Body "$Warnings"
- Exit 1
- }
- if ($Error) {
- if ($Error -match "Not supported") {
- ($notsup = "Not supported: You may need to switch from ACHI to RAID/RST mode, see the link for how to do this non-destructively: https://www.top-password.com/blog/switch-from-raid-to-ahci-without-reinstalling-windows/")
- Rmm-Alert -Category 'Monitor - Drive SMART Values' -Body "$notsup"
- }
- Rmm-Alert -Category 'Monitor - Drive SMART Values' -Body "$error"
- exit 1
- }
- Close-Rmm-Alert -Category "Monitor - Drive SMART Values"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement