Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Power Apps - Multiple apps deleted

Back
Ided88638d-8627-4c20-ba08-67c13807a9b1
RulenamePower Apps - Multiple apps deleted
DescriptionIdentifies mass delete activity where multiple Power Apps are deleted, matching a predefined threshold of total apps deleted or app delete events across multiple Power Platform environments.
SeverityMedium
TacticsImpact
TechniquesT1485
T0826
Required data connectorsPowerPlatformAdmin
KindScheduled
Query frequency1h
Query period7d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Power Apps - Multiple apps deleted.yaml
Version3.2.0
Arm templateed88638d-8627-4c20-ba08-67c13807a9b1.json
Deploy To Azure
let total_app_mass_delete_threshold = 25;
let cross_environment_delete_threshold = 10;
let query_frequency = 1h;
let app_delete_events = materialize(
    PowerPlatformAdminActivity
    | where TimeGenerated >= ago (query_frequency)
    | where EventOriginalType == "DeletePowerApp"
    | extend Properties = tostring(PropertyCollection)
    | extend AppId = extract(@'"powerplatform.analytics.resource.power_app.id","Value":"([^"]+)"', 1, Properties)
    | extend AppId = tolower(replace_string(AppId, '/providers/Microsoft.PowerApps/apps/', ''))
    | extend EnvironmentId = extract(@'"powerplatform.analytics.resource.environment.id","Value":"([^"]+)"', 1, Properties)
    );
app_delete_events
| summarize AppCount = count(), EnvCount = dcount(EnvironmentId) by ActorName
| where AppCount >= total_app_mass_delete_threshold or EnvCount >= cross_environment_delete_threshold
| join kind=inner app_delete_events on ActorName
| summarize
    Apps = make_set(AppId, 1000),
    Environments = make_set(EnvironmentId, 1000),
    StartTime = min(TimeGenerated)
    by AppCount, EnvCount, ActorName
| extend
    PowerAppsEntityId = 27593,
    DataverseId = 32780,
    AccountName = tostring(split(ActorName, '@')[0]),
    UPNSuffix = tostring(split(ActorName, '@')[1])
| project
    StartTime,
    ActorName,
    AppCount,
    Apps,
    EnvCount,
    Environments,
    PowerAppsEntityId,
    DataverseId,
    AccountName,
    UPNSuffix
triggerThreshold: 0
query: |
  let total_app_mass_delete_threshold = 25;
  let cross_environment_delete_threshold = 10;
  let query_frequency = 1h;
  let app_delete_events = materialize(
      PowerPlatformAdminActivity
      | where TimeGenerated >= ago (query_frequency)
      | where EventOriginalType == "DeletePowerApp"
      | extend Properties = tostring(PropertyCollection)
      | extend AppId = extract(@'"powerplatform.analytics.resource.power_app.id","Value":"([^"]+)"', 1, Properties)
      | extend AppId = tolower(replace_string(AppId, '/providers/Microsoft.PowerApps/apps/', ''))
      | extend EnvironmentId = extract(@'"powerplatform.analytics.resource.environment.id","Value":"([^"]+)"', 1, Properties)
      );
  app_delete_events
  | summarize AppCount = count(), EnvCount = dcount(EnvironmentId) by ActorName
  | where AppCount >= total_app_mass_delete_threshold or EnvCount >= cross_environment_delete_threshold
  | join kind=inner app_delete_events on ActorName
  | summarize
      Apps = make_set(AppId, 1000),
      Environments = make_set(EnvironmentId, 1000),
      StartTime = min(TimeGenerated)
      by AppCount, EnvCount, ActorName
  | extend
      PowerAppsEntityId = 27593,
      DataverseId = 32780,
      AccountName = tostring(split(ActorName, '@')[0]),
      UPNSuffix = tostring(split(ActorName, '@')[1])
  | project
      StartTime,
      ActorName,
      AppCount,
      Apps,
      EnvCount,
      Environments,
      PowerAppsEntityId,
      DataverseId,
      AccountName,
      UPNSuffix  
customDetails:
  EnvironmentsImpacted: Environments
  EnvironmentsCount: EnvCount
  AppDeleteCount: AppCount
  AppsDeleted: Apps
relevantTechniques:
- T1485
- T0826
tactics:
- Impact
entityMappings:
- fieldMappings:
  - identifier: AppId
    columnName: PowerAppsEntityId
  entityType: CloudApplication
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
eventGroupingSettings:
  aggregationKind: SingleAlert
requiredDataConnectors:
- dataTypes:
  - PowerPlatformAdminActivity
  connectorId: PowerPlatformAdmin
kind: Scheduled
queryPeriod: 7d
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Power Apps - Multiple apps deleted.yaml
severity: Medium
id: ed88638d-8627-4c20-ba08-67c13807a9b1
version: 3.2.0
description: Identifies mass delete activity where multiple Power Apps are deleted, matching a predefined threshold of total apps deleted or app delete events across multiple Power Platform environments.
triggerOperator: gt
alertDetailsOverride:
  alertDisplayNameFormat: Power Apps - mass deletion of apps
  alertDescriptionFormat: '{{AppCount}} apps were deleted in {{EnvCount}} environments by {{ActorName}} , exceeding the mass delete threshold.'
name: Power Apps - Multiple apps deleted
status: Available
queryFrequency: 1h
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/ed88638d-8627-4c20-ba08-67c13807a9b1')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/ed88638d-8627-4c20-ba08-67c13807a9b1')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "{{AppCount}} apps were deleted in {{EnvCount}} environments by {{ActorName}} , exceeding the mass delete threshold.",
          "alertDisplayNameFormat": "Power Apps - mass deletion of apps"
        },
        "alertRuleTemplateName": "ed88638d-8627-4c20-ba08-67c13807a9b1",
        "customDetails": {
          "AppDeleteCount": "AppCount",
          "AppsDeleted": "Apps",
          "EnvironmentsCount": "EnvCount",
          "EnvironmentsImpacted": "Environments"
        },
        "description": "Identifies mass delete activity where multiple Power Apps are deleted, matching a predefined threshold of total apps deleted or app delete events across multiple Power Platform environments.",
        "displayName": "Power Apps - Multiple apps deleted",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "PowerAppsEntityId",
                "identifier": "AppId"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "SingleAlert"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Power Apps - Multiple apps deleted.yaml",
        "query": "let total_app_mass_delete_threshold = 25;\nlet cross_environment_delete_threshold = 10;\nlet query_frequency = 1h;\nlet app_delete_events = materialize(\n    PowerPlatformAdminActivity\n    | where TimeGenerated >= ago (query_frequency)\n    | where EventOriginalType == \"DeletePowerApp\"\n    | extend Properties = tostring(PropertyCollection)\n    | extend AppId = extract(@'\"powerplatform.analytics.resource.power_app.id\",\"Value\":\"([^\"]+)\"', 1, Properties)\n    | extend AppId = tolower(replace_string(AppId, '/providers/Microsoft.PowerApps/apps/', ''))\n    | extend EnvironmentId = extract(@'\"powerplatform.analytics.resource.environment.id\",\"Value\":\"([^\"]+)\"', 1, Properties)\n    );\napp_delete_events\n| summarize AppCount = count(), EnvCount = dcount(EnvironmentId) by ActorName\n| where AppCount >= total_app_mass_delete_threshold or EnvCount >= cross_environment_delete_threshold\n| join kind=inner app_delete_events on ActorName\n| summarize\n    Apps = make_set(AppId, 1000),\n    Environments = make_set(EnvironmentId, 1000),\n    StartTime = min(TimeGenerated)\n    by AppCount, EnvCount, ActorName\n| extend\n    PowerAppsEntityId = 27593,\n    DataverseId = 32780,\n    AccountName = tostring(split(ActorName, '@')[0]),\n    UPNSuffix = tostring(split(ActorName, '@')[1])\n| project\n    StartTime,\n    ActorName,\n    AppCount,\n    Apps,\n    EnvCount,\n    Environments,\n    PowerAppsEntityId,\n    DataverseId,\n    AccountName,\n    UPNSuffix\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P7D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Impact"
        ],
        "techniques": [
          "T1485"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}