Automate your Sentinel incident triage

Koos Goossens
8 min readMar 24, 2022

…by enriching them with the help of VirusTotal

Thank you VirusTotal-bot! I’ll happily take that scan report off your hands.


Once a security incident is raised, and triage begins, our security analysts often take very similar steps during their investigations.

Automation might be able to help to shorten investigations, bring down ‘alert fatigue’ and in turn make sure your analysts have more time to make your organization even safer.

In this article I’ll demonstrate how to leverage VirusTotal’s services to automatically scan all of your file hashes and IP addresses that come through Microsoft Sentinel as entities in their respective incidents. The scan results are then automatically attached to the security incidents so that your analysts see the reputation and other details in an instant, without having to go out and retrieve this information themselves.

Let your SIEM SOAR like an eagle

When you read and listen about Microsoft Sentinel the term “SOAR” most likely came to your attention a couple of times. But what is SOAR?

SOAR stands for Security Orchestration Automated Response and it refers to the technologies used to take away some of the load of analyst working at your SOC. (Security Operations Center)

A different kind of soar

The orchestration part refers to the various log integrations and centralized management. Think for example of multiple log sources coming into multiple Sentinel workspaces across multiple Azure regions, but still keep one centralized aggregated view of all security incidents.

The automated response part can be broader. Where individual tasks, your analysts might perform, can be automated. From the start of the triage all the way to closing the investigation. Examples of this can be retrieving additional sign-in information about a user, disabling user accounts, resetting passwords, blocking ports on a firewall or opening up a ticket in an external application.

Microsoft leverages their Azure Logic App technology to let you create playbooks for these automations. This is great because you can make use of hundreds of different connectors already available to integrate with your existing solutions like Microsoft 365, ServiceNow and Teams. And you can even create your own custom connectors for your own custom applications.

Alert fatigue is real. Security analysts face a huge burden of triage as they not only have to sift through a sea of alerts, but also correlate alerts from different products and repeat similar investigations steps over and over again.

By automating repetitive, time-consuming tasks, you can lower this burden and let your security analysts focus on stopping more sophisticated attacks and make your SOC run more efficient.


One example of a common repetitive tasks is copying and pasting over evidence, like when checking the reputation of a URL, file and/or IP address. A very popular service to use for this is VirusTotal, a website created by the Spanish security company Hispasec Sistemas and launched in 2004. It has switched ownership to Google back in 2012.

To check the reputation of your file, URL or IP, VirusTotal uses a aggregated set of anti-virus products and other online scan engines which they call “contributors”. Their list of companies that have integrated their services is quite impressive!

VirusTotal’s homepage which let you upload and search for file hashes, URLs and IP addresses

What’s also great about VirusTotal is that they provide you an API for automated submissions and even a Logic App Connector to get started quickly.

You can easily request an API key free of use for testing purposes only. Please read their detailed documentation about public vs premium pricing tiers.

Create a playbook

Before we can define our automation steps in Sentinel, we need to have created a playbook first.

Deploy an Azure Logic App straight from the Azure Portal or from the automation blade in Sentinel:

Make sure you use the correct trigger!

It’s important that the workflow starts with an “incident trigger” instead of an “alert trigger”. This is because we want to assign this playbook later with a global automation rule, where only playbooks with the former can be selected.

The two different triggers available for Microsoft Sentinel

After the incident is passed into the workflow of the Logic App, the general overview looks like this:

General overview of how the VirusTotal enrichment of incidents can look like
  1. First the entities are retrieved from the incident in Sentinel. Luckily Microsoft recently provided us with some new additions like these “Get IPs” and “Get FileHashes” steps so that you don’t have to sort the entities yourself anymore. Hooray!
  2. Next, it will loop through all IP addresses and file hashes in parallel. (There might be more than one entity of each kind)
  3. Looking up IP addresses is a bit simpler than file hashes so I only had to put a VirusTotal step here and an “Add comment to incident” step, which will add the output from the scan to the incident. More on this later…
    Once your add a VirusTotal step for the first time, it will ask you for your API key. Follow these steps on the VirusTotal website to get started.
  4. With file hashes I had to implement an extra step. With Microsoft security products, like Defender for Endpoint, you generally are provided with both the SHA1 and SHA256 hashes of the files related to the incident. This means that the VirusTotal lookup will be running twice for every file, and you’ll end up with duplicate reports in your incident.
    To work around this, I’ve created an array variable right before the loop starts. The scan step will still be performed twice, but before the report is added to the incident there will be a check if this array variable already contains the report or not. If it does not contain a report then the incident in Sentinel is added and contents of the report is added to the variable. For the next run this step is skipped. Thanks to Jesper Keijzer for this tip!
The variable ‘reported_ids’ is used to determine if a scan report was already made for a particular file hash

You can find my full Logic App workflow on my Github page here!
Here you’ll also find the html files and PowerShell code mentioned below.

Save the report in your incident

The results from the VirusTotal scan are saved as a comment in the incident in Sentinel. For this step we can even leverage an html formatted message to make it look nice as well.

Last month Microsoft also increased the total character limit for comments to 30K, which makes it possible to use graphics now as well. Nice!

Example VirusTotal report as a comment inside the Sentinel incident

Editing html for your comment inside the Logic App designer is not ideal because it will not render the html properly. And the preview might look completely of as a result. That why I’d advise to switch over to the code view instead, and paste in the html code as the message value there.

Example of a html formatted comment. Keep in mind that JSON needs some escaping for special characters
The html formatted comment from code view might might look awkward in the workflow editor

Construct your comments in html dynamically

Constructing html inside the code view of a playbook can be a bit cumbersome as well. And because of the JSON nature of the code definition of a playbook, you need to be careful with escape character for some special character. Lastly, the message value should be formatted as one single string.

To work around this I first made sure the html document looks correct (in for example VScode) and then converted the contents into a JSON formatted string to paste into the code view.

In this particular case with VirusTotal the value for sigma_analysis_data is not always provided and depending on the file hash processed. This might result in some empty tables and a less clean layout as a result.

Using an html format also gives us the ability to use some more ‘advanced’ html functions like if() and concat(). This can be extremely useful to make your comments more dynamic depending on the outcome of previous steps. Thanks again to Jesper Keijzer for this awesome tip!

Example of an if() statement used to dynamically construct the comment message

Copying and pasting over the html contents into the JSON formatted code view can be done in several ways. But the easiest way might be by using PowerShell. This step can also be integrated into your Infrastructure-as-Code pipelines where you define your detections, playbooks and automation rules as code and deploy them into Sentinel.

This makes it easier to update the comment message if you need to. Just update the easier-readable html file and the pipeline can make sure these contents get pushed as parameter values for the playbook deployment.

$jsonString = (Get-Content ./logicapp-enrich-incident-virustotal-filehash-comment.html -Raw) -replace "`r`n" | ConvertTo-JsonWrite-Host $jsonString

On my Github page you’ll find all examples mentioned in this article to import and interact with yourself.

Sentinel automation rules

To automatically trigger your newly created playbook, you need to create an automation rule in Sentinel. For this you’ll need to open the “Automation” blade → “Create” → “Automation rule”:

In this example all incidents created by Defender for Endpoint will trigger a ‘Run playbook’ action (because those most likely contains file hashes and IP addresses) and also a tag ‘enriched’ will be added to the incident
By making sure your automation tasks add tags, these incidents are better visible


I hope this article gave a clear understanding of how Sentinel automation and playbooks with Logic App can help your security team be more efficient. I hope this sparked enough interest to get started and to try out other integrations as well.

If you do, please drop me a comment and let me know what automation steps you would like to see to lower your teams alert fatigue as well!

Thank you for reading!

— Koos



Koos Goossens

Microsoft Security MVP | Photographer | Watch nerd | Pinball enthusiast | BBQ Grillmaster