locked
エラーイベントを監視するVBSを作成したい RRS feed

  • 質問

  • エラーが発生した際に、自動でメールを送信するようにVBSで、エラーイベントを監視するVBSを作成したいのですが、うまくいきません。

    イベントビューアで見る、「種類:エラー」、かつ「イベントID:1000」が発生した際にメール送信するようにしたいのです。

    種類を限定せず、「イベントID:1000」が発生した際にメール送信するVBSは下記のとおりできました。

    **************************************************************************************************

    Option Explicit
    Dim MailTo,Locator,Service,StrComputer,ObjWMIService
    Dim ColMonitoredEvents,CsSet,Cs,WServerName,Item_S,Item_E
    Dim ObjLatestEvent,WDate,WMessage

    Initial_Set
    ChkEvent
    WScript.Quit

    Sub Initial_Set

      MailTo = "メールアドレス"

      Set Locator = WScript.CreateObject("WbemScripting.SWbemLocator")
      Set Service = Locator.ConnectServer
    End Sub

    Sub ChkEvent
      StrComputer = "."
      Set ObjWMIService = GetObject("winmgmts:{(Security)}\\" & StrComputer & "\root\cimv2")

      Set ColMonitoredEvents = ObjWMIService.ExecNotificationQuery _   
        ("Select * from __InstanceCreationEvent Where " _
            & "TargetInstance ISA 'Win32_NTLogEvent' " _
                & "and TargetInstance.EventCode = '1000' ")
               
      Set CsSet = Service.ExecQuery("Select * From Win32_ComputerSystem")
      For Each Cs In CsSet
        WServerName =  Cs.Name
      Next

      Do
        Set ObjLatestEvent = ColMonitoredEvents.NextEvent
        WDate = Left(ObjLatestEvent.TargetInstance.TimeWritten,InStr(ObjLatestEvent.TargetInstance.TimeWritten,"."))
        WDate = Mid(WDate,1,4) & "/" & Mid(WDate,5,2) & "/" & Mid(WDate,7,2) & " " & _
                Mid(WDate,9,2) & ":" & Mid(WDate,11,2) & ":" & Mid(WDate,13,2)
        WDate = DateAdd("h",9,WDate)
        WMessage = ObjLatestEvent.TargetInstance.Message
      MailSend
      Loop
    End Sub

    Sub MailSend
      'メール送信の記述
    End Sub

    ****************************************************************************************************

    一応、上記VBSは動いているのですが、正常な動作の場合にも「イベントID:1000」は発生するので、

    種類がエラーの時というのを条件に加えたいのです。

    上記VBSもネット上から拾ってきて、修正しただけで、自分は初心者に近いレベルなので

    ご教授して頂けると助かります。

    環境はWindowsServer2003ですが、今後は2008でも使用したいと思っています。宜しくお願い致します。

    2013年4月1日 4:43

回答

  • 2008 で動かしてみた物でよければ。

    '************************************************************
    ' 出力を WScript から CScript に変更しておく事。
    ' コマンドプロンプトから cscript /H:Cscript
    ' Wscript で起動するとタスクでしかシャットダウン出来ないので注意
    '
    ' 利用方法
    ' コマンドを起動して、このプログラムを実行。
    ' イベントログに「エラー」「警告」メッセージ
    ' が発生するとイベントをキャッチします。
    '
    ' テストでイベントを発生させるには
    ' 新たにコマンドプロンプトを起動して
    ' EVENTCREATE /T ERROR /ID 1000 /L APPLICATION /D "wait test"
    ' と入力。
    ' アプリケーションログに、イベントID1000、エラー
    ' として wait test とメッセージを残します。
    '************************************************************
    Const MailServer = ""
    Const SmtpPort = 25
    Const UserName = ""  'ログインアカウントの設定
    Const PassWord = ""  'ログインパスワードの設定
    Const MailTo = ""  '複数の場合は『,』区切り
    Const MailFrom = ""
    Dim Subject, Body
    '************************************************************
    Dim objCDO:       Set objCDO = CreateObject("CDO.Message")
    Dim objCDOConfig: Set objCDOConfig = CreateObject("CDO.Configuration")
    Dim objFields:    Set objFields = objCDOConfig.Fields
    With objFields
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = MailServer
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = SmtpPort
      .Item("http://schemas.microsoft.com/cdo/configuration/SendUsing") = 2         'smtpauthenticateを使う時は必ず2にする
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1  '認証を使う 1はbasic認証、2はNTLM認証
      .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = UserName
      .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = PassWord
      .Update
      '.Send
    End With
    '************************************************************
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
      strComputer & "\root\cimv2")
    Set colMonitoredEvents = objWMIService.ExecNotificationQuery _   
      ("Select * from __InstanceCreationEvent Where " _
        & "TargetInstance ISA 'Win32_NTLogEvent' " _
          & "and (TargetInstance.Type = 'エラー' " _
            & "or TargetInstance.Type = '警告') ")
    '************************************************************
    Do
      Set objLatestEvent = colMonitoredEvents.NextEvent
      With objLatestEvent

        '**********************************************
        '抽出出来る内容 テストする場合
        '**********************************************
        'Wscript.Echo objLatestEvent.TargetInstance.Category
        'Wscript.Echo objLatestEvent.TargetInstance.CategoryString
        'Wscript.Echo objLatestEvent.TargetInstance.ComputerName
        'Wscript.Echo objLatestEvent.TargetInstance.Data
        'Wscript.Echo objLatestEvent.TargetInstance.EventCode
        'Wscript.Echo objLatestEvent.TargetInstance.EventIdentifier
        'Wscript.Echo objLatestEvent.TargetInstance.EventType
        'Wscript.Echo objLatestEvent.TargetInstance.Logfile
        'Wscript.Echo objLatestEvent.TargetInstance.Message
        'Wscript.Echo objLatestEvent.TargetInstance.RecordNumber
        'Wscript.Echo objLatestEvent.TargetInstance.SourceName
        'Wscript.Echo objLatestEvent.TargetInstance.TimeGenerated
        'Wscript.Echo objLatestEvent.TargetInstance.TimeWritten
        'Wscript.Echo objLatestEvent.TargetInstance.Type
        'Wscript.Echo objLatestEvent.TargetInstance.User
        'イベント発生後に終了
        'Wscript.quit
        '**********************************************


        '**********************************************
        '送信
        '**********************************************
        'コンピュータ名とイベントタイプをタイトルに
        Subject = objLatestEvent.TargetInstance.ComputerName & _
          Space(2) & _
            objLatestEvent.TargetInstance.Type
        '本文生成
        Body = ""
        'プロパティを列挙して拾えるものは全部埋め込んでおく。
        On Error Resume Next
        For Each obj IN .TargetInstance.Properties_
          Body = Body & obj.Name & " : " & obj.Value & VbCrLf
        Next
        On Error Goto 0
        With objCDO
          .Configuration = objCDOConfig
          .To = MailTo
          .From = MailFrom
          .Subject = Subject
          .TextBody = Body
          .Send
        End With
      End With
    Loop

     

    • 回答の候補に設定 佐伯玲 2013年4月4日 1:43
    • 回答としてマーク toyo_g 2013年4月4日 3:48
    2013年4月2日 1:24

すべての返信

  • 2008 で動かしてみた物でよければ。

    '************************************************************
    ' 出力を WScript から CScript に変更しておく事。
    ' コマンドプロンプトから cscript /H:Cscript
    ' Wscript で起動するとタスクでしかシャットダウン出来ないので注意
    '
    ' 利用方法
    ' コマンドを起動して、このプログラムを実行。
    ' イベントログに「エラー」「警告」メッセージ
    ' が発生するとイベントをキャッチします。
    '
    ' テストでイベントを発生させるには
    ' 新たにコマンドプロンプトを起動して
    ' EVENTCREATE /T ERROR /ID 1000 /L APPLICATION /D "wait test"
    ' と入力。
    ' アプリケーションログに、イベントID1000、エラー
    ' として wait test とメッセージを残します。
    '************************************************************
    Const MailServer = ""
    Const SmtpPort = 25
    Const UserName = ""  'ログインアカウントの設定
    Const PassWord = ""  'ログインパスワードの設定
    Const MailTo = ""  '複数の場合は『,』区切り
    Const MailFrom = ""
    Dim Subject, Body
    '************************************************************
    Dim objCDO:       Set objCDO = CreateObject("CDO.Message")
    Dim objCDOConfig: Set objCDOConfig = CreateObject("CDO.Configuration")
    Dim objFields:    Set objFields = objCDOConfig.Fields
    With objFields
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = MailServer
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = SmtpPort
      .Item("http://schemas.microsoft.com/cdo/configuration/SendUsing") = 2         'smtpauthenticateを使う時は必ず2にする
      .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1  '認証を使う 1はbasic認証、2はNTLM認証
      .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = UserName
      .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = PassWord
      .Update
      '.Send
    End With
    '************************************************************
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
      strComputer & "\root\cimv2")
    Set colMonitoredEvents = objWMIService.ExecNotificationQuery _   
      ("Select * from __InstanceCreationEvent Where " _
        & "TargetInstance ISA 'Win32_NTLogEvent' " _
          & "and (TargetInstance.Type = 'エラー' " _
            & "or TargetInstance.Type = '警告') ")
    '************************************************************
    Do
      Set objLatestEvent = colMonitoredEvents.NextEvent
      With objLatestEvent

        '**********************************************
        '抽出出来る内容 テストする場合
        '**********************************************
        'Wscript.Echo objLatestEvent.TargetInstance.Category
        'Wscript.Echo objLatestEvent.TargetInstance.CategoryString
        'Wscript.Echo objLatestEvent.TargetInstance.ComputerName
        'Wscript.Echo objLatestEvent.TargetInstance.Data
        'Wscript.Echo objLatestEvent.TargetInstance.EventCode
        'Wscript.Echo objLatestEvent.TargetInstance.EventIdentifier
        'Wscript.Echo objLatestEvent.TargetInstance.EventType
        'Wscript.Echo objLatestEvent.TargetInstance.Logfile
        'Wscript.Echo objLatestEvent.TargetInstance.Message
        'Wscript.Echo objLatestEvent.TargetInstance.RecordNumber
        'Wscript.Echo objLatestEvent.TargetInstance.SourceName
        'Wscript.Echo objLatestEvent.TargetInstance.TimeGenerated
        'Wscript.Echo objLatestEvent.TargetInstance.TimeWritten
        'Wscript.Echo objLatestEvent.TargetInstance.Type
        'Wscript.Echo objLatestEvent.TargetInstance.User
        'イベント発生後に終了
        'Wscript.quit
        '**********************************************


        '**********************************************
        '送信
        '**********************************************
        'コンピュータ名とイベントタイプをタイトルに
        Subject = objLatestEvent.TargetInstance.ComputerName & _
          Space(2) & _
            objLatestEvent.TargetInstance.Type
        '本文生成
        Body = ""
        'プロパティを列挙して拾えるものは全部埋め込んでおく。
        On Error Resume Next
        For Each obj IN .TargetInstance.Properties_
          Body = Body & obj.Name & " : " & obj.Value & VbCrLf
        Next
        On Error Goto 0
        With objCDO
          .Configuration = objCDOConfig
          .To = MailTo
          .From = MailFrom
          .Subject = Subject
          .TextBody = Body
          .Send
        End With
      End With
    Loop

     

    • 回答の候補に設定 佐伯玲 2013年4月4日 1:43
    • 回答としてマーク toyo_g 2013年4月4日 3:48
    2013年4月2日 1:24
  • 藤森幸治 様

    ご回答ありがとうございます!

    とてもわかりやすく書いて頂いて、初心者の自分でも読むことができました。

    ご回答頂いた構文を、社内用に書き換えて、思い通りの動作が出来ました。

    一旦、回答としてマークさせて頂きます。

    もし宜しければ、追加でもう1点ご教授いただきたいのですが、

    上記スクリプトで監視したいサーバでだけ、なぜか動きません。

    該当サーバはWindowsServer2003なのですが、他のWindowsServer2003サーバやWindowsServer2008サーバ、

    クライアントのWindows7やWindowsXPでは動作するのですが、実際に監視させたいサーバでだけ動きません。

    何が動かないかというと、イベントをキャッチしません。

    試しにメール送信部分のみ実行させたところ、問題なくメールは送信されました。

    で、イベントを監視する部分のみを簡潔に書き換えて実行したところ、反応がありません。

    ※スクリプト自体は実行されています。

    こんな感じです。********************************************************

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
      strComputer & "\root\cimv2")
    Set colMonitoredEvents = objWMIService.ExecNotificationQuery _   
      ("Select * from __InstanceCreationEvent Where " _
        & "TargetInstance ISA 'Win32_NTLogEvent' " _
          & "and (TargetInstance.Type = 'エラー') ")
    Do
      Set objLatestEvent = colMonitoredEvents.NextEvent
      With objLatestEvent

       msgbox "エラーが発生しました"

      End With
    Loop

    ********************************************************************

    TargetInstance.Type をTargetInstance.EventCodeなどに変えてみてもダメです。

    イベントはコマンドプロンプトの「EVENTCREATE」で登録しています。

    イベントビューアに登録されているのは、確認しています。

    このスクリプトで、イベントをキャッチするために必須となるOSの設定(サービスとか)などが

    あるのでしょうか?

    動作するサーバと、動作しないサーバのサービスを比べてみましたが、わかりません。

    原因となる可能性があるものを教えて頂ける助かります。

    宜しくお願い致します。

    2013年4月4日 3:48
  • スクリプト センター | TechNet

    http://technet.microsoft.com/ja-jp/scriptcenter/bb410849.aspx

    スクリプトセンターを確認して頂くのが早そうですね。

    2013年4月4日 5:56
  • 藤森幸治 様

    なるほど、それではご回答頂いたサイトを参考にしてみます。

    WMIは動いていて、他のWMIを使ったスクリプトを実行してみたところ正常に動作しました。

    スクリプトではなくサーバ側の原因かもしれません。

    とても丁寧なご対応頂きありがとうございました。

    頑張って動かしてみます。

    2013年4月4日 6:28