none
Email Notification BODY Text Using SMTP Event Consumer

    問題

  • HI,

    Can anybody please help with the SMTP MEssage Content in the MOF file below which is not triggering email after grouping TargetInstance.FileName I want the FileNames in the Email Message..

    please Advice how can i get the grouped Filenames in the event class

    // 1. Change the context to Root\Subscription namespace
    //    All standard consumer classes are
    //    registered there.

    #pragma namespace("\\\\.\\root\\subscription")


    // 2. Create an instance of __EventFilter class
    //    and use it's Query property to store
    //    your WQL event query.

    instance of __EventFilter as $EventFilter
    {
        Name  = "FileCopyFilter";
        EventNamespace = "Root\\Cimv2";
        Query ="SELECT * From __InstanceCreationEvent WITHIN 10 Where TargetInstance ISA 'CIM_DATAFile'AND TargetInstance.Drive='D:' GROUP WITHIN 10 BY TargetInstance.FileName";
        QueryLanguage = "WQL";
    };


    // 3. Create an instance of __EventConsumer
    //    derived class. (ActiveScriptEventConsumer
    //    SMTPEventConsumer etc...)

    instance of SMTPEventConsumer as $SMTPConsumer
    {
        Name = "FileCopySMTPConsumer";
        Message = "A File Name %TargetInstance.FileName% Were Copied";
        SMTPServer = "me@.com";
        Subject = "Filescopied to USB on Computer %TargetInstance.CSName%";
        ToLine = me@.com;
        FromLine = "%TargetInstance.CSName%@.com";
    };


    // 4. Join the two instances by creating
    //    an instance of __FilterToConsumerBinding
    //    class.

    instance of __FilterToConsumerBinding
    {

        Filter = $EventFilter;
        Consumer = $SMTPConsumer;
    };

    2012年3月14日 下午 12:42

解答

  • As per Bill.

    I have written file system watchers since NT4.  Eevery project that needs something like this has very different requirements outside of just detecting the event.  This can be done in script but it cannot be done the wway you are approaching it.  You have found a process that can send an email but will not do the other things.

    On good approach to doing this is to use MSMQ.  You can end Q messages on each file in  a script event then have a process that scans the Q periodically to collect all of the file names that hhave been created.

    You can also do this by running a Powershell script under the task scheduler.

    You cannot do it with the SMTP event in a MOF or any other way.

    The issue you will have with the vbscript method you ae experimenting with is that you can have no memory.  The events will be delivered but yu will have not evidence of past events as the variables are not persisted and the event code runs statelessly.

    Here is a script that uses teh FileSystemWatcher to event onfile changes.   It can be easily modifed to your needs.

    http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b


    ¯\_(ツ)_/¯

    2012年3月22日 下午 04:41

所有回覆

  • Hi,

    What is the goal you are trying to achieve?

    Bill

    2012年3月14日 下午 03:39
  • HI,

    Can anybody please help with the SMTP MEssage Content in the MOF file below which is not triggering email after grouping TargetInstance.FileName I want the FileNames in the Email Message..

    I assume that 'Not triggering email' means you never get an email.  This can be caused by an error in the MOF when it executes.  Look in the WEBMlog and the event log file for errors.

    Does you email server require authentication?

    This line looks suspicious:

    SMTPServer = "me@.com";

    It should be either an IP or an FQDN and not an email address.

    The 'from' line must resolve to a legitimate email address with most SMTP servers.

    Try this from a PowerShell prompt to test the mail server on the machine you are trying to run the MOF from.

    PS>Send-MailMessage `
         -to someone@somewhere.com `
         -from me@here.com `
         -subject test `
         -body test `
         -smtpserver smtp.domain.com

    The line has line extender characters at the end of each bit.  Be sure to not lose them.

    REplace to/from/smtpserver with your caleues.  If this wil lnot work as posted  then you cannot use a MOF to send email and may need to use an account and password for the SMTP server.

    If the PowerShell test works the test the MOF. To test for errors remove the variables in the MOF and test.


    ¯\_(ツ)_/¯

    2012年3月14日 下午 05:51
  • hi,

    My goal is to get filenames copied to D: in the Email Body

    Instead it  triggers email for each file copy for which i used group and BY  but now when iam using them it is not triggering email

    2012年3月15日 上午 09:22
  • hi,

    Thank you i just changed the from and to for blog purpose

    iam getting email when iam not using group and by in the query but just want to get the file names in the email Body

    Thank you,

    2012年3月15日 上午 09:25
  • Group does not work on all events.  All providers cannot supply it.  Within 10 will buffer for 10 until teh timeout occurs then it wil send whatever it has even if it is only one item.

    What you are trying to do cannot really be done.  Events are individual per object.  Witin jsut allows fro some buffering to keep the events from occurring to frequently.


    ¯\_(ツ)_/¯

    2012年3月15日 下午 12:20
  • Hi,

    Your description of what you want to do is too vague. You are describing steps, not a goal.

    What is the underlying purpose for which you want to perform these steps?

    Bill

    2012年3月15日 下午 03:23
  • Hi,

    Your description of what you want to do is too vague. You are describing steps, not a goal.

    What is the underlying purpose for which you want to perform these steps?

    Bill

    Bill - the query syntax is wrong for this event provider.

    Once you remove the group clause the query and email work assuming a correct email server.


    ¯\_(ツ)_/¯

    2012年3月15日 下午 03:32
  • Hi,

    I am asking about the purpose of the MOF. What goal is it supposed to achieve?

    In other words, the OP needs to describe the "what" and not the "how."

    Bill

    2012年3月15日 下午 04:02
  • hi,

    My goal is to get filenames copied to D: in the Email Body

    Instead it  triggers email for each file copy for which i used group and BY  but now when iam using them it is not triggering email

    Bill - this is the goal.  It is a bit vague but he wants to copy nrely created filenames into a mail message and email it.  That is this query:

    SELECT * From __InstanceCreationEvent WITHIN 10 Where TargetInstance ISA 'CIM_DATAFile'AND TargetInstance.Drive='D:'

    This will trigger an event witin 10 items created.  The problem is that the within times out so you will likely get names one at a time.  These can be posted to a file or the registry and monitorred to only send an email after a period of time or a number of files.  Tis would have to be done using a 'script' task.


    ¯\_(ツ)_/¯

    2012年3月15日 下午 04:18
  • Hi,

    What I am asking is: Why is that the goal? What is the underlying purpose the OP wants to achieve?

    Bill

    2012年3月15日 下午 04:51
  • You want to know the meta-reason for  the getting notified that files are being created.

    Good question. 


    ¯\_(ツ)_/¯

    2012年3月15日 下午 07:03
  • I just discovered that teh SQWL that you are using is actually incorrect becuase yuo have modified it but incompletely.

    These two WQL statemnsts are correct.

    "SELECT * From InstanceCreationEvent WITHIN 1 Where TargetInstance ISA 'CIM_DATAFile'AND TargetInstance.Drive='D:'";

    "SELECT * From __InstanceCreationEvent WITHIN 1 Where TargetInstance ISA 'CIM_DATAFile'AND TargetInstance.Drive='D:' GROUP WITHIN 300";

    With this particular event you can use WITHIN 1 in the first clause.  The GROUP WITHIN is not a group by but a GROUP WITHIN <interval>  The interval is in seconds.  My example above is a wait of 5 minutes.  This will dump any events collected every 5 minutes. 

    As I had mentioned earlier.  The WITHIN in this event is a time and teh first WITHIN can only be set to 1.  If you set it to anything else you will get an event error 10 in the Application log warning about teh clause 0x80042002.

    I am still not sure that it will grpoup as needed.  I believe it will dump whenever the timeout occurs. 

    Try it and see.


    ¯\_(ツ)_/¯

    2012年3月16日 下午 06:50
  • Just some additional information, if you use the GROUP clause in your query it returns an instance of the __AggregateEvent class which contains only one (Representative) of the instances received during the grouping interval (see here).

    Uros Calakovic

    2012年3月19日 下午 05:04
  • Just some additional information, if you use the GROUP clause in your query it returns an instance of the __AggregateEvent class which contains only one (Representative) of the instances received during the grouping interval (see here).

    Uros Calakovic

    Go0od point.  It is  necessary to understand what and why grouping is available.  It is a threshhold setting.  It says I wan to be notifed every time teh threshhold exceeds, equal or is less than some number withing a specified interval.  It is a quality metric measuremnent system and not a method of grouping as in SQL.  Group in an interval that can have a qualifier called numberof events.

    Careful reading of the documentation will eventually clarify what is happening.


    ¯\_(ツ)_/¯

    2012年3月19日 下午 05:20
  • Thanks to both of you,

    Well my final goal is  to get filenames to email body whenever files are copied to a storage device like USB after exploring a lot  still  unable to get it.

    Iam not aware of th entire methodology or process to achieve this in proper way if it is really achievable..as iam very new to WMI..trying to achieve it

    using WMI permanent Event Subscription or vbscript

    Here is the Complete Script:

    'OnErrorResumeNext
    HKEY_LOCAL_MACHINE = &H80000002
    Dim objFSO,objTextFile
    Dim CurrentDate
    CurrentDate = Now
    Dim wshShell
    dim message
    Set wshShell = WScript.CreateObject("WScript.Shell")
    Set objNetwork = WScript.CreateObject("WScript.Network") 
    strUser = objNetwork.UserDomain
    'strComputer = "."
    'On Error Resume Next
    If WScript.Arguments.Count = 1Then
        strComputer = WScript.Arguments(0)   'drag and drop a MSG file from desktop
        Dim fso, strArg1, tArray
        set fso = CreateObject("Scripting.FileSystemObject")
            strArg1 = WScript.Arguments(0)
        
        If fso.FileExists(strArg1) Then
            tArray = split(fso.GetBaseName(strArg1))
            strComputer = tArray(UBound(tArray))
            fso.DeleteFile(strArg1)
        Else
            strComputer =strArg1
        EndIf    
    Else
        strComputer = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
        message = "Enter a PC Name:" & vbcrlf & vbcrlf & _
        strComputer = "."
    '   InputBox(message,"Computer Name?",strComputer)
    EndIf

    If strcomputer = ""Then WScript.Quit
    strComputer = UCase(strComputer)

    Dim strWQL, oWMI, colDiskDrives, oDiskDrive,drive
    Dim colPartitions, oPartition
    Dim ColLDrives, oLDrive, strModel, i
    i = 0
    OnErrorResumeNext
    Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
    IfErr <> 0Then

        MsgBox Err.Description,vbCritical + vbOKOnly,"Error"
        WScript.Quit
    EndIf
    OnErrorGoTo0
    'Getting the drive letter  ...
    Set colDiskDrives = oWMI.ExecQuery("SELECT * FROM Win32_DiskDrive where InterfaceType='USB' and size > 0",,48)
        ForEach oDiskDriveIn colDiskDrives'Get USB Drives.  DeviceID looks like \\.\PHYSICALDRIVE1
          strModel = oDiskDrive.Caption
           strWQL =  "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" & oDiskDrive.deviceID & _
             "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"
           Set colPartitions = oWMI.ExecQuery(strWQL,,48)
           ForEach oPartitionIn colPartitions
            i = i + 1
            'WScript.Echo "Partition: " & oPartition.DeviceID 'Device ID looks like Disk #1, Partition #0
             strWQL = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & oPartition.DeviceID & _
             "'} WHERE AssocClass = Win32_LogicalDiskToPartition"
             
             Set colLDrives = oWMI.ExecQuery(strWQL,,48)
                ForEach oLDriveIn ColLDrives
    '               iRetval = MsgBox("Found " & strModel & ". View Files?",vbYesNoCancel + vbQuestion,"Drive found")

    '               If iRetval = vbCancel Then WScript.Quit 
    '               If iRetval = vbYes Then 
                    drive=oLDrive.DeviceID
    '               Explore oLDrive.DeviceID   'Device ID looks like E:
    '               End If


                Next
           Next     
       Next

    OnErrorResumeNext
    Set colMonitoredEvents = oWMI.ExecNotificationQuery("SELECT * From __InstanceCreationEvent WITHIN 5 Where TargetInstance ISA 'CIM_DATAFile'And TargetInstance.Drive='"& drive &"'")
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Do  
    Set objLatestEvent = colMonitoredEvents.NextEvent
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objTextFile = objFSO.CreateTextFile("c:\USBFileCopy.txt",True)
    'If IsNull(objLatestEvent) Is True Then Exit Do

    ForEach objLatestEventIn colMonitoredEvents
    strText = "FileName: " & objLatestEvent.TargetInstance.FileName & objLatestEvent.TargetInstance.FileType & strComputer & Now
    objTextFile.WriteLine(strText)
    Next
    Loop
    objTextFile.Close
    'These constants are defined to make the code more readable
    Const ForReading = 1, ForWriting = 2, ForAppending = 8
    If objFile.Size > 0Then
    'To Read Values from txt File for email Body
    Set objFile = objFSO.GetFile("c:\USBFileCopy.txt")
    'Open the file for reading
    Set objReadFile = objFSO.OpenTextFile("c:\USBFileCopy.txt",1)
    'The ReadAll method reads the entire file into the variable BodyText
    BodyText = objReadFile.ReadAll
    'Close the file
    objReadFile.Close
    Set objEmail = CreateObject("CDO.Message") 
    objEmail.From = "me@domain.com"
    objEmail.To = "you@domain.com"
    objEmail.Subject = "Files Copied to USB" & strModel & "by User" & objNetwork.UserName
    objEmail.Textbody = BodyText
    objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "xyz.domain.com"
    objEmail.Configuration.Fields.Update
    objEmail.Send
    Else
    set objEmail = Nothing
    EndIf


    • 已編輯 codefix 2012年3月22日 上午 05:59
    2012年3月22日 上午 05:51
  • I thought this questiopn was about uiosng a MOF to create a otification event.  Now you are completely changing this.

    The MOF works perfectly.  I have run it many times.

    This send an email with the name of any file dropped onto the USB.

    #pragma namespace("\\\\.\\root\\subscription")
    instance of __EventFilter as $EventFilter
    {
        Name  = "FileCopyFilter";
        EventNamespace = "Root\\Cimv2";
        Query ="SELECT * From __InstanceCreationEvent WITHIN 10 Where TargetInstance ISA 'CIM_DATAFile' AND TargetInstance.Drive='E:'";
        QueryLanguage = "WQL";
    };
    instance of SMTPEventConsumer as $SMTPConsumer
    {
        Name = "FileCopySMTPConsumer";
        Message = "A File Name %TargetInstance.FileName% Were Copied";
        SMTPServer = "alpha";
        Subject = "Filescopied to USB on Computer %TargetInstance.CSName%";
        ToLine = "user@domain.com";
        FromLine = "me@mydom.com";
    };
    instance of __FilterToConsumerBinding
    {
        Filter = $EventFilter;
        Consumer = $SMTPConsumer;
    }; 

    That's it. Just compile it an it works.  No other code needed.


    ¯\_(ツ)_/¯


    • 已編輯 jrv 2012年3月22日 上午 07:17
    2012年3月22日 上午 07:16
  • Hi,

    I am trying both ways to achieve it your are absolutely right it is working fine with MOF as long as single file is copied to USB..but if multiple files are copied it is

    sending email for each file copied that is where iam not getting to know how could i solve it so that it emails one mail with all the file names in its bodyText ....

    is it really possible?


    • 已編輯 codefix 2012年3月22日 上午 08:55
    2012年3月22日 上午 08:53
  • Hi,

    I am trying both ways to achieve it your are absolutely right it is working fine with MOF as long as single file is copied to USB..but if multiple files are copied it is

    sending email for each file copied that is where iam not getting to know how could i solve it so that it emails one mail with all the file names in its bodyText ....

    is it really possible?


    The simple answer is you cannot d othat with an SMTP Event.  YOou can with a script event.  Set the timeout to whatever you want and teh limit hugher than needed.  Then use  a Script event to search for all of the new files.

    You can alss just hace a script event trigger on every file and write that into a file.  Mail the file from the task when you think it has enogh files.

    Just change the MOF to use a script task event.

    You could also use teh FileSystemWatcher to capture the new files and run it as a Scheduled Task.


    ¯\_(ツ)_/¯

    2012年3月22日 上午 10:42
  • I'm trying to get the big picture here...

    Isn't the real question about how to prevent and/or log and/or control what gets copied to removable devices?

    In this case I think your answer is a system management product, not a script.

    Bill

    2012年3月22日 下午 04:23
  • As per Bill.

    I have written file system watchers since NT4.  Eevery project that needs something like this has very different requirements outside of just detecting the event.  This can be done in script but it cannot be done the wway you are approaching it.  You have found a process that can send an email but will not do the other things.

    On good approach to doing this is to use MSMQ.  You can end Q messages on each file in  a script event then have a process that scans the Q periodically to collect all of the file names that hhave been created.

    You can also do this by running a Powershell script under the task scheduler.

    You cannot do it with the SMTP event in a MOF or any other way.

    The issue you will have with the vbscript method you ae experimenting with is that you can have no memory.  The events will be delivered but yu will have not evidence of past events as the variables are not persisted and the event code runs statelessly.

    Here is a script that uses teh FileSystemWatcher to event onfile changes.   It can be easily modifed to your needs.

    http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b


    ¯\_(ツ)_/¯

    2012年3月22日 下午 04:41
  • As per Bill.

    I have written file system watchers since NT4.  Eevery project that needs something like this has very different requirements outside of just detecting the event.  This can be done in script but it cannot be done the wway you are approaching it.  You have found a process that can send an email but will not do the other things.

    On good approach to doing this is to use MSMQ.  You can end Q messages on each file in  a script event then have a process that scans the Q periodically to collect all of the file names that hhave been created.

    You can also do this by running a Powershell script under the task scheduler.

    You cannot do it with the SMTP event in a MOF or any other way.

    The issue you will have with the vbscript method you ae experimenting with is that you can have no memory.  The events will be delivered but yu will have not evidence of past events as the variables are not persisted and the event code runs statelessly.

    Here is a script that uses teh FileSystemWatcher to event onfile changes.   It can be easily modifed to your needs.

    http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b


    ¯\_(ツ)_/¯

    Thank you so much the link you provided was really so helpful but still need one small help i could see as long as the script is running during that time only it is sending emails once

    it stops its not working how i can make this script permanently monitor all the time or am I missing anything

    2012年3月30日 上午 04:12
  • We have no idea what script you are talking about.


    ¯\_(ツ)_/¯

    2012年3月30日 上午 04:19
  • Just run the script and leave it running.  It will trigger an event on any or all of the condition you choose.

    The script may fail if your event code has any errors so be sure that the event code you are using works correctly.

    Tis code wil still only send one email message per file change/creation.  It will not aggregate.  The WMI code I showed you will aggregate but will not give you the names of all objects.

    To get what you want you need to design a custom agggregating handler.  This is a fairly advanced techique and requires very good scripting skills.


    ¯\_(ツ)_/¯

    2012年4月2日 上午 04:05