В процессе ...

Скрипт сбора показаний 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 — показывает частоту ошибок происходящих при записи на диск. Может служить показателем качества поверхности и механики накопителя.

Таблица 1. Известные S.M.A.R.T. атрибуты

Ссылки