{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion": "1.0.0.0",
        "triggers": {
            "HTTP_Request": {
                "type": "Request",
                "kind": "Http",
                "inputs": {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "incidentId": {
                                "type": "string"
                            },
                            "incidentTitle": {
                                "type": "string"
                            },
                            "incidentTime": {
                                "type": "string"
                            },
                            "hosts": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "HostName": {
                                            "type": "string"
                                        },
                                        "DnsDomain": {
                                            "type": "string"
                                        },
                                        "AzureID": {
                                            "type": "string"
                                        },
                                        "OmsAgentID": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "actions": {
            "Initialize_MDEResults": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDEResults",
                            "type": "array",
                            "value": []
                        }
                    ]
                }
            },
            "Initialize_MDEDeviceTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDEDeviceTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_MDEAlertTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDEAlertTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_MDEProcessTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDEProcessTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_MDENetworkTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDENetworkTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_MDEFileTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDEFileTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_MDELogonTableHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "MDELogonTableHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Initialize_KQLSectionHTML": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "KQLSectionHTML",
                            "type": "string",
                            "value": ""
                        }
                    ]
                }
            },
            "Condition_ValidateKey": {
                "actions": {
                    "For_each_Host_MDE": {
                        "foreach": "@triggerBody()?['hosts']",
                        "actions": {
                            "Compose_HostName": {
                                "type": "Compose",
                                "inputs": "@toLower(coalesce(item()?['HostName'], item()?['hostName'], item()?['properties']?['hostName'], ''))"
                            },
                            "Compose_FQDN": {
                                "runAfter": {
                                    "Compose_HostName": [
                                        "Succeeded"
                                    ]
                                },
                                "type": "Compose",
                                "inputs": "@if(not(equals(coalesce(item()?['DnsDomain'], item()?['dnsDomain'], ''), '')), concat(outputs('Compose_HostName'), '.', toLower(coalesce(item()?['DnsDomain'], item()?['dnsDomain'], ''))), outputs('Compose_HostName'))"
                            },
                            "Get_MDE_Device": {
                                "runAfter": {
                                    "Compose_FQDN": [
                                        "Succeeded"
                                    ]
                                },
                                "type": "Http",
                                "inputs": {
                                    "uri": "@concat('https://api.securitycenter.microsoft.com/api/machines?$filter=computerDnsName+eq+%27', encodeUriComponent(outputs('Compose_FQDN')), '%27&$top=1')",
                                    "method": "GET",
                                    "authentication": {
                                        "type": "ManagedServiceIdentity",
                                        "audience": "https://api.securitycenter.microsoft.com"
                                    }
                                },
                                "runtimeConfiguration": {
                                    "contentTransfer": {
                                        "transferMode": "Chunked"
                                    }
                                }
                            },
                            "Parse_MDE_Device": {
                                "runAfter": {
                                    "Get_MDE_Device": [
                                        "Succeeded",
                                        "Failed"
                                    ]
                                },
                                "type": "ParseJson",
                                "inputs": {
                                    "content": "@body('Get_MDE_Device')",
                                    "schema": {
                                        "type": "object",
                                        "properties": {
                                            "value": {
                                                "type": "array",
                                                "items": {
                                                    "type": "object",
                                                    "properties": {
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "computerDnsName": {
                                                            "type": "string"
                                                        },
                                                        "osPlatform": {
                                                            "type": "string"
                                                        },
                                                        "osVersion": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "lastSeen": {
                                                            "type": "string"
                                                        },
                                                        "healthStatus": {
                                                            "type": "string"
                                                        },
                                                        "onboardingStatus": {
                                                            "type": "string"
                                                        },
                                                        "riskScore": {
                                                            "type": "string"
                                                        },
                                                        "exposureLevel": {
                                                            "type": "string"
                                                        },
                                                        "isAadJoined": {
                                                            "type": [
                                                                "boolean",
                                                                "null"
                                                            ]
                                                        },
                                                        "managedBy": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "managedByStatus": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "rbacGroupName": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "defenderAvStatus": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "ipAddresses": {
                                                            "type": "array"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                            "Compose_Device_Found": {
                                "runAfter": {
                                    "Parse_MDE_Device": [
                                        "Succeeded",
                                        "Failed"
                                    ]
                                },
                                "type": "Compose",
                                "inputs": "@greater(length(coalesce(body('Parse_MDE_Device')?['value'], json('[]'))), 0)"
                            },
                            "Compose_Device_ID": {
                                "runAfter": {
                                    "Compose_Device_Found": [
                                        "Succeeded"
                                    ]
                                },
                                "type": "Compose",
                                "inputs": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['id'], '')"
                            },
                            "Condition_Device_Found": {
                                "actions": {
                                    "Get_MDE_Alerts": {
                                        "type": "Http",
                                        "inputs": {
                                            "uri": "@concat('https://api.securitycenter.microsoft.com/api/machines/', outputs('Compose_Device_ID'), '/alerts?$filter=lastUpdateTime+ge+', formatDateTime(addDays(utcNow(), -7), 'yyyy-MM-ddTHH:mm:ssZ'), '&$top=10&$orderby=lastUpdateTime+desc')",
                                            "method": "GET",
                                            "authentication": {
                                                "type": "ManagedServiceIdentity",
                                                "audience": "https://api.securitycenter.microsoft.com"
                                            }
                                        },
                                        "runtimeConfiguration": {
                                            "contentTransfer": {
                                                "transferMode": "Chunked"
                                            }
                                        }
                                    },
                                    "Get_MDE_LogonUsers": {
                                        "type": "Http",
                                        "inputs": {
                                            "uri": "@concat('https://api.securitycenter.microsoft.com/api/machines/', outputs('Compose_Device_ID'), '/logonusers?$top=10')",
                                            "method": "GET",
                                            "authentication": {
                                                "type": "ManagedServiceIdentity",
                                                "audience": "https://api.securitycenter.microsoft.com"
                                            }
                                        },
                                        "runtimeConfiguration": {
                                            "contentTransfer": {
                                                "transferMode": "Chunked"
                                            }
                                        }
                                    },
                                    "Run_DeviceProcess_KQL": {
                                        "type": "ApiConnection",
                                        "inputs": {
                                            "host": {
                                                "connection": {
                                                    "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                                                }
                                            },
                                            "method": "post",
                                            "body": "@concat('DeviceProcessEvents | where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h) | where DeviceName has \"', outputs('Compose_HostName'), '\" | project TimeGenerated, DeviceName, AccountName, AccountDomain, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, SHA256, FolderPath | order by TimeGenerated desc | take 25')",
                                            "path": "/queryData",
                                            "queries": {
                                                "subscriptions": "<AZURE-SUBSCRIPTION-ID>",
                                                "resourcegroups": "<RESOURCE-GROUP>",
                                                "resourcetype": "Log Analytics Workspace",
                                                "resourcename": "<LOG-ANALYTICS-WORKSPACE>",
                                                "timerange": "7d"
                                            }
                                        }
                                    },
                                    "Run_DeviceNetwork_KQL": {
                                        "type": "ApiConnection",
                                        "inputs": {
                                            "host": {
                                                "connection": {
                                                    "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                                                }
                                            },
                                            "method": "post",
                                            "body": "@concat('DeviceNetworkEvents | where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h) | where DeviceName has \"', outputs('Compose_HostName'), '\" | where ActionType in (\"ConnectionSuccess\", \"ConnectionFailed\", \"ConnectionFound\") | project TimeGenerated, DeviceName, ActionType, RemoteIP, RemoteUrl, RemotePort, LocalIP, LocalPort, Protocol, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName | order by TimeGenerated desc | take 25')",
                                            "path": "/queryData",
                                            "queries": {
                                                "subscriptions": "<AZURE-SUBSCRIPTION-ID>",
                                                "resourcegroups": "<RESOURCE-GROUP>",
                                                "resourcetype": "Log Analytics Workspace",
                                                "resourcename": "<LOG-ANALYTICS-WORKSPACE>",
                                                "timerange": "7d"
                                            }
                                        }
                                    },
                                    "Run_DeviceFile_KQL": {
                                        "type": "ApiConnection",
                                        "inputs": {
                                            "host": {
                                                "connection": {
                                                    "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                                                }
                                            },
                                            "method": "post",
                                            "body": "@concat('DeviceFileEvents | where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h) | where DeviceName has \"', outputs('Compose_HostName'), '\" | where ActionType in (\"FileCreated\", \"FileModified\", \"FileRenamed\") | where FileName endswith \".exe\" or FileName endswith \".ps1\" or FileName endswith \".bat\" or FileName endswith \".cmd\" or FileName endswith \".vbs\" or FileName endswith \".js\" or FileName endswith \".dll\" or FileName endswith \".lnk\" or FileName endswith \".msi\" or FileName endswith \".hta\" | project TimeGenerated, DeviceName, ActionType, FileName, FolderPath, SHA256, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName | order by TimeGenerated desc | take 20')",
                                            "path": "/queryData",
                                            "queries": {
                                                "subscriptions": "<AZURE-SUBSCRIPTION-ID>",
                                                "resourcegroups": "<RESOURCE-GROUP>",
                                                "resourcetype": "Log Analytics Workspace",
                                                "resourcename": "<LOG-ANALYTICS-WORKSPACE>",
                                                "timerange": "7d"
                                            }
                                        }
                                    },
                                    "Run_DeviceAlert_KQL": {
                                        "type": "ApiConnection",
                                        "inputs": {
                                            "host": {
                                                "connection": {
                                                    "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                                                }
                                            },
                                            "method": "post",
                                            "body": "@concat('AlertEvidence | where TimeGenerated > ago(7d) | where DeviceName has \"', outputs('Compose_HostName'), '\" | join kind=inner (AlertInfo | project AlertId, Title, Severity, Category, AttackTechniques, ServiceSource) on AlertId | project TimeGenerated, DeviceName, AlertId, Title, Severity, Category, AttackTechniques, ServiceSource, EntityType, EvidenceRole | order by TimeGenerated desc | take 10')",
                                            "path": "/queryData",
                                            "queries": {
                                                "subscriptions": "<AZURE-SUBSCRIPTION-ID>",
                                                "resourcegroups": "<RESOURCE-GROUP>",
                                                "resourcetype": "Log Analytics Workspace",
                                                "resourcename": "<LOG-ANALYTICS-WORKSPACE>",
                                                "timerange": "7d"
                                            }
                                        }
                                    },
                                    "Compose_RiskBadge": {
                                        "runAfter": {
                                            "Get_MDE_Alerts": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ],
                                            "Get_MDE_LogonUsers": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ],
                                            "Run_DeviceProcess_KQL": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ],
                                            "Run_DeviceNetwork_KQL": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ],
                                            "Run_DeviceFile_KQL": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ],
                                            "Run_DeviceAlert_KQL": [
                                                "Succeeded",
                                                "Failed",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "Compose",
                                        "inputs": "@if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['riskScore'], 'none')), 'high'), '<span style=\"background:#c0392b;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">High</span>', if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['riskScore'], 'none')), 'medium'), '<span style=\"background:#e67e22;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Medium</span>', if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['riskScore'], 'none')), 'low'), '<span style=\"background:#27ae60;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Low</span>', '<span style=\"background:#95a5a6;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">None</span>')))"
                                    },
                                    "Compose_ExposureBadge": {
                                        "runAfter": {
                                            "Compose_RiskBadge": [
                                                "Succeeded"
                                            ]
                                        },
                                        "type": "Compose",
                                        "inputs": "@if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['exposureLevel'], 'none')), 'high'), '<span style=\"background:#c0392b;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">High</span>', if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['exposureLevel'], 'none')), 'medium'), '<span style=\"background:#e67e22;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Medium</span>', if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['exposureLevel'], 'none')), 'low'), '<span style=\"background:#27ae60;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Low</span>', '<span style=\"background:#95a5a6;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">None</span>')))"
                                    },
                                    "Compose_OnboardBadge": {
                                        "runAfter": {
                                            "Compose_ExposureBadge": [
                                                "Succeeded"
                                            ]
                                        },
                                        "type": "Compose",
                                        "inputs": "@if(equals(toLower(coalesce(body('Parse_MDE_Device')?['value']?[0]?['onboardingStatus'], '')), 'onboarded'), '<span style=\"background:#27ae60;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Onboarded</span>', '<span style=\"background:#c0392b;color:#fff;padding:2px 7px;border-radius:3px;font-size:11px\">Not Onboarded</span>')"
                                    },
                                    "Append_Device_HTML_Row": {
                                        "runAfter": {
                                            "Compose_OnboardBadge": [
                                                "Succeeded"
                                            ]
                                        },
                                        "type": "AppendToStringVariable",
                                        "inputs": {
                                            "name": "MDEDeviceTableHTML",
                                            "value": "@concat('<tr><td style=\"padding:6px 10px;border:1px solid #ddd;font-weight:bold;font-family:monospace;font-size:12px\">', outputs('Compose_FQDN'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(body('Parse_MDE_Device')?['value']?[0]?['osPlatform'], 'Unknown'), ' ', coalesce(body('Parse_MDE_Device')?['value']?[0]?['osVersion'], ''), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(body('Parse_MDE_Device')?['value']?[0]?['lastSeen'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd\">', outputs('Compose_OnboardBadge'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd\">', outputs('Compose_RiskBadge'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd\">', outputs('Compose_ExposureBadge'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(body('Parse_MDE_Device')?['value']?[0]?['healthStatus'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(body('Parse_MDE_Device')?['value']?[0]?['managedBy'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', if(equals(string(coalesce(body('Parse_MDE_Device')?['value']?[0]?['isAadJoined'], false)), 'true'), 'Yes', 'No'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(body('Parse_MDE_Device')?['value']?[0]?['rbacGroupName'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px;text-align:center\">', string(length(coalesce(body('Get_MDE_Alerts')?['value'], json('[]')))), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px;text-align:center\">', string(length(coalesce(body('Get_MDE_LogonUsers')?['value'], json('[]')))), '</td></tr>')"
                                        }
                                    },
                                    "For_each_MDE_Alert": {
                                        "foreach": "@coalesce(body('Get_MDE_Alerts')?['value'], json('[]'))",
                                        "actions": {
                                            "Compose_Alert_SeverityBadge": {
                                                "type": "Compose",
                                                "inputs": "@if(equals(toLower(coalesce(item()?['severity'], '')), 'high'), '<span style=\"background:#c0392b;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px\">High</span>', if(equals(toLower(coalesce(item()?['severity'], '')), 'medium'), '<span style=\"background:#e67e22;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px\">Medium</span>', if(equals(toLower(coalesce(item()?['severity'], '')), 'low'), '<span style=\"background:#f1c40f;color:#333;padding:2px 6px;border-radius:3px;font-size:11px\">Low</span>', '<span style=\"background:#95a5a6;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px\">Info</span>')))"
                                            },
                                            "Append_Alert_HTML_Row": {
                                                "runAfter": {
                                                    "Compose_Alert_SeverityBadge": [
                                                        "Succeeded"
                                                    ]
                                                },
                                                "type": "AppendToStringVariable",
                                                "inputs": {
                                                    "name": "MDEAlertTableHTML",
                                                    "value": "@concat('<tr><td style=\"padding:6px 10px;border:1px solid #ddd;font-weight:bold;font-family:monospace;font-size:12px\">', outputs('Compose_FQDN'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['title'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd\">', outputs('Compose_Alert_SeverityBadge'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['category'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['status'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['firstEventTime'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['lastUpdateTime'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px\">', coalesce(item()?['mitreTechniques']?[0], ''), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px\"><a href=\"https://security.microsoft.com/alerts/', coalesce(item()?['id'], ''), '\" style=\"color:#2980b9\">View</a></td></tr>')"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "Append_Device_HTML_Row": [
                                                "Succeeded"
                                            ]
                                        },
                                        "type": "Foreach",
                                        "operationOptions": "Sequential"
                                    },
                                    "For_each_LogonUser": {
                                        "foreach": "@coalesce(body('Get_MDE_LogonUsers')?['value'], json('[]'))",
                                        "actions": {
                                            "Append_Logon_HTML_Row": {
                                                "type": "AppendToStringVariable",
                                                "inputs": {
                                                    "name": "MDELogonTableHTML",
                                                    "value": "@concat('<tr><td style=\"padding:6px 10px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', outputs('Compose_FQDN'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['accountName'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['accountDomain'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['accountType'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['firstSeen'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['lastSeen'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['logonTypes'], 'Unknown'), '</td><td style=\"padding:6px 10px;border:1px solid #ddd;font-size:12px;text-align:center\">', string(coalesce(item()?['logonCount'], 0)), '</td></tr>')"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "For_each_MDE_Alert": [
                                                "Succeeded",
                                                "Failed",
                                                "Skipped",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "Foreach",
                                        "operationOptions": "Sequential"
                                    },
                                    "For_each_Process_Row": {
                                        "foreach": "@coalesce(body('Run_DeviceProcess_KQL')?['value'], json('[]'))",
                                        "actions": {
                                            "Compose_Process_CmdTrunc": {
                                                "type": "Compose",
                                                "inputs": "@substring(coalesce(item()?['ProcessCommandLine'], ''), 0, min(120, length(coalesce(item()?['ProcessCommandLine'], ''))))"
                                            },
                                            "Append_Process_HTML_Row": {
                                                "runAfter": {
                                                    "Compose_Process_CmdTrunc": [
                                                        "Succeeded"
                                                    ]
                                                },
                                                "type": "AppendToStringVariable",
                                                "inputs": {
                                                    "name": "MDEProcessTableHTML",
                                                    "value": "@concat('<tr><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['TimeGenerated'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['DeviceName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['AccountName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['InitiatingProcessFileName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:11px\">', coalesce(item()?['FileName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:11px;word-break:break-all\">', outputs('Compose_Process_CmdTrunc'), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:10px;color:#666\">', coalesce(item()?['SHA256'], ''), '</td></tr>')"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "For_each_LogonUser": [
                                                "Succeeded",
                                                "Failed",
                                                "Skipped",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "Foreach",
                                        "operationOptions": "Sequential"
                                    },
                                    "For_each_Network_Row": {
                                        "foreach": "@coalesce(body('Run_DeviceNetwork_KQL')?['value'], json('[]'))",
                                        "actions": {
                                            "Append_Network_HTML_Row": {
                                                "type": "AppendToStringVariable",
                                                "inputs": {
                                                    "name": "MDENetworkTableHTML",
                                                    "value": "@concat('<tr><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['TimeGenerated'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['DeviceName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['ActionType'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['RemoteIP'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px;word-break:break-all\">', coalesce(item()?['RemoteUrl'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px;text-align:center\">', string(coalesce(item()?['RemotePort'], 0)), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['Protocol'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:11px\">', coalesce(item()?['InitiatingProcessFileName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['InitiatingProcessAccountName'], ''), '</td></tr>')"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "For_each_Process_Row": [
                                                "Succeeded",
                                                "Failed",
                                                "Skipped",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "Foreach",
                                        "operationOptions": "Sequential"
                                    },
                                    "For_each_File_Row": {
                                        "foreach": "@coalesce(body('Run_DeviceFile_KQL')?['value'], json('[]'))",
                                        "actions": {
                                            "Append_File_HTML_Row": {
                                                "type": "AppendToStringVariable",
                                                "inputs": {
                                                    "name": "MDEFileTableHTML",
                                                    "value": "@concat('<tr><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:11px;color:#666\">', coalesce(item()?['TimeGenerated'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['DeviceName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['ActionType'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:12px\">', coalesce(item()?['FileName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:11px;word-break:break-all\">', coalesce(item()?['FolderPath'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:10px;color:#666\">', coalesce(item()?['SHA256'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-family:monospace;font-size:11px\">', coalesce(item()?['InitiatingProcessFileName'], ''), '</td><td style=\"padding:5px 8px;border:1px solid #ddd;font-size:12px\">', coalesce(item()?['InitiatingProcessAccountName'], ''), '</td></tr>')"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "For_each_Network_Row": [
                                                "Succeeded",
                                                "Failed",
                                                "Skipped",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "Foreach",
                                        "operationOptions": "Sequential"
                                    },
                                    "Append_MDE_KQL_Section": {
                                        "runAfter": {
                                            "For_each_File_Row": [
                                                "Succeeded",
                                                "Failed",
                                                "Skipped",
                                                "TimedOut"
                                            ]
                                        },
                                        "type": "AppendToStringVariable",
                                        "inputs": {
                                            "name": "KQLSectionHTML",
                                            "value": "@concat('<div style=\"border-left:4px solid #2980b9;padding:10px 14px;margin-bottom:20px;background:#f8fafd\"><strong style=\"color:#1a5276;font-size:13px\">&#128421; ', outputs('Compose_FQDN'), ' — MDE Queries (±2h incident window)</strong><br><br><strong style=\"font-size:12px;color:#2471a3\">Process Events</strong><br><span style=\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\">DeviceProcessEvents\n| where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h)\n| where DeviceName has \"', outputs('Compose_HostName'), '\"\n| project TimeGenerated, DeviceName, AccountName, AccountDomain, InitiatingProcessFileName,\n  InitiatingProcessCommandLine, FileName, ProcessCommandLine, SHA256, FolderPath\n| order by TimeGenerated desc | take 25</span><br><br><strong style=\"font-size:12px;color:#2471a3\">Network Events</strong><br><span style=\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\">DeviceNetworkEvents\n| where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h)\n| where DeviceName has \"', outputs('Compose_HostName'), '\"\n| where ActionType in (\"ConnectionSuccess\", \"ConnectionFailed\", \"ConnectionFound\")\n| project TimeGenerated, DeviceName, ActionType, RemoteIP, RemoteUrl, RemotePort,\n  LocalIP, LocalPort, Protocol, InitiatingProcessFileName, InitiatingProcessCommandLine,\n  InitiatingProcessAccountName\n| order by TimeGenerated desc | take 25</span><br><br><strong style=\"font-size:12px;color:#2471a3\">Suspicious File Events</strong><br><span style=\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\">DeviceFileEvents\n| where TimeGenerated between(datetime(', triggerBody()?['incidentTime'], ') - 2h .. datetime(', triggerBody()?['incidentTime'], ') + 2h)\n| where DeviceName has \"', outputs('Compose_HostName'), '\"\n| where ActionType in (\"FileCreated\", \"FileModified\", \"FileRenamed\")\n| where FileName endswith \".exe\" or FileName endswith \".ps1\" or FileName endswith \".bat\"\n  or FileName endswith \".cmd\" or FileName endswith \".vbs\" or FileName endswith \".js\"\n  or FileName endswith \".dll\" or FileName endswith \".lnk\" or FileName endswith \".msi\"\n  or FileName endswith \".hta\"\n| project TimeGenerated, DeviceName, ActionType, FileName, FolderPath, SHA256,\n  InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName\n| order by TimeGenerated desc | take 20</span><br><br><strong style=\"font-size:12px;color:#2471a3\">Alert Evidence (7d)</strong><br><span style=\"font-family:Consolas,Courier New,monospace;font-size:11px;color:#1c2833;white-space:pre\">AlertEvidence\n| where TimeGenerated > ago(7d)\n| where DeviceName has \"', outputs('Compose_HostName'), '\"\n| join kind=inner (AlertInfo | project AlertId, Title, Severity, Category, AttackTechniques, ServiceSource) on AlertId\n| project TimeGenerated, DeviceName, AlertId, Title, Severity, Category,\n  AttackTechniques, ServiceSource, EntityType, EvidenceRole\n| order by TimeGenerated desc | take 10</span></div>')"
                                        }
                                    },
                                    "Append_MDE_Result_Found": {
                                        "runAfter": {
                                            "Append_MDE_KQL_Section": [
                                                "Succeeded"
                                            ]
                                        },
                                        "type": "AppendToArrayVariable",
                                        "inputs": {
                                            "name": "MDEResults",
                                            "value": {
                                                "hostName": "@outputs('Compose_FQDN')",
                                                "deviceId": "@outputs('Compose_Device_ID')",
                                                "osPlatform": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['osPlatform'], 'Unknown')",
                                                "osVersion": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['osVersion'], 'Unknown')",
                                                "lastSeen": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['lastSeen'], 'Unknown')",
                                                "healthStatus": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['healthStatus'], 'Unknown')",
                                                "onboardingStatus": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['onboardingStatus'], 'Unknown')",
                                                "riskScore": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['riskScore'], 'None')",
                                                "exposureLevel": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['exposureLevel'], 'None')",
                                                "isAadJoined": "@string(coalesce(body('Parse_MDE_Device')?['value']?[0]?['isAadJoined'], false))",
                                                "managedBy": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['managedBy'], 'Unknown')",
                                                "rbacGroupName": "@coalesce(body('Parse_MDE_Device')?['value']?[0]?['rbacGroupName'], 'Unknown')",
                                                "mdeFound": true,
                                                "activeAlerts": "@coalesce(body('Get_MDE_Alerts')?['value'], json('[]'))",
                                                "activeAlertCount": "@length(coalesce(body('Get_MDE_Alerts')?['value'], json('[]')))",
                                                "logonUsers": "@coalesce(body('Get_MDE_LogonUsers')?['value'], json('[]'))",
                                                "logonUserCount": "@length(coalesce(body('Get_MDE_LogonUsers')?['value'], json('[]')))",
                                                "processEvents": "@coalesce(body('Run_DeviceProcess_KQL')?['value'], json('[]'))",
                                                "processEventCount": "@length(coalesce(body('Run_DeviceProcess_KQL')?['value'], json('[]')))",
                                                "networkEvents": "@coalesce(body('Run_DeviceNetwork_KQL')?['value'], json('[]'))",
                                                "networkEventCount": "@length(coalesce(body('Run_DeviceNetwork_KQL')?['value'], json('[]')))",
                                                "fileEvents": "@coalesce(body('Run_DeviceFile_KQL')?['value'], json('[]'))",
                                                "fileEventCount": "@length(coalesce(body('Run_DeviceFile_KQL')?['value'], json('[]')))",
                                                "alertEvidenceEvents": "@coalesce(body('Run_DeviceAlert_KQL')?['value'], json('[]'))",
                                                "alertEvidenceEventCount": "@length(coalesce(body('Run_DeviceAlert_KQL')?['value'], json('[]')))"
                                            }
                                        }
                                    }
                                },
                                "runAfter": {
                                    "Compose_Device_ID": [
                                        "Succeeded"
                                    ]
                                },
                                "else": {
                                    "actions": {
                                        "Append_Device_HTML_Row_NotFound": {
                                            "type": "AppendToStringVariable",
                                            "inputs": {
                                                "name": "MDEDeviceTableHTML",
                                                "value": "@concat('<tr style=\"background:#fff3cd\"><td style=\"padding:6px 10px;border:1px solid #ddd;font-family:monospace;font-size:12px;color:#856404\">', outputs('Compose_FQDN'), '</td><td colspan=\"11\" style=\"padding:6px 10px;border:1px solid #ddd;text-align:center\"><span style=\"color:orange\">&#9888; Device not found in MDE — may not be onboarded or hostname did not match</span></td></tr>')"
                                            }
                                        },
                                        "Append_MDE_KQL_NotFound": {
                                            "runAfter": {
                                                "Append_Device_HTML_Row_NotFound": [
                                                    "Succeeded"
                                                ]
                                            },
                                            "type": "AppendToStringVariable",
                                            "inputs": {
                                                "name": "KQLSectionHTML",
                                                "value": "@concat('<div style=\"border-left:4px solid #f39c12;padding:8px 14px;margin-bottom:12px;background:#fffdf0\"><span style=\"color:#7d6608;font-size:12px\">&#9888; <strong>', outputs('Compose_FQDN'), '</strong> — not found in MDE — device may not be onboarded. KQL queries not executed.</span></div>')"
                                            }
                                        },
                                        "Append_MDE_Result_NotFound": {
                                            "runAfter": {
                                                "Append_MDE_KQL_NotFound": [
                                                    "Succeeded"
                                                ]
                                            },
                                            "type": "AppendToArrayVariable",
                                            "inputs": {
                                                "name": "MDEResults",
                                                "value": {
                                                    "hostName": "@outputs('Compose_FQDN')",
                                                    "mdeFound": false,
                                                    "activeAlertCount": 0,
                                                    "processEventCount": 0,
                                                    "networkEventCount": 0,
                                                    "fileEventCount": 0,
                                                    "alertEvidenceEventCount": 0
                                                }
                                            }
                                        }
                                    }
                                },
                                "expression": {
                                    "and": [
                                        {
                                            "equals": [
                                                "@outputs('Compose_Device_Found')",
                                                true
                                            ]
                                        }
                                    ]
                                },
                                "type": "If"
                            }
                        },
                        "type": "Foreach",
                        "operationOptions": "Sequential"
                    },
                    "Response_Success": {
                        "runAfter": {
                            "For_each_Host_MDE": [
                                "Succeeded",
                                "Failed",
                                "Skipped",
                                "TimedOut"
                            ]
                        },
                        "type": "Response",
                        "kind": "Http",
                        "inputs": {
                            "statusCode": 200,
                            "headers": {
                                "Content-Type": "application/json"
                            },
                            "body": {
                                "mdeDeviceTableHTML": "@variables('MDEDeviceTableHTML')",
                                "mdeAlertTableHTML": "@variables('MDEAlertTableHTML')",
                                "mdeProcessTableHTML": "@variables('MDEProcessTableHTML')",
                                "mdeNetworkTableHTML": "@variables('MDENetworkTableHTML')",
                                "mdeFileTableHTML": "@variables('MDEFileTableHTML')",
                                "mdeLogonTableHTML": "@variables('MDELogonTableHTML')",
                                "kqlSectionHTML": "@variables('KQLSectionHTML')",
                                "results": "@variables('MDEResults')"
                            }
                        }
                    }
                },
                "runAfter": {
                    "Initialize_MDEResults": [
                        "Succeeded"
                    ],
                    "Initialize_MDEDeviceTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_MDEAlertTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_MDEProcessTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_MDENetworkTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_MDEFileTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_MDELogonTableHTML": [
                        "Succeeded"
                    ],
                    "Initialize_KQLSectionHTML": [
                        "Succeeded"
                    ]
                },
                "else": {
                    "actions": {
                        "Response_Unauthorized": {
                            "type": "Response",
                            "kind": "Http",
                            "inputs": {
                                "statusCode": 401,
                                "body": {
                                    "error": "Unauthorized - invalid worker key"
                                }
                            }
                        }
                    }
                },
                "expression": {
                    "and": [
                        {
                            "equals": [
                                "@triggerOutputs()?['headers']?['x-worker-key']",
                                "@parameters('WorkerSharedKey')"
                            ]
                        }
                    ]
                },
                "type": "If"
            }
        },
        "outputs": {},
        "parameters": {
            "WorkerSharedKey": {
                "defaultValue": "<WORKER-SHARED-KEY>",
                "type": "String"
            },
            "$connections": {
                "type": "Object",
                "defaultValue": {}
            }
        }
    },
    "parameters": {
        "$connections": {
            "type": "Object",
            "value": {
                "azuremonitorlogs": {
                    "id": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/providers/Microsoft.Web/locations/westus2/managedApis/azuremonitorlogs",
                    "connectionId": "/subscriptions/<AZURE-SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Web/connections/azuremonitorlogs-1",
                    "connectionName": "azuremonitorlogs-1",
                    "connectionProperties": {}
                }
            }
        }
    }
}