Jump to content

Get Power On Hours Hard Disk


ozzy1615
 Share

Recommended Posts

  • Moderators

I am assuming Power On Hours is just the uptime. You can get that from WMI (no error checking in place):

$objWMI = ObjGet("winmgmts:\\.\root\cimv2")
$oUptime = $objWMI.ExecQuery("Select * from Win32_PerfFormattedData_PerfOS_System")
    For $sTime In $oUptime
        ConsoleWrite(($sTime.SystemUpTime / 60) & " minutes" & @CRLF)
    Next

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

On ‎18‎/‎11‎/‎2016 at 5:43 PM, MuffinMan said:

Take a look at ptrex's SMART drive Analysis SMART_WMI.au3 example.  You should be able to get POH data using it.

 

Thanks for the reply man,

Well, this script doesnt show the result that i want:
Untitled.jpg

Im looking for a script that show me the value in hours or hexadecimal.

Link to comment
Share on other sites

Link to comment
Share on other sites

Hello. As I said to handle that in AutoIt you need to traslate tthis code to AutoIt.

http://www.codeproject.com/Articles/16671/Hard-drive-information-using-S-M-A-R-T

I have not free time traslate it. 

An alternative could be using some commandline tools and get the value using AutoIt.

 

 

 

Saludos

 

Link to comment
Share on other sites

Using the external tool Smart.exe from here : http://retired.beyondlogic.org/solutions/smart/smart.htm

#RequireAdmin ; needed
#Include <Array.au3> ; just for _ArrayDisplay

$sSmartPath = @ScriptDir & "\smart.exe"  ; Downloaded from here : http://retired.beyondlogic.org/solutions/smart/smart.htm

; Run Smart.exe and get the result
Local $iPid = Run($sSmartPath, @ScriptDir, @SW_HIDE, 2)
ProcessWaitClose($iPid)
Local $sResult = StdoutRead($iPid)

; Get all infos from the output string
Local $aRegExResult = StringRegExp($sResult, "(?m)^\[[A-F0-9]{2}\]\h(\N+?)\h+(\w+)\h+(\d+)\h+(\d+)\h+(\d+)\h+(-?\d+)\h+(\w+)", 3) ; Parse the elements in an array
If @error Then Exit MsgBox(16, "Error", "No result found")
Local $aSmartInfos = _Array1DTo2D($aRegExResult, 7) ; Converts the 1D array to a 2D array
_ArrayDisplay($aSmartInfos)

; Get the "Power On Hours Count" value :
$iPOHC = StringRegExp($sResult, "Power On Hours Count\N+?(\d+)\h+\w+\R", 1) ; now get the Power On Hours Count value
If @error Then Exit MsgBox(16, "Error", "Unable to retrieve the Power On Hours Count value")
MsgBox(0, "", "Power On Hours Count : " & $iPOHC[0])




; #FUNCTION# ====================================================================================================================
; Name ..........: _Array1DTo2D
; Description ...: Transforms a 1D to a 2D array.
; Syntax ........: _Array1DTo2D($avArray, $iCols[, $iStart = 0[, $iEnd = 0[, $iFlag = 0]]])
; Parameters ....: $avArray             - Array to modify.
;                  $iCols               - Number of columns to transform the array to.
;                  $iStart              - [optional] Index of array to start the transformation. Default is the first element.
;                  $iEnd                - [optional] Index of array to stop the transformation. Default is the last element.
;                  $iFlag               - [optional] If set to 1, the array size must to a multiple of $iCols. Default is 0.
; Return values .: Success : Returns a 2D array
;                  Failure : Returns 0 and sets @error to :
;                    1 - $aArray is not an array
;                    2 - $iStart is greater than $iEnd
;                    3 - $aArray is not a 1D array
;                    4 - $aArray size is not a multiple of $iCols
; Author ........: jguinch
; ===============================================================================================================================
Func _Array1DTo2D($avArray, $iCols, $iStart = 0, $iEnd = 0, $iFlag = 0)

    If $iStart = Default OR $iStart < 0 Then $iStart = 0
    If $iEnd = Default Then $iEnd = 0

    If NOT IsArray($avArray) Then Return SetError(1, 0, 0)
    If UBound($avArray, 0) <> 1 Then Return SetError(3, 0, 0)

    Local $iUBound = UBound($avArray) - 1

    If $iEnd < 1 Then $iEnd = $iUBound
    If $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart > $iEnd Then Return SetError(2, 0, 0)

    Local $iNbRows = ($iEnd - $iStart + 1) / $iCols
    If $iFlag AND IsFloat($iNbRows) Then Return SetError(2, 0, 0)

    Local $aRet[ Ceiling($iNbRows) ][$iCols]
    Local $iCol = 0, $iRow = 0
    For $i = $iStart To $iEnd
        If $iCol = $iCols Then
            $iCol = 0
            $iRow += 1
        EndIf
        $aRet[$iRow][$iCol] = $avArray[$i]
        $iCol += 1
    Next

    Return $aRet
EndFunc

 

Link to comment
Share on other sites

Or you can use the native WMI Console -- Tested on two computers.

#RequireAdmin
Opt('MustDeclareVars', 1)

Local $rtn = GetPOH()
MsgBox(0, 'Result', $rtn)
Exit

;===============================================================================================================
Func GetPOH()
    Local $pid = Run('WMIC /NAMESPACE:\\root\wmi PATH MSStorageDriver_ATAPISmartData', '', @SW_HIDE, 6)
    If @error Or Not $pid Then Return -1

    Local $stdout = ''

    Do
        Sleep(10)
        $stdout &= StdoutRead($pid, 0, 0)
    Until @error

    MsgBox(0, 'Smart Data  (debug)', $stdout)

    ; split headers from data
    Local $a = StringSplit($stdout, @CRLF, 1)
    ; there are 3 sets of curly brackets in the data, we want the second set
    Local $s = StringTrimLeft($a[2], StringInStr($a[2], '{', 0, 2) + 7)
    Local $array, $n, $str

    For $i = 1 To 10
        ; get end position of attribute string
        $n = StringInStr($s, ',', 0, 12) + 1
        ; get the attribute string from data to a separate var
        $str = StringLeft($s, $n)
        ; remove that attribute string from data
        $s = StringTrimLeft($s, $n)
        ; search for attribute 9, which is the POH string
        If Number(StringLeft($str, 1)) = 9 Then
            ; trim to position of the DeviceID string
            $s = StringTrimLeft($a[2], StringInStr($a[2], 'IDE') - 1)
            ; get DeviceID string
            $s = StringLeft($s, StringInStr($s, ' ') - 1) & @CRLF & @CRLF
            ; split the POH string
            $array = StringSplit($str, ',')
            ; get POH calculation
            $s &= Number($array[6]) + (Number($array[7]) * 256) & '  (Power On Hours)'
            ; return the DeviceID and POH
            Return $s
        EndIf
    Next
    Return -2
EndFunc

 

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Very nice @ripdad
Where did you find the information for the way to calculate it ?

Inspired from your code, here is an AutoIt version, without using any external command line (just the WMI object) :

Local $sInstanceName, $aVendorSpecific, $sDiskFriendlyName, $iPoh
Local $oWMI = ObjGet("winmgmts:root\wmi")
Local $oSmartData = $oWMI.ExecQuery("select * from MSStorageDriver_ATAPISmartData")
For $oData In $oSmartData
    $sInstanceName = StringRegExpReplace($oData.InstanceName, "_\d+$", "")
    $aVendorSpecific = $oData.VendorSpecific
    $sDiskFriendlyName = RegRead("HKLM\System\CurrentControlSet\Enum\" & $sInstanceName, "FriendlyName")

    For $i = 2 To UBound($aVendorSpecific) - 1 Step 12
        If $aVendorSpecific[$i] = 9 Then
            $iPoh = Number($aVendorSpecific[$i + 5] + $aVendorSpecific[$i + 6] * 256 + $aVendorSpecific[$i + 7] * 65536)
            MsgBox(0, "", "Power On Hours for " & $sDiskFriendlyName & " : " & $iPoh & @CRLF)
        EndIf
    Next
Next

 

Edited by jguinch
Link to comment
Share on other sites

There is an additional calculation for POH, when the drive exceeds 65536 Hours. It is calculated from the next row (VSD1). Most drives won't make it though. I had one drive that did make it, an 80Gig WD - all the others failed way before that.

Number($array[6]) + (Number($array[7]) * 256) + (Number($array[8]) * 65536)

 

 

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...