*[PC]HDL4-G S.M.A.R.Tチェックスクリプト

vbsに慣れるため作成したスクリプト
HDL4-Gにはsmart.cgiというS.M.A.R.Tをチェックできる機能があるのだが
いちいち手動でチェックするのも面倒なので作成。
最低限のエラーチェックは行っているつもり。
ホスト名(またはIPアドレス)を引数に実行。
スクリプト名(拡張子除く).ホスト名(またはIPアドレス).iniファイルを
スクリプトと同じディレクトリに作成する。
スクリプト名は変更可能。
チェック項目は01、05、07、C4、C5、C6、C7、C8。


LandiskCheck.vbs

'******************************************************************************
'*** smart.cgiを取得し前回取得時のデータと比較。悪化時メッセージ出力        ***
'*** 引数:ホスト名またはIPアドレス                                          ***
'*** 使用ファイル:スクリプト名.ホスト名.ini 初回起動時自動作成              ***
'******************************************************************************
Option Explicit
Dim StsTbl(4,8,2)  'i:DiskNo. j:S.M.A.R.T値 k:before/after
Dim iniPath
Dim HostName
Dim DiskNo
DiskNo = Array("SATA1","SATA2","SATA3","SATA4")
Dim StsNo
StsNo = Array("01 Raw Read Error      ", _
              "05 Reallocated Sector  ", _
              "07 Seek Error          ", _
              "C4 Reallocated Event   ", _
              "C5 Pending Sector      ", _
              "C6 Uncorrectable Sector", _
              "C7 UDMA CRC Error      ", _
              "C8 Multi Zone Error    ")
Dim Args
Set Args = WScript.Arguments
If Args.Count <= 0 Then
   WScript.Echo "ホストが指定されていません"
   WScript.Quit
End If

HostName = Args(0)
iniPath = GetiniPath(HostName)
Call iniToTbl(iniPath,StsTbl)
Call CGIToTbl(HostName,StsTbl)
Call TblToini(iniPath,StsTbl,DiskNo,StsNo)
Call TblCheck(StsTbl,DiskNo,StsNo)
'WScript.Echo "END"


'******************************************************************************
'*** ホスト名からiniファイルフルパスを生成する                              ***
'******************************************************************************
Function GetiniPath(HostName)
    Dim FsoObj
    Set FsoObj = CreateObject("Scripting.FileSystemObject")
    Set GetiniPath = FsoObj.GetFile(WScript.ScriptFullName)
    Dim RegObj
    set RegObj =  New RegExp
    RegObj.Pattern = "\.vbs$"
    RegObj.IgnoreCase = True '大文字/小文字を同一視
    GetiniPath = RegObj.Replace(GetiniPath,"." & HostName & ".ini")
    Set FsoObj = Nothing
    set RegObj = Nothing
End Function


'******************************************************************************
'*** iniファイルからテーブルを作成する                                      ***
'******************************************************************************
Function iniToTbl(iniPath,StsTbl)
    Dim FsoObj
    Set FsoObj = CreateObject("Scripting.FileSystemObject")
    If FsoObj.FileExists(iniPath) = False Then
        Call TblInit(StsTbl)
        Set FsoObj = Nothing
        Exit Function
    End If
    Set FsoObj = Nothing

    Dim iLine
    Dim i
    Dim j
    Dim StmObj
    Set StmObj = CreateObject("ADODB.Stream")
    StmObj.Type = 2   'テキストモード
    StmObj.Charset = "shift_jis"
    StmObj.Open
    StmObj.loadFromFile iniPath
    Dim RegOut
    Dim RegObj
    set RegObj =  New RegExp
    RegObj.Pattern = "\d{5}$"

    For i = 0 To 3
        For j = 0 To 7
            iLine = StmObj.ReadText(-2)
            set RegOut = RegObj.Execute(iLine)
            StsTbl(i,j,0) = RegOut(0)
            StsTbl(i,j,1) = "00000"
        Next
    Next
    StmObj.Close()
    Set StmObj = Nothing
    set RegObj = Nothing
End Function


'******************************************************************************
'*** iniファイルがない場合に初期値でテーブルを作成する                      ***
'******************************************************************************
Function TblInit(StsTbl)
    Dim i
    Dim j
    Dim k
    For i = 0 To 3
        For j = 0 To 7
            For k = 0 To 1
                StsTbl(i,j,k) = "00000"
            Next
        Next
    Next
End Function


'******************************************************************************
'*** cgiデータを取得しテーブルに展開                                        ***
'******************************************************************************
Function CGIToTbl(HostName,StsTbl)
    Dim HttpObj
    Dim StmObj
    Dim URL
    URL = "http://" & HostName & "/gate/smart.cgi"
    Set HttpObj = CreateObject("MSXML2.XMLHTTP")
    HttpObj.Open "GET",URL,False
    On Error Resume Next
    HttpObj.Send
    On Error GoTo 0
    If (HttpObj.Status < 200 Or HttpObj.Status >= 300) Then
        WScript.Echo "URL取得失敗。LANDISK起動を確認してください。" & vbLf & "処理を中断します。"
        set HttpObj = Nothing
        WScript.Quit
    End If

'ストリームに取込
    Set StmObj           = CreateObject("ADODB.Stream")
    StmObj.Type          = 1             'バイナリモード
    StmObj.Open
    StmObj.Write HttpObj.responseBody    'バイナリデータ書込
    Set HttpObj          = Nothing
    StmObj.Position      = 0             '先頭に位置付け
    StmObj.Type          = 2             'テキストモード
    StmObj.Charset       = "ascii"
    StmObj.LineSeparator = 10            'LF

'テーブルに取込
    Dim i
    Dim j
    Dim iLine
    Dim StsNoW
    StsNoW = Array("  1", _
                   "  5", _
                   "  7", _
                   "196", _
                   "197", _
                   "198", _
                   "199", _
                   "200")                'landisk S.M.A.R.T値テーブル
    Dim RegObj
    set RegObj =  New RegExp
    Dim RegOut                           'RegExpマッチングコレクション
    i = 0
    Do Until StmObj.EOS
'最初にDiskNoを決定する
        Do Until StmObj.EOS  'オーバーラン防止にEOSチェック
           iLine = StmObj.readText(-2)
            RegObj.Pattern = "^=== sata" 'DiskNoチェック
            if RegObj.Test(iLine) Then
                For i = i to 3
                    RegObj.Pattern = "^=== sata" & i+1
                    if RegObj.Test(iLine) Then Exit For
                Next
                Exit Do
            End If
        Loop
'Statusに一致する行を探す
        j = 0
        Do Until j  = 7 OR StmObj.EOS  'オーバーラン防止にEOSチェック
           iLine = StmObj.readText(-2)
            For j = j to 7               'StatusNoチェック
                RegObj.Pattern = "^" & StsNoW(j)
                if RegObj.Test(iLine) Then Exit For '該当したら抜ける
            Next
            if j > 7 Then
                j = 0        '該当せずは再検索に備え添字リセット
            Else
                RegObj.Pattern = "\d+$"
                set RegOut = RegObj.Execute(iLine)
                If RegOut(0) > 99999 then    '5桁overは99999決め打ち
                    StsTbl(i,j,1)  = "99999"
                else
                    StsTbl(i,j,1)  = "00000" &  RegOut(0)  '前zero付与フォーマット
                    RegObj.Pattern = "\d{5}$"
                    set RegOut     = RegObj.Execute(StsTbl(i,j,1))
                    StsTbl(i,j,1)  = RegOut(0)
                End If
            End If
        Loop
        if i = 3 And j = 7 Then
            Exit Do        '全項目セットできたら以降はスルー
        End If
    Loop

'後処理
    set RegObj = Nothing
    StmObj.Close()
    Set StmObj = Nothing

End Function


'******************************************************************************
'*** テーブルをiniファイルに書出                                            ***
'******************************************************************************
Function TblToini(iniPath,StsTbl,DiskNo,StsNo)
    Dim i
    Dim j
    Dim k
    Dim oLine
    Dim StmObj
    Set StmObj = CreateObject("ADODB.Stream")
    StmObj.Type = 2   'テキストモード
    StmObj.Charset = "shift_jis"
    StmObj.Open

    For i = 0 To 3
        For j = 0 To 7
            oLine = DiskNo(i)     & "," _
                  & StsNo(j)      & "," _
                  & StsTbl(i,j,0) & "," _
                  & StsTbl(i,j,1)
            StmObj.WriteText oLine,1
        Next
    Next

    StmObj.SaveToFile iniPath,2
    StmObj.Close()
    Set StmObj = Nothing
End Function


'******************************************************************************
'*** テーブルのS.M.A.R.T値をチェックし悪化時メッセージ出力                  ***
'******************************************************************************
Function TblCheck(StsTbl,DiskNo,StsNo)
    Dim i
    Dim j
    Dim ErrMsg
    Dim WSHObj
    For i = 0 To 3
        For j = 0 To 7
            If StsTbl(i,j,1) > StsTbl(i,j,0) Then
                ErrMsg = ErrMsg                 _
                       & DiskNo(i)              _
                       & " "    & StsNo(j)      _
                       & " "    & StsTbl(i,j,0) _
                       & " -> " & StsTbl(i,j,1) _
                       & vbLf
            End If
        Next
    Next
    If ErrMsg  <> "" Then
        Set WSHobj = WScript.CreateObject("WScript.Shell")
        ErrMsg     = "cscript ""C:\Program Files\PPX\script\WSHPopUP.vbs""" _
                   & " """ & ErrMsg & """"    _
                   & " 0"                     _
                   & " " & WScript.ScriptName _
                   & " " & vbOKOnly
        WSHObj.Run ErrMsg,0,False    '終了待機しない
        Set WSHobj = Nothing
    End If

End Function


C:\Program Files\PPX\script\WSHPopUP.vbs

Option Explicit
Dim Arg
Dim WSHObj
Set WSHobj = WScript.CreateObject("WScript.Shell")
Set Arg = WScript.Arguments
WSHObj.Popup Arg(0),Arg(1),Arg(2),Arg(3)
Set WSHobj = Nothing