Мониторинг состояния жесткого диска по S.M.A.R.T.
15 Sep 2017В процессе ...
Скрипт сбора показаний S.M.A.R.T. для Icinga2:
<#
icinga2scripts
Version 1.0
Description: Скрипт для Icinga 2 - Информация о состоянии дисков по данным S.M.A.R.T.
Pavel Satin (c) 2016
pslater.ru@gmail.com
#>
param(
[Parameter(Mandatory=$True)]
[string] $Drive,
[int[]] $AttributeId,
[string[]] $Property,
[switch] $FriendlyOutput)
# parses attribute table in smartctl output and builds an object
#[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3
Try {
$architecture = ''
if ([IntPtr]::Size -eq 4) {
$architecture = "x86"
$smart = [string[]](C:\ProgramData\icinga2\Scripts\Icinga2\bin\smartctl_x86.exe -A $Drive)
} else {
$architecture = "x86_64"
$smart = [string[]](C:\ProgramData\icinga2\Scripts\Icinga2\bin\smartctl.exe -A $Drive)
}
$attributes=@()
foreach ($s in $smart) {
if ($s -match '^\s*(\d+)\s+(\w+)\s+(\w+)\s+(\d+)\s+(\d+)\s+([\d-]+)\s+([\w-]+)\s+(\w+)\s+([\w-]+)\s+(\d+)') {
$o = new-object -Typename PSObject
add-member -in $o -m NoteProperty -name 'ID' -value ([int]$matches[1])
add-member -in $o -m NoteProperty -name 'Name' -value $matches[2]
add-member -in $o -m NoteProperty -name 'Flag' -value $matches[3]
add-member -in $o -m NoteProperty -name 'Value' -value ([int]$matches[4])
add-member -in $o -m NoteProperty -name 'Worst' -value ([int]$matches[5])
add-member -in $o -m NoteProperty -name 'Threshold' -value ([int]$matches[6])
add-member -in $o -m NoteProperty -name 'Type' -value $matches[7]
add-member -in $o -m NoteProperty -name 'Updated' -value $matches[8]
add-member -in $o -m NoteProperty -name 'WhenFailed' -value $matches[9]
add-member -in $o -m NoteProperty -name 'Raw' -value ([int64]$matches[10])
$attributes += $o
}
}
$devinfo = [string[]](C:\ProgramData\icinga2\Scripts\Icinga2\bin\smartctl.exe -i $Drive)
$HDD_smart = "Disk $Drive - OK`n"
foreach ($s2 in $devinfo) {
$HDD_smart = $HDD_smart + $s2 + "`n"
}
for ($i = 0; $i -lt 15; $i++)
{
$HDD_smart = $HDD_smart + "$(($attributes)[$i].Name) : $(($attributes)[$i].Raw)`n"
$HDD_smart_perfdata = $HDD_smart_perfdata + "$(($attributes)[$i].Name)=$(($attributes)[$i].Raw);; "
}
Write-Host $HDD_smart " | " $HDD_smart_perfdata
[System.Environment]::Exit($returnStateOK)
} Catch {
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-Host $ErrorMessage
[System.Environment]::Exit($returnStateCritical)
}
Вариант 2
WMI классы:
MSStorageDriver_FailurePredictEvent
MSStorageDriver_FailurePredictFunction
MSStorageDriver_FailurePredictData
MSStorageDriver_FailurePredictThresholds
MSStorageDriver_FailurePredictStatus
function Convert-DECtoHEX {
param($DEC)
foreach ($value in $DEC) {
$c = "{0:x}" -f [Int]$value
$s=$c.ToString()
if ($s.length -eq 1) {
"0$s"
} else {
$s
}
}
}
function Convert-HEXtoDEC {
param($HEX)
foreach ($value in $HEX) {
[Convert]::ToInt32($value, 16)
}
}
$strComputer = "."
$fpdDisks = get-wmiObject -class "MSStorageDriver_FailurePredictData" -namespace "root\WMI" -comp $strComputer
foreach ($fpd1Disk in $fpdDisks) {
"`nActive: " + $fpd1Disk.Active
"InstanceName: " + $fpd1Disk.InstanceName
"`nVendorSpecific: " #+ $fpd1Disk.VendorSpecific
$byteString = $fpd1Disk.VendorSpecific
$i = 0
foreach($byte in $byteString) {
$i = $i + 1
$cByte = $byte #Convert-DECtoHEX($byte)
if ($i -eq 1) {
$pByte = $cByte; continue
} elseif ($i -eq 2) {
$tmp1 = Convert-DECtoHEX($pByte)
$tmp2 = Convert-DECtoHEX($cByte)
$tmp = $tmp1 + $tmp2
$tmp = Convert-HEXtoDEC($tmp)
write-host "`nhdd smart data length: $tmp"
$pByte = $cByte
} elseif (($i-3)%12 -eq 0) {
$tmp2 = Convert-DECtoHEX($cByte)
if ($tmp2 -eq "00") { break }
write-host "`n$tmp2 " -nonewline
$pByte = $cByte
} elseif ( (($i-3)%12 -eq 5) -or (($i-3)%12 -eq 7) -or (($i-3)%12 -eq 9) ) {
$pByte = $cByte; continue
} elseif ( (($i-3)%12 -eq 6) -or (($i-3)%12 -eq 8) -or (($i-3)%12 -eq 10) ) {
$tmp1 = Convert-DECtoHEX($pByte)
$tmp2 = Convert-DECtoHEX($cByte)
$tmp = $tmp2 + $tmp1
$tmp = Convert-HEXtoDEC($tmp)
write-host "$tmp " -nonewline
$pByte = $cByte
} else {
$tmp2 = $cByte
write-host "$tmp2 " -nonewline
$pByte = $cByte
}
}
}
# $fptDisks = get-wmiObject -class "MSStorageDriver_FailurePredictThresholds" -namespace "root\WMI" -comp $strComputer
# foreach($fpt1Disk in $fptDisks){
# "`n`nVendorSpecific: " #+ $fpt1Disk.VendorSpecific
# $byteString = $fpt1Disk.VendorSpecific
# # $byteString
# $i = 0
# foreach($byte in $byteString) {
# $i = $i + 1
# $cByte = $byte #Convert-DECtoHEX($byte)
# if ($i -eq 1) {
# $pByte = $cByte; continue
# } elseif ($i -eq 2) {
# $tmp1 = Convert-DECtoHEX($pByte)
# $tmp2 = Convert-DECtoHEX($cByte)
# $tmp = $tmp1 + $tmp2
# $tmp = Convert-HEXtoDEC($tmp)
# write-host "`nhdd smart thresholds length: $tmp"
# $pByte = $cByte
# } elseif (($i-3)%12 -eq 0) {
# $tmp2 = Convert-DECtoHEX($cByte)
# if ($tmp2 -eq "00") { break }
# write-host "`n$tmp2 " -nonewline
# $pByte = $cByte
# } elseif ( (($i-3)%12 -eq 5) -or (($i-3)%12 -eq 7) -or (($i-3)%12 -eq 9) ) {
# $pByte = $cByte; continue
# } elseif ( (($i-3)%12 -eq 6) -or (($i-3)%12 -eq 8) -or (($i-3)%12 -eq 10) ) {
# $tmp1 = Convert-DECtoHEX($pByte)
# $tmp2 = Convert-DECtoHEX($cByte)
# $tmp = $tmp2 + $tmp1
# $tmp = Convert-HEXtoDEC($tmp)
# write-host "$tmp " -nonewline
# $pByte = $cByte
# } else {
# $tmp2 = $cByte
# write-host "$tmp2 " -nonewline
# $pByte = $cByte
# }
# }
# }
Вариант 3
- 05 Reallocated Sector Count
- 187 (BB) Reported Uncorrected Sector Count (UNC Error)
- 197 (С5) Current Pending Sector Count
- 198 (С6) Offline Uncorrectable Sector Count (Uncorrectable Sector Count)
- 200 (С8) Write Error Rate (MultiZone Error Rate)
$smart = gwmi -Namespace root\WMI -Class MSStorageDriver_FailurePredictData
# foreach ($smart in $smartdisks) {
if ($smart.VendorSpecific.Length -gt 0) {
$smart = @($smart)
}
for ($n = 0; $n -lt $smart.Length; $n++) {
$result = @()
for ($i = 2; $i -lt $smart[$n].VendorSpecific.Length; $i += 12) {
$obj = New-Object PSObject
$obj | Add-Member -MemberType NoteProperty -Name "AttrID" -Value $smart[$n].VendorSpecific[$i];
$obj | Add-Member -MemberType NoteProperty -Name "Raws" $smart[$n].VendorSpecific[($i+5)..($i+10)];
$result += $obj
# $result += [pscustomobject] @{
# AttrID = $smart[$n].VendorSpecific[$i];
# Raws = $smart[$n].VendorSpecific[($i+5)..($i+10)];
# }
}
Write-Host "Drive: $($smart[$n].InstanceName)"
}
# }
$result
# $RawIndex = 5,187,197,198,200
# $IsSmartBad = $false
# for ($n = 0; $n -lt $smart.Length; $n++) {
# for ($i = 2; $i -lt $smart[$n].VendorSpecific.Length; $i += 12) {
# if ($RawIndex -contains $smart[$n].VendorSpecific[$i]) {
# $smart.VendorSpecific[($i+5)..($i+10)] | Where {$_ -gt 0} | Foreach { $IsSmartBad = $true }
# Write-Host "RAW-значение аттрибутов 05 или 187 или 197 или 198 или 200 больше нуля"
# Write-Host "Аттрибут: $RawIndex"
# }
# }
# }
Вариант 4
Get-Disk | foreach { $_ | Get-StorageReliabilityCounter | Format-List }
Вариант 5
function get-diskstatus {
[CmdletBinding()]
param (
[string]$computername = $env:COMPUTERNAME
)
$items = "Unknown1","Unknown2", "Attribute", "Status", "Unknown3", "Value", "Worst", "Raw1", "Raw2", "Unknown4","Unknown5","Unknown6"
$dataDrives = Get-WmiObject -Namespace root\wmi -Class MSStorageDriver_FailurePredictData -ComputerName $computername
foreach ($data in $dataDrives) {
#$data | select InstanceName, Active
$values = $data.VendorSpecific
$flb = $values.Count - ($values.Count % 12) -1
for ($i = 0; $i -le $flb-11; $i += 12 ){
$obj = New-Object -TypeName PSObject
for($j = 0; $j -le 11; $j++) {
$obj | Add-Member -MemberType Noteproperty -Name $($items[$j]) -Value $($values[$i + $j])
}
$obj
}
}
}
get-diskstatus | ft * –a
Вариант 6
function test-diskstatus {
[CmdletBinding()]
param (
[string]$computername = $env:COMPUTERNAME
)
Get-WmiObject -Namespace root\wmi -Class MSStorageDriver_FailurePredictStatus -ComputerName $computername | select InstanceName, Active, PredictFailure, Reason
}
test-diskstatus
Вариант 7
В Windows 8 и выше ...
PS C:\> $(Get-PhysicalDisk | Select *)[0]
Usage : Auto-Select
OperationalStatus : OK
HealthStatus : Healthy
BusType : SATA
CannotPoolReason : Insufficient Capacity
SupportedUsages : {Auto-Select, Manual-Select, Hot Spare, Retired...}
MediaType : HDD
ObjectId : {1}\\DC01E\root/Microsoft/Windows/Storage/Providers_v2\SPACES_PhysicalDisk.ObjectId=
"{75d7402b-467c-11e4-80b0-806e6f6e6963}:PD:{7a493ea2-4804-5de8-cbfc-d2ec3f37bf20}"
PassThroughClass :
PassThroughIds :
PassThroughNamespace :
PassThroughServer :
UniqueId : SCSI\Disk&Ven_WDC&Prod_WD1003FBYX-01Y7B\4&2e5a6532&0&010000:DC01E
AllocatedSize : 1000204886016
CanPool : False
Description :
DeviceId : 1
EnclosureNumber :
FirmwareVersion : 01.01V01
FriendlyName : PhysicalDisk1
IsIndicationEnabled :
IsPartial : True
LogicalSectorSize : 512
Manufacturer :
Model : WDC WD1003FBYX-01Y7B0
OtherCannotPoolReasonDescription :
PartNumber :
PhysicalLocation :
PhysicalSectorSize : 512
SerialNumber : WD-WCAW33014128
Size : 1000204886016
SlotNumber :
SoftwareVersion :
SpindleSpeed : 4294967295
PSComputerName :
CimClass : ROOT/Microsoft/Windows/Storage:MSFT_PhysicalDisk
CimInstanceProperties : {ObjectId, PassThroughClass, PassThroughIds, PassThroughNamespace...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
PS C:\> Get-PhysicalDisk | ft -AutoSize DeviceId,Model,MediaType,BusType,Size
DeviceId Model MediaType BusType Size
-------- ----- --------- ------- ----
1 WDC WD1003FBYX-01Y7B0 HDD SATA 1000204886016
2 WDC WD1002FBYS-02A6B0 HDD SATA 1000204886016
3 WDC WD1003FBYX-01Y7B0 HDD SATA 1000204886016
0 WDC WD10EZRZ-00Z5HB0 HDD SATA 1000204886016
Вариант 8
function Get-FailingDrive {
<#
.SYNOPSIS
Checks for any potentially failing drives and reports back drive information.
.DESCRIPTION
Checks for any potentially failing drives and reports back drive information. This only works
against local hard drives using SMART technology. Reason values and their meanings can be found
here: http://en.wikipedia.org/wiki/S.M.A.R.T#Known_ATA_S.M.A.R.T._attributes
.PARAMETER Computer
Remote or local computer to check for possible failed hard drive.
.PARAMETER Credential
Provide alternate credential to perform query.
.NOTES
Author: Boe Prox
Version: 1.0
http://learn-powershell.net
.EXAMPLE
Get-FailingDrive
WARNING: ST9320320AS ATA Device may fail!
MediaType : Fixed hard disk media
InterFace : IDE
DriveName : ST9320320AS ATA Device
Reason : 1
SerialNumber : 202020202020202020202020533531584e5a4d50
FailureImminent : True
Description
-----------
Command ran against the local computer to check for potential failed hard drive.
#>
[cmdletbinding()]
Param (
[parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[string[]]$Computername = $ENV:Computername,
[parameter()]
[System.Management.Automation.PSCredential]$Credential
)
Begin {
$queryhash = @{}
$BadDriveHash = @{}
}
Process {
ForEach ($Computer in $Computername) {
[regex]$regex = "(?<DriveName>\w+\\[A-Za-z0-9_]*)\w+"
Try {
Write-Verbose "Checking for failed drives"
Get-WmiObject -NameSpace "root\wmi" -Class MSStorageDriver_FailurePredictStatus -ComputerName $Computer | ForEach {
Write-Verbose "Drive: $($_.InstanceName)"
$drive = $regex.Matches($_.InstanceName) | ForEach {$_.Groups['DriveName'].value}
Write-Verbose "Gathering more information about failing drive"
$BadDrive = Get-WmiObject -NameSpace "root\cimv2" -Class Win32_DiskDrive -ComputerName $Computer | Where {$_.PNPDeviceID -like "$drive*"}
If ($BadDrive) {
Write-Warning "$($BadDriveHash['Computername']): $($BadDrive.Model) may fail!"
New-Object PSObject -Property @{
DriveName = $BadDrive.Model
FailureImminent = $_.PredictFailure
Reason = $_.Reason
MediaType = $BadDrive.MediaType
SerialNumber = $BadDrive.SerialNumber
InterFace = $BadDrive.InterfaceType
Partitions = $BadDrive.Partitions
Size = $BadDrive.Size
Computer = $BadDriveHash['Computername']
}
}
}
} Catch {
Write-Warning "$($Error[0])"
}
}
}
}
Get-FailingDrive -ComputerName l204.pshome.local -Verbose
Критичные атрибуты
Raw Read Error Rate — частота ошибок при чтении данных с диска, происхождение которых обусловлено аппаратной частью диска.
Spin Up Time — время раскрутки пакета дисков из состояния покоя до рабочей скорости. При расчете нормализованного значения (Value) практическое время сравнивается с некоторой эталонной величиной, установленной на заводе. Не ухудшающееся немаксимальное значение при Spin Up Retry Count Value = max (Raw равном 0) не говорит ни о чем плохом. Отличие времени от эталонного может быть вызвано рядом причин, например просадка по вольтажу блока питания.
Spin Up Retry Count — число повторных попыток раскрутки дисков до рабочей скорости, в случае если первая попытка была неудачной. Ненулевое значение Raw (соответственно немаксимальное Value) свидетельствует о проблемах в механической части накопителя.
Seek Error Rate — частота ошибок при позиционировании блока головок. Высокое значение Raw свидетельствует о наличии проблем, которыми могут являться повреждение сервометок, чрезмерное термическое расширение дисков, механические проблемы в блоке позиционирования и др. Постоянное высокое значение Value говорит о том, что все хорошо.
Reallocated Sector Count — число операций переназначения секторов. SMART в современных дисках способен произвести анализ сектора на стабильность работы «на лету» и в случае признания его сбойным, произвести его переназначение.
Некритичные атрибуты
Start/Stop Count — полное число запусков/остановов шпинделя. Гарантировано мотор диска способен перенести лишь определенное число включений/выключений. Это значение выбирается в качестве Treshold. Первые модели дисков со скоростью вращения 7200 оборотов/мин имели ненадежный двигатель, могли перенести лишь небольшое их число и быстро выходили из строя.
Power On Hours — число часов проведенных во включенном состоянии. В качестве порогового значения для него выбирается паспортное время наработки на отказ (MTBF). Обычно величина MTBF огромна, и маловероятно, что этот параметр достигнет критического порога. Но даже в этом случае выход из строя диска совершенно не обязателен.
Drive Power Cycle Count — количество полных циклов включения-выключения диска. По этому и предыдущему атрибуту можно оценить, например, сколько использовался диск до покупки.
Temperatue — Здесь хранятся показания встроенного термодатчика. Температура имеет огромное влияние на срок службы диска (даже если она находится в допустимых пределах). Вернее имеет влияние не на срок службы диска а на частоту возникновения некоторых типов ошибок, которые влияют на срок службы.
Current Pending Sector Count — Число секторов, являющихся кандидатами на замену. Они не были еще определенны как плохие, но считывание их отличается от чтения стабильного сектора, так называемые подозрительные или нестабильные сектора.
Uncorrectable Sector Count — число ошибок при обращении к сектору, которые не были скорректированы. Возможными причинами возникновения могут быть сбои механики или порча поверхности.
UDMA CRC Error Rate — число ошибок, возникающих при передаче данных по внешнему интерфейсу. Могут быть вызваны некачественными кабелями, нештатными режимами работы.
Write Error Rate — показывает частоту ошибок происходящих при записи на диск. Может служить показателем качества поверхности и механики накопителя.