玩转WMI --- 用脚本获取硬盘传感器温度和SMART讯息

来源:互联网 发布:wemall商业版java源码 编辑:程序博客网 时间:2024/05/08 01:35

搜索了一下WMI对象内的Class发现确实有比较方便的类

命名空间root/wmi下MSStorageDriver_ATAPISmartData类的子集VendorSpecific内存放了硬盘内部芯片存储的所有SMART讯息大小为512Bytes。直接提取出来如下:


一堆乱麻。查询了一下SMART讯息相关资料,没有找到直接的spec。但是了解到第1,2个Byte位置代表SMART版本号(如图为10,0)。第3Byte开始往后全部为SMART attributes,每12个Bytes为一组代表一个分类Item,假定如下结构体便于厘清。

        struct 
        {
            char attrib;
            char flags;
            char worst;
            char normal;
            char current;
            char current1;
            char current2;
            char current3;
            char current4;
            char current5;
            char current6;
            char current7;
          }  Attriubtes

维基百科上(http://en.wikipedia.org/wiki/S.M.A.R.T.)有各分类Item的详细定义。

找到我们想要的温度和POH所在的Item ID,如下


  可知第一Byte分别为4,9,194的三个分类Item内存储着Start/Stop Count(硬盘开关机次数),POH(硬盘持续使用时间),Temperature(硬盘内部温度)的资讯。我们按照上述结构体定义就可将温度和POH等想要的讯息解析出来。如果以16进制表示,每12Bytes的分类Item内第7个Bytes代表当前值的高位,第6个Bytes代表当前值的低位。

这里要说明的是S.M.A.R.T定义的所有Item不是每块硬盘都支持的,可能只支持SMART标准内部分Item功能。所以流程上如要严谨化需用到另外一个WMI类MSStorageDriver_FailurePredictThresholds    --- 其可以枚举出本地硬盘所有可用分类Item的首字节ID值。

流程思路已经很清晰,使用脚本实现温度和POH的自动提取方法自然也就很容易,附上当时写的代码如下(vbs):


'Verison:        WSH 5.8
'Platform:       WinXP/Vista/WIN7
'Author:         Ken Hua (
hua.ken@inventec.com.cn)
'
' Script Function:
'   Get Hard Disk S.M.A.R.T information
'

'On Error Resume Next
'Option Explicit

Const Start_Stop_Count = 4      'A tally of spindle start/stop cycles.
Const Power_On_Hours = 9        'Count of hours in power-on state.  
Const Temperature = 194          'Current internal temperature.  


Dim i,j,k,items(100),threshold(100),smartdata(2,11)
Dim Description(2),Limit(2),Normal(2),Bad(2),Data(2),getInfo(2)
Dim strComputer,objWMIService,colItems,objItem

strComputer = "."
getInfo(0) = Start_Stop_Count
getInfo(1) = Power_On_Hours
getInfo(2) = Temperature


Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\WMI")
Set colItems = objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_FailurePredictThresholds",,48)  
 For Each objItem In colItems      
  j = 0
  For i = 2 To UBound(objItem.VendorSpecific, 1) Step 12
   items(j) = objItem.VendorSpecific(i)
   threshold(j) = objItem.VendorSpecific(i+1)
                 j = j + 1
  Next
 Next 
   
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\WMI")
Set colItems = objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData",,48) 
 For Each objItem In colItems      
  For i = 2 To UBound(objItem.VendorSpecific, 1) Step 12
                 If objItem.VendorSpecific(i) = getInfo(0) Then
                  k = i
                  For j = 0 To 11
                   smartdata(0,j) = objItem.VendorSpecific(k)
                   k = k + 1
                  Next 
                 End If
                 If objItem.VendorSpecific(i) = getInfo(1) Then
                  k = i
                  For j = 0 To 11
                   smartdata(1,j) = objItem.VendorSpecific(k)
                   k = k + 1
                  Next 
                 End If
                 If objItem.VendorSpecific(i) = getInfo(2) Then
                  k = i
                  For j = 0 To 11
                   smartdata(2,j) = objItem.VendorSpecific(k)
                   k = k + 1
                  Next 
                 End If
                Next                                
 Next

 For i = 0 To 100
  If items(i) = getInfo(0) Then
   Limit(0) = threshold(i)
  End If
  If items(i) = getInfo(1) Then
   Limit(1) = threshold(i)
  End If
  If items(i) = getInfo(2) Then
   Limit(2) = threshold(i)
  End If
 Next
 
 Description(0) = "Start/Stop Count"
 Description(1) = "Power On Hours"
 Description(2) = "Temperature" 
  
 Normal(0) = smartdata(0,3)
 Normal(1) = smartdata(1,3)
 Normal(2) = smartdata(2,3)
   
 Bad(0) = smartdata(0,4)
 Bad(1) = smartdata(1,4)
 Bad(2) = smartdata(2,4)
 
 Data(0) = (Int(smartdata(0,7))*16*16*16)+(Int(smartdata(0,6))*16*16)+Int(smartdata(0,5))
 Data(1) = (Int(smartdata(1,7))*16*16*16)+(Int(smartdata(1,6))*16*16)+Int(smartdata(1,5))
 Data(2) = (Int(smartdata(2,7))*16*16*16)+(Int(smartdata(2,6))*16*16)+Int(smartdata(2,5))

       Wscript.echo "Hard Disk S.M.A.R.T                                 -- Hua.ken@Inventec.com.cn    " & vbCrLf _
                   &"----------------------------------------------------------------------------------" & vbCrLf _
                   &" Description(ID)   Threshold_Limit      Normal      Bad        Data               " & vbCrLf _  
                   &"----------------------------------------------------------------------------------" & vbCrLf _ 
                   & Description(0) & "(" & getInfo(0) & ")" & Space(7) & Limit(0) & Space(16) & Normal(0) & Space(12) & Bad(0) & Space(12) & Data(0) & vbCrLf _ 
                   & Description(1) & "(" & getInfo(1) & ")" & Space(7) & Limit(1) & Space(17) & Normal(1) & Space(13) & Bad(1) & Space(13) & Data(1) & vbCrLf _ 
                   & Description(2) & "(" & getInfo(2) & ")" & Space(9) & Limit(2) & Space(17) & Normal(2) & Space(13) & Bad(2) & Space(13) & Data(2)
Wscript.Quit

在本人Presario CQ32笔记本上运行状况截图:



1 0
原创粉丝点击