Using Event Triggered Tasks to Send Messages to Microsoft Teams

Building on my previous post about Incoming Webhooks in Microsoft Teams, one of the things I wanted to do was send a notification to a team if a particular event is logged to the Windows Event Log.

In this example, I will notify my team if one of my virtual machines changes state i.e. starts, shuts down, pauses etc. There are three parts to this solution.

The Webhook

The first thing we need to do is create the webhook, which i covered here.

The Script

For this script to work, we need to it accept some parameters, therefore we will start with a param block

param(
    $eventID,
    $vmname,
    $computer
)

The next thing we need to do is turn the EventID’s into something that is readable. I don’t know about you, but I can’t remember the difference between 18500 and 18502. For this, I’m using a switch statement.

switch ($eventID)
    {
        18500 {[string]$event = 'Started'}
        18502 {[string]$event = 'Turned Off'}
        18504 {[string]$event = 'Shutdown'}
        18510 {[string]$event = 'Saved'}
        18512 {[string]$event = 'Reset'}
        18516 {[string]$event = 'Paused'}
        18518 {[string]$event = 'Resumed'}

    }

If you haven’t seen or used a switch statement before, it’s a fairly straightforward construct. Think of it like a bunch of IF statements, but more concise and easier to maintain. Simply put, it will look at the value inside $eventID and run the corresponding script-block. Inside the script-block I am setting the value of $event to use later on in the script.

The final step before we build our message card and post it is to create a message string, and get the current date and time.

$message = "{0} has {1}" -f $vmname, $event
$date = (get-date)

The message card is not too different from the one in my first post, I’ve just altered the values of some properties to suit this scenario, and inserted the variables $computer, $event, $vmname and $date.

$body = @"
{
    '@type':'MessageCard',
    '@context':'http://schema.org/extensions',
    'themeColor':'007667',
    'title':'A change has been detected on $vmname',
    'summary':'VM State Changed',
    'sections':[{
        'activityTitle':'$message',
        'activitySubtitle':'$date',
        'facts':[
            {'name':'Host', 'value':'$computer'},
            {'name':'VM', 'value':'$vmname'},
            {'name':'Event', 'value':'$event'},
            {'name':'Time', 'value':'$date'}
        ]
    }],
    
}
"@

The really important thing here is to make sure you don’t mix and match your single and double quotes. Remember that JSON is a string format and as such, if you accidentally use a ” in the middle, you will prematurely end the string and it wont work.

Now we can use Invoke-Webrequest with our webhook URL and $body to send the message to Teams.

$url = <My URL>
invoke-webrequest -Uri $url -ContentType 'application/json' -Body $body -Method Post

See the full script here.

param(
    $eventID,
    $vmname,
    $computer
)

switch ($eventID)
    {
        18500 {[string]$event = 'Started'}
        18502 {[string]$event = 'Turned Off'}
        18504 {[string]$event = 'Shutdown'}
        18510 {[string]$event = 'Saved'}
        18512 {[string]$event = 'Reset'}
        18516 {[string]$event = 'Paused'}
        18518 {[string]$event = 'Resumed'}

    }
$message = "{0} has {1}" -f $vmname, $event
$date = (get-date)
$body = @"
{
    '@type':'MessageCard',
    '@context':'http://schema.org/extensions',
    'themeColor':'007667',
    'title':'A change has been detected on $vmname',
    'summary':'VM State Changed',
    'sections':[{
        'activityTitle':'$message',
        'activitySubtitle':'$date',
        'facts':[
            {'name':'Host', 'value':'$computer'},
            {'name':'VM', 'value':'$vmname'},
            {'name':'Event', 'value':'$event'},
            {'name':'Time', 'value':'$date'}
        ]
    }],
    
}
"@

$uri = <My URL>
invoke-webrequest -Uri $uri -ContentType 'application/json' -Body $body -Method Post

The Scheduled Task

To create the scheduled task, open up task scheduler and create a new task. On the first tab give the task a name and set the security profile. This is my dev machine, so I have just left it as Run only when user is logged in.

On the trigger tab, choose On an event from the drop down menu, select Custom and then click on New Event Filter

Choose the XML tab and select the box to Edit query manually and paste the follow XML into the text area and click OK.

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-Hyper-V-Worker-Admin">
    <Select Path="Microsoft-Windows-Hyper-V-Worker-Admin">*[System[(EventID=18500 or EventID=18502 or EventID=18504 or EventID=18510 or EventID=18512 or EventID=18516 or EventID=18518)]]</Select>
  </Query>
</QueryList>

On the Action tab, create a new action. In the Action drop down, choose Start a program. Under program/script enter Powershell.exe and add the following arguments <Path to script> ‘$(EventID)’ ‘$(VmName)’ ‘$(Computer)’

Under the settings tab, make sure that you choose Run a new instance in parallel, otherwise if multiple VMs change state at the same time, you will miss some notifications. An example of this would be if the disk your VMs are running on fills up, all of the VMs will pause.

Save the task.

Now you might have noticed that I haven’t explained the arguments yet, well we’re not quite done so I’m going to do that now.

Export the task as XML and open the file in you favorite text editor.

Inside the EventTrigger section, add the following

<ValueQueries>
        <Value name="Computer">Event/System/Computer</Value>
        <Value name="EventID">Event/System/EventID</Value>
        <Value name="VmName">Event/UserData/VmlEventLog/VmName</Value>
</ValueQueries>


Save the file and then import the task, delete the old one, and you should start to receive notifications as your VMs start, stop pause etc.

Obviously, this might not be as robust as a purpose built software package and it offers no remediation, but if you’re after a simple notification system, it should work quite well.

Thanks for reading.

One thought on “Using Event Triggered Tasks to Send Messages to Microsoft Teams

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s