Search And Delete Emails - Microsoft Graph Security

This playbook performs the following steps: 1. Checks that the Microsoft Graph integration is available and active. 2. Lists existing eDiscovery cases and finds the specified case, or creates it if missing. 3. Composes the KQL content query based on the mailbox scope (recipientsOnly, allTenantMailboxes, or other). 4. Creates a new eDiscovery search with the composed query, or reuses an existing search based on the force input. 5. Runs an estimate statistics operation to count emails matching the query. 6. Waits for the estimate operation to complete and checks whether any emails were found. 7. Optionally previews the results (statistics summary or full export), based on the preview input. 8. Purges the matching emails (Hard delete / Soft delete / manual analyst approval). 9. Cleans up the eDiscovery search based on the cleanup input.

Microsoft Graph Security · 58 tasks · 13 inputs · 0 outputs

Details

IDSearch And Delete Emails - Microsoft Graph Security
From Version6.10.0
Tasks58

README

This playbook performs the following steps:

  1. Checks that the Microsoft Graph integration is available and active.
  2. Lists existing eDiscovery cases and finds the specified case, or creates it if missing.
  3. Composes the KQL content query based on the mailbox scope (recipientsOnly, allTenantMailboxes, or other).
  4. Creates a new eDiscovery search with the composed query, or reuses an existing search based on the force input.
  5. Runs an estimate statistics operation to count emails matching the query.
  6. Waits for the estimate operation to complete and checks whether any emails were found.
  7. Optionally previews the results (statistics summary or full export), based on the preview input.
  8. Purges the matching emails (Hard delete / Soft delete / manual analyst approval).
  9. Cleans up the eDiscovery search based on the cleanup input.

Dependencies

This playbook uses the following sub-playbooks, integrations, and scripts.

Sub-playbooks

This playbook does not use any sub-playbooks.

Integrations

  • MicrosoftGraphSecurity

Scripts

  • IsIntegrationAvailable
  • Print
  • Set

Commands

  • msg-create-ediscovery-case
  • msg-create-ediscovery-search
  • msg-delete-ediscovery-search
  • msg-export-result-ediscovery-data
  • msg-get-last-estimate-statistics-operation
  • msg-list-case-operation
  • msg-list-ediscovery-cases
  • msg-list-ediscovery-searchs
  • msg-purge-ediscovery-data
  • msg-run-estimate-statistics

Playbook Inputs


Name Description Default Value Required
case eDiscovery case to use. Looked up by name; created if missing. XSOAR Auto Phishing Required
mailbox_scope One of: recipientsOnly, allTenantMailboxes, allCaseCustodians, allCaseNoncustodialDataSources, allTenantSites. Drives data_source_scopes and KQL composition. recipientsOnly Optional
mailbox_exclusion CSV of mailboxes to exclude. Honored only when mailbox_scope=allTenantMailboxes.   Optional
kql KQL query identifying the emails to search/delete. Additional clauses are composed around it depending on mailbox_scope.   Required
recipients CSV of email addresses. Required when mailbox_scope=recipientsOnly. Optional when mailbox_scope=allCaseCustodians.   Optional
search_name When provided, plays into the force semantics (force=true delete-and-recreate, force=false reuse). When omitted, an auto-name like XSOAR-Search-${incident.id}-${ts} is generated.   Optional
description eDiscovery search description. Defaults to “Created by XSOAR for incident ${incident.id}” when empty.   Optional
force Only meaningful when search_name is provided. true ⇒ delete-and-recreate. false ⇒ reuse existing. false Optional
preview “true” / “false” / empty=manual. Whether to pause for analyst review before delete. true Optional
preview_mode “statistics” (count + size from estimate) or “export” (run export job, download report). statistics Optional
export_format File format for the export when preview_mode=export. “msg” produces individual .msg files inside a ZIP (preferred for analyst review). “pst” produces a single PST archive. Ignored when preview_mode=statistics. msg Optional
delete_type “Hard” / “Soft” / empty=manual (also lets analyst pick Skip).   Optional
cleanup “auto” / “true” / “false”. auto ⇒ delete the search only if it was auto-generated. auto Optional

Playbook Outputs


There are no outputs for this playbook.

Playbook Image


Search And Delete Emails - Microsoft Graph Security

Inputs

  • case — eDiscovery case to use. Looked up by name; created if missing.
  • mailbox_scope — One of: recipientsOnly, allTenantMailboxes, allCaseCustodians, allCaseNoncustodialDataSources, allTenantSites. Drives data_source_scopes and KQL composition.
  • kql — KQL query identifying the emails to search/delete. Additional clauses are composed around it depending on mailbox_scope.
  • recipients — CSV of email addresses. Required when mailbox_scope=recipientsOnly. Optional when mailbox_scope=allCaseCustodians.
  • mailbox_exclusion — CSV of mailboxes to exclude. Honored only when mailbox_scope=allTenantMailboxes.
  • search_name — When provided, plays into the force semantics (force=true delete-and-recreate, force=false reuse). When omitted, an auto-name like XSOAR-Search-${incident.id}-${ts} is generated.
  • description — eDiscovery search description. Defaults to "Created by XSOAR for incident ${incident.id}" when empty.
  • force — Only meaningful when search_name is provided. true ⇒ delete-and-recreate. false ⇒ reuse existing.
  • preview — "true" / "false" / empty=manual. Whether to pause for analyst review before delete.
  • preview_mode — "statistics" (count + size from estimate) or "export" (run export job, download report).
  • export_format — File format for the export when preview_mode=export. "msg" produces individual .msg files inside a ZIP (preferred for analyst review). "pst" produces a single PST archive. Ignored when preview_mode=statistics.
  • delete_type — "Hard" / "Soft" / empty=manual (also lets analyst pick Skip).
  • cleanup — "auto" / "true" / "false". auto ⇒ delete the search only if it was auto-generated.

Commands used

msg-create-ediscovery-case msg-create-ediscovery-search msg-delete-ediscovery-search msg-export-result-ediscovery-data msg-get-last-estimate-statistics-operation msg-list-case-operation msg-list-ediscovery-cases msg-list-ediscovery-searchs msg-purge-ediscovery-data msg-run-estimate-statistics

Flowchart

yes Create new case Reuse existing case allTenantMailboxes recipientsOnly Exclusion not provided Exclusion provided Create new search Reuse existing search yes Delete existing search false export statistics #error# #error# hard manual soft #error# #error# auto delete hard soft #error# Email found Preview false manual Preview export false Generate new description Reuse existing description yes Start Start Check Microsoft Graph integration is available - IsIntegrationAvailable Check Microsoft Graph int... IsIntegrationAvailable Done Done List eDiscovery cases - msg-list-ediscovery-cases List eDiscovery cases msg-list-ediscovery-cases Does the specified eDiscovery case exist? Does the specified eDisco... Create eDiscovery case - msg-create-ediscovery-case Create eDiscovery case msg-create-ediscovery-case Route by mailbox scope Route by mailbox scope Build participants clause - Set Build participants clause Set Is a mailbox exclusion list provided? Is a mailbox exclusion li... Was a custom search name provided? Was a custom search name ... List eDiscovery searches in case - msg-list-ediscovery-searchs List eDiscovery searches ... msg-list-ediscovery-searchs Does a matching eDiscovery search already exist? Does a matching eDiscover... Re-create or reuse existing search? Re-create or reuse existi... Delete existing search - msg-delete-ediscovery-search Delete existing search msg-delete-ediscovery-search Retrieve search ID from existing search - Set Retrieve search ID from e... Set Create eDiscovery search - msg-create-ediscovery-search Create eDiscovery search msg-create-ediscovery-search Run estimate statistics - msg-run-estimate-statistics Run estimate statistics msg-run-estimate-statistics Should results be previewed before purging? Should results be preview... Display estimate statistics - Print Display estimate statistics Print Start export task - msg-export-result-ediscovery-data Start export task msg-export-result-ediscovery-... Download export file - msg-list-case-operation Download export file msg-list-case-operation How should the matched emails be purged? How should the matched em... Permanently delete matched emails - msg-purge-ediscovery-data Permanently delete matche... msg-purge-ediscovery-data Move matched emails to recoverable items - msg-purge-ediscovery-data Move matched emails to re... msg-purge-ediscovery-data Should the eDiscovery search be cleaned up? Should the eDiscovery sea... Delete eDiscovery search - msg-delete-ediscovery-search Delete eDiscovery search msg-delete-ediscovery-search Analyst: select purge type or skip Analyst: select purge typ... Wait for estimate statistics to complete - msg-get-last-estimate-statistics-operation Wait for estimate statist... msg-get-last-estimate-statist... Purge Emails Purge Emails Preview Results Preview Results Cleanup eDiscovery Search Cleanup eDiscovery Search Is any email found? Is any email found? Print no emails found - Print Print no emails found Print Finalize the email search query - Set Finalize the email search... Set Set scope: all tenant mailboxes (recipients filter) - Set Set scope: all tenant mai... Set Use provided KQL query as-is (no exclusion) - Set Use provided KQL query as... Set Build exclusion clause - Set Build exclusion clause Set Wrap KQL query for exclusion filtering - Set Wrap KQL query for exclus... Set Set DataSourceScopes - Set Set DataSourceScopes Set Set scope: all tenant mailboxes (no exclusion) - Set Set scope: all tenant mai... Set Use provided KQL query as-is (whole-tenant scope) - Set Use provided KQL query as... Set Set scope: custom mailbox scope from input - Set Set scope: custom mailbox... Set Store found case ID - Set Store found case ID Set Add recipients filter to KQL query - Set Add recipients filter to ... Set Add exclusion clause to KQL query - Set Add exclusion clause to K... Set Generate search name automatically - Set Generate search name auto... Set Which preview mode should be used? Which preview mode should... Analyst: confirm whether to preview found emails Analyst: confirm whether ... Save resolved search name - Set Save resolved search name Set Was a custom search description provided? Was a custom search descr... Generate default search description - Set Generate default search d... Set Save provided search description - Set Save provided search desc... Set Store newly created search ID - Set Store newly created searc... Set Store newly created case ID - Set Store newly created case ID Set Store found search ID - Set Store found search ID Set Notify: export results are not yet ready - Print Notify: export results ar... Print Run Search Statistics Run Search Statistics Was the search auto-generated? Was the search auto-gener...
id: Search And Delete Emails - Microsoft Graph Security
version: -1
name: Search And Delete Emails - Microsoft Graph Security
description: |-
  This playbook performs the following steps:
    1. Checks that the Microsoft Graph integration is available and active.
    2. Lists existing eDiscovery cases and finds the specified case, or creates it if missing.
    3. Composes the KQL content query based on the mailbox scope (recipientsOnly, allTenantMailboxes, or other).
    4. Creates a new eDiscovery search with the composed query, or reuses an existing search based on the force input.
    5. Runs an estimate statistics operation to count emails matching the query.
    6. Waits for the estimate operation to complete and checks whether any emails were found.
    7. Optionally previews the results (statistics summary or full export), based on the preview input.
    8. Purges the matching emails (Hard delete / Soft delete / manual analyst approval).
    9. Cleans up the eDiscovery search based on the cleanup input.
starttaskid: "0"
tasks:
  "0":
    id: "0"
    taskid: 7151238b-5451-4006-8266-d61b065a77c9
    type: start
    task:
      id: 7151238b-5451-4006-8266-d61b065a77c9
      version: -1
      name: ""
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "1"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 100
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "1":
    id: "1"
    taskid: d44d516f-6273-47b6-a953-c8873802f5fe
    type: condition
    task:
      id: d44d516f-6273-47b6-a953-c8873802f5fe
      version: -1
      name: Check Microsoft Graph integration is available
      description: Returns 'yes' if integration brand is available. Otherwise returns 'no'.
      scriptName: IsIntegrationAvailable
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      "yes":
      - "3"
    scriptarguments:
      brandname:
        complex:
          root: modules
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: modules.state
                iscontext: true
              right:
                value:
                  simple: active
          - - operator: isEqualString
              left:
                value:
                  simple: modules.brand
                iscontext: true
              right:
                value:
                  simple: Microsoft Graph
          accessor: brand
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 250
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "2":
    id: "2"
    taskid: cb216bf9-6f61-40b5-86dd-d7cd348fd6a3
    type: title
    task:
      id: cb216bf9-6f61-40b5-86dd-d7cd348fd6a3
      version: -1
      name: Done
      description: Done
      type: title
      iscommand: false
      brand: ""
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 7400
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "3":
    id: "3"
    taskid: b4d9ab83-1eba-4aae-8198-35a5bf9f253b
    type: regular
    task:
      id: b4d9ab83-1eba-4aae-8198-35a5bf9f253b
      version: -1
      name: List eDiscovery cases
      description: Get a list of the eDiscovery cases.
      script: '|||msg-list-ediscovery-cases'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "4"
    scriptarguments:
      all_results:
        simple: "true"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 405
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "4":
    id: "4"
    taskid: b87b74bb-0344-41b1-b9e9-b11523b60205
    type: condition
    task:
      id: b87b74bb-0344-41b1-b9e9-b11523b60205
      version: -1
      name: Does the specified eDiscovery case exist?
      description: Checks whether the eDiscovery case specified by the case input already exists.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      Create new case:
      - "6"
      Reuse existing case:
      - "45"
    separatecontext: false
    conditions:
    - label: Reuse existing case
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: MsGraph.eDiscoveryCase.DisplayName
            iscontext: true
          right:
            value:
              simple: ${inputs.case}
            iscontext: true
    - label: Create new case
      condition:
      - - operator: isNotEqualString
          left:
            value:
              simple: MsGraph.eDiscoveryCase.DisplayName
            iscontext: true
          right:
            value:
              simple: ${inputs.case}
              iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 550
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "6":
    id: "6"
    taskid: e4da15b6-a414-4da3-85dc-61f162596974
    type: regular
    task:
      id: e4da15b6-a414-4da3-85dc-61f162596974
      version: -1
      name: Create eDiscovery case
      description: Create a new eDiscovery case. This command only creates an eDiscovery (Premium) case using the new case format. To learn more about the new case format in eDiscovery, see https://learn.microsoft.com/en-us/microsoft-365/compliance/advanced-ediscovery-new-case-format.
      script: '|||msg-create-ediscovery-case'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "59"
    scriptarguments:
      description:
        simple: Case created by XSOAR Search and Delete (MS Graph Security) playbook.
      display_name:
        simple: ${inputs.case}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 50,
          "y": 735
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "7":
    id: "7"
    taskid: ab1a86b8-d7b0-446a-9a9b-1b5853c04816
    type: condition
    task:
      id: ab1a86b8-d7b0-446a-9a9b-1b5853c04816
      version: -1
      name: Route by mailbox scope
      description: Routes the flow based on the mailbox_scope input to compose the appropriate KQL content query.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "43"
      allTenantMailboxes:
      - "9"
      recipientsOnly:
      - "8"
    separatecontext: false
    conditions:
    - label: recipientsOnly
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.mailbox_scope
            iscontext: true
          right:
            value:
              simple: recipientsOnly
    - label: allTenantMailboxes
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.mailbox_scope
            iscontext: true
          right:
            value:
              simple: allTenantMailboxes
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 1105
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "8":
    id: "8"
    taskid: 6524c0a7-03c1-4d5a-9872-5ec26c2e6ab2
    type: regular
    task:
      id: 6524c0a7-03c1-4d5a-9872-5ec26c2e6ab2
      version: -1
      name: Build participants clause
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "36"
    scriptarguments:
      key:
        simple: ParticipantsClause
      value:
        complex:
          root: inputs.recipients
          transformers:
          - operator: splitAndTrim
            args:
              delimiter:
                value:
                  simple: ','
          - operator: join
            args:
              separator:
                value:
                  simple: ' OR participants:'
          - operator: ConcatFormat
            args:
              ctx_data: {}
              ctx_inc: {}
              ctx_inputs: {}
              keep_symbol_to_null: {}
              prefix:
                value:
                  simple: '(participants:'
              suffix:
                value:
                  simple: )
              variable_markers: {}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 1205,
          "y": 1460
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "9":
    id: "9"
    taskid: 26697752-8b49-4ec3-9393-347610a400f8
    type: condition
    task:
      id: 26697752-8b49-4ec3-9393-347610a400f8
      version: -1
      name: Is a mailbox exclusion list provided?
      description: Set a value in context under the key you entered.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      Exclusion not provided:
      - "38"
      Exclusion provided:
      - "39"
    separatecontext: false
    conditions:
    - label: Exclusion not provided
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.mailbox_exclusion
            iscontext: true
          right:
            value: {}
    - label: Exclusion provided
      condition:
      - - operator: isNotEmpty
          left:
            value:
              simple: inputs.mailbox_exclusion
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -200,
          "y": 1280
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "10":
    id: "10"
    taskid: c9c7de29-6dfd-4fb4-9809-8e24b90c51fe
    type: condition
    task:
      id: c9c7de29-6dfd-4fb4-9809-8e24b90c51fe
      version: -1
      name: Was a custom search name provided?
      description: Checks whether a custom search name was provided, or if one should be auto-generated.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      Create new search:
      - "48"
      Reuse existing search:
      - "53"
    separatecontext: false
    conditions:
    - label: Reuse existing search
      condition:
      - - operator: isNotEmpty
          left:
            value:
              simple: inputs.search_name
            iscontext: true
          right:
            value: {}
    - label: Create new search
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.search_name
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 2495
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "11":
    id: "11"
    taskid: 6005b1c6-1caf-4750-833a-e40fc3e977c1
    type: regular
    task:
      id: 6005b1c6-1caf-4750-833a-e40fc3e977c1
      version: -1
      name: List eDiscovery searches in case
      description: Get a list of eDiscoverySearch resources from an eDiscovery case.
      script: '|||msg-list-ediscovery-searchs'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "12"
    scriptarguments:
      all_results:
        simple: "true"
      case_id:
        simple: ${ResolvedCaseId}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 2845
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "12":
    id: "12"
    taskid: 347752aa-64dd-4cb9-b174-ee01c86ed291
    type: condition
    task:
      id: 347752aa-64dd-4cb9-b174-ee01c86ed291
      version: -1
      name: 'Does a matching eDiscovery search already exist? '
      description: Checks whether an existing eDiscovery search with the specified name was found in the case.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "16"
      "yes":
      - "15"
    separatecontext: false
    conditions:
    - label: "yes"
      condition:
      - - operator: isNotEmpty
          left:
            value:
              simple: MsGraph.eDiscoverySearch.SearchId
            iscontext: true
          right:
            value: {}
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 3020
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "13":
    id: "13"
    taskid: 956ad573-7bc7-45ac-82cc-adf60e76ad46
    type: condition
    task:
      id: 956ad573-7bc7-45ac-82cc-adf60e76ad46
      version: -1
      name: Re-create or reuse existing search?
      description: Determines whether to delete and recreate the existing search or reuse it, based on the force input.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "16"
      Delete existing search:
      - "14"
      "false":
      - "58"
    separatecontext: false
    conditions:
    - label: Delete existing search
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.force
            iscontext: true
          right:
            value:
              simple: "true"
    - label: "false"
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.force
            iscontext: true
          right:
            value:
              simple: "false"
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 3370
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "14":
    id: "14"
    taskid: 51bd5c63-cef4-4c93-8fc0-20016576ec7c
    type: regular
    task:
      id: 51bd5c63-cef4-4c93-8fc0-20016576ec7c
      version: -1
      name: Delete existing search
      description: Delete an eDiscoverySearch object.
      script: '|||msg-delete-ediscovery-search'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "16"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      search_id:
        simple: ${ExistingSearchID}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 3535
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "15":
    id: "15"
    taskid: abf029f6-833c-484b-9a24-08c6da5a1f66
    type: regular
    task:
      id: abf029f6-833c-484b-9a24-08c6da5a1f66
      version: -1
      name: Retrieve search ID from existing search
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "13"
    scriptarguments:
      key:
        simple: ExistingSearchID
      value:
        complex:
          root: MsGraph.eDiscoverySearch
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: MsGraph.eDiscoverySearch.DisplayName
                iscontext: true
              right:
                value:
                  simple: inputs.search_name
                iscontext: true
          accessor: SearchId
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 3195
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "16":
    id: "16"
    taskid: ca8bed28-4c84-47e2-806f-b4916c07e757
    type: regular
    task:
      id: ca8bed28-4c84-47e2-806f-b4916c07e757
      version: -1
      name: Create eDiscovery search
      description: Create a new eDiscoverySearch object.
      script: '|||msg-create-ediscovery-search'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "60"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      content_query:
        simple: ${ContentQuery}
      data_source_scopes:
        simple: ${DataSourceScopes}
      description:
        simple: ${ResolvedDescription}
      display_name:
        simple: ${ResolvedSearchName}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 3720
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "19":
    id: "19"
    taskid: 51f0b4ca-c19f-4103-b388-31259f61120e
    type: regular
    task:
      id: 51f0b4ca-c19f-4103-b388-31259f61120e
      version: -1
      name: Run estimate statistics
      description: Starts an eDiscovery estimate statistics operation in Microsoft Purview. The operation calculates the size and number of items matching the search query.
      script: '|||msg-run-estimate-statistics'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "30"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4200
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "20":
    id: "20"
    taskid: 0ad5456f-26d3-4084-bd50-14182e11359f
    type: condition
    task:
      id: 0ad5456f-26d3-4084-bd50-14182e11359f
      version: -1
      name: Should results be previewed before purging?
      description: Determines the preview mode (statistics or export) based on the preview_mode input.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "31"
      export:
      - "22"
      statistics:
      - "21"
    separatecontext: false
    conditions:
    - label: statistics
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.preview_mode
            iscontext: true
          right:
            value:
              simple: statistics
    - label: export
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.preview_mode
            iscontext: true
          right:
            value:
              simple: export
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 5180
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "21":
    id: "21"
    taskid: c6d965ea-ba83-40b1-a8e7-20f59f373f8d
    type: regular
    task:
      id: c6d965ea-ba83-40b1-a8e7-20f59f373f8d
      version: -1
      name: Display estimate statistics
      description: Prints text to war room (Markdown supported)
      scriptName: Print
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "31"
    scriptarguments:
      value:
        simple: |-
          eDiscovery search estimate:
          - Items count: ${MsGraph.eDiscovery.EstimateStatistics.mailboxCount}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 5400
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "22":
    id: "22"
    taskid: d1411a16-4909-4ddd-972c-6542288d5283
    type: regular
    task:
      id: d1411a16-4909-4ddd-972c-6542288d5283
      version: -1
      name: Start export task
      description: Export results from an estimated ediscoverySearch. For details, see Manage a collection estimate (https://learn.microsoft.com/en-us/purview/ediscovery-create-draft-collection#manage-a-collection-estimate).
      script: '|||msg-export-result-ediscovery-data'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#error#':
      - "2"
      '#none#':
      - "23"
    scriptarguments:
      additional_options:
        simple: advancedIndexing
      case_id:
        simple: ${ResolvedCaseId}
      display_name:
        simple: XSOAR-Export-${incident.id}
      export_criteria:
        simple: searchHits
      export_format:
        simple: ${inputs.export_format}
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerror: true
    continueonerrortype: errorPath
    view: |-
      {
        "position": {
          "x": 40,
          "y": 5400
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "23":
    id: "23"
    taskid: 9a3b0f81-8d6a-452e-b77d-a4c2d981c6a2
    type: regular
    task:
      id: 9a3b0f81-8d6a-452e-b77d-a4c2d981c6a2
      version: -1
      name: Download export file
      description: Get a list of the caseOperation objects and their properties, or retrieve a specific operation by ID. When operation_id is provided, you can set download_file=true to download the export report (if available).
      script: '|||msg-list-case-operation'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#error#':
      - "2"
      '#none#':
      - "62"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      download_file:
        simple: "true"
      operation_id:
        simple: ${ResolvedOperationID}
    separatecontext: false
    continueonerror: true
    continueonerrortype: errorPath
    view: |-
      {
        "position": {
          "x": 40,
          "y": 5565
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "24":
    id: "24"
    taskid: 1c372dd7-6952-4567-a5d5-d2de73837bce
    type: condition
    task:
      id: 1c372dd7-6952-4567-a5d5-d2de73837bce
      version: -1
      name: How should the matched emails be purged?
      description: Determines the purge type based on the delete_type input - Hard, Soft, or manual analyst selection.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      hard:
      - "25"
      manual:
      - "29"
      soft:
      - "26"
    separatecontext: false
    conditions:
    - label: hard
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.delete_type
            iscontext: true
          right:
            value:
              simple: Hard
    - label: soft
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.delete_type
            iscontext: true
          right:
            value:
              simple: Soft
    - label: manual
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.delete_type
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 6055
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "25":
    id: "25"
    taskid: 32ec426e-0287-4df0-aba0-76ab957a2994
    type: regular
    task:
      id: 32ec426e-0287-4df0-aba0-76ab957a2994
      version: -1
      name: Permanently delete matched emails
      description: |-
        Deletes mailbox items in Exchange or messages in Microsoft Teams that are included in an eDiscovery search.

        You can collect and purge the following categories of Teams content:

        Teams 1:1 chats - Chat messages, posts, and attachments shared in a Teams conversation between two people. Teams 1:1 chats are also called conversations.
        Teams group chats - Chat messages, posts, and attachments shared in a Teams conversation between three or more people. Also called 1:N chats or group conversations.
        Teams channels - Chat messages, posts, replies, and attachments shared in a standard Teams channel.
        Private channels - Message posts, replies, and attachments shared in a private Teams channel.
        Shared channels - Message posts, replies, and attachments shared in a shared Teams channel.
      script: '|||msg-purge-ediscovery-data'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#error#':
      - "2"
      '#none#':
      - "33"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      purge_areas:
        simple: mailboxes
      purge_type:
        simple: permanentlyDelete
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerror: true
    continueonerrortype: errorPath
    view: |-
      {
        "position": {
          "x": 40,
          "y": 6420
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "26":
    id: "26"
    taskid: 6a7babf6-b24b-4622-bbed-821267861b16
    type: regular
    task:
      id: 6a7babf6-b24b-4622-bbed-821267861b16
      version: -1
      name: Move matched emails to recoverable items
      description: |-
        Deletes mailbox items in Exchange or messages in Microsoft Teams that are included in an eDiscovery search.

        You can collect and purge the following categories of Teams content:

        Teams 1:1 chats - Chat messages, posts, and attachments shared in a Teams conversation between two people. Teams 1:1 chats are also called conversations.
        Teams group chats - Chat messages, posts, and attachments shared in a Teams conversation between three or more people. Also called 1:N chats or group conversations.
        Teams channels - Chat messages, posts, replies, and attachments shared in a standard Teams channel.
        Private channels - Message posts, replies, and attachments shared in a private Teams channel.
        Shared channels - Message posts, replies, and attachments shared in a shared Teams channel.
      script: '|||msg-purge-ediscovery-data'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#error#':
      - "2"
      '#none#':
      - "33"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      purge_areas:
        simple: mailboxes
      purge_type:
        simple: recoverable
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerror: true
    continueonerrortype: errorPath
    view: |-
      {
        "position": {
          "x": 675,
          "y": 6420
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "27":
    id: "27"
    taskid: 01dac98c-072e-444c-b985-5dd20af2c49c
    type: condition
    task:
      id: 01dac98c-072e-444c-b985-5dd20af2c49c
      version: -1
      name: Should the eDiscovery search be cleaned up?
      description: Determines whether to delete the eDiscovery search after purge, based on the cleanup input.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      auto:
      - "66"
      delete:
      - "28"
    separatecontext: false
    conditions:
    - label: delete
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.cleanup
            iscontext: true
          right:
            value:
              simple: "true"
    - label: auto
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.cleanup
            iscontext: true
          right:
            value:
              simple: auto
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 6730
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "28":
    id: "28"
    taskid: 4da86785-6f2e-44b5-aab5-4ddf760fe0fb
    type: regular
    task:
      id: 4da86785-6f2e-44b5-aab5-4ddf760fe0fb
      version: -1
      name: Delete eDiscovery search
      description: Delete an eDiscoverySearch object.
      script: '|||msg-delete-ediscovery-search'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "2"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 7055
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "29":
    id: "29"
    taskid: f9813592-c76e-4b7f-b773-f1d539f59160
    type: condition
    task:
      id: f9813592-c76e-4b7f-b773-f1d539f59160
      version: -1
      name: 'Analyst: select purge type or skip'
      description: 'Manually select the purge type: Hard (permanently delete), Soft (move to recoverable items), or skip.'
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      hard:
      - "25"
      soft:
      - "26"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 6220
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "30":
    id: "30"
    taskid: 6302ccd6-f04f-4548-b37f-4bab41ff8b2b
    type: regular
    task:
      id: 6302ccd6-f04f-4548-b37f-4bab41ff8b2b
      version: -1
      name: Wait for estimate statistics to complete
      description: Retrieves the most recent eDiscovery estimate statistics operation for a given search in Microsoft Purview. Use this command after running 'msg-run-estimate-statistics' to check the results.
      script: '|||msg-get-last-estimate-statistics-operation'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#error#':
      - "2"
      '#none#':
      - "34"
    scriptarguments:
      case_id:
        simple: ${ResolvedCaseId}
      search_id:
        simple: ${ResolvedSearchId}
    separatecontext: false
    continueonerror: true
    continueonerrortype: errorPath
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4345
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "31":
    id: "31"
    taskid: 9aa42b1b-5c2b-43d4-a282-5946b11b02d0
    type: title
    task:
      id: 9aa42b1b-5c2b-43d4-a282-5946b11b02d0
      version: -1
      name: Purge Emails
      description: Proceeds to delete-type decision (Hard / Soft / manual).
      type: title
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "24"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 5915
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "32":
    id: "32"
    taskid: 5dfcc1b9-f036-4128-bf12-4ad829d0a809
    type: title
    task:
      id: 5dfcc1b9-f036-4128-bf12-4ad829d0a809
      version: -1
      name: Preview Results
      description: Proceeds to preview mode (statistics display or export).
      type: title
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "51"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4675
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "33":
    id: "33"
    taskid: 0dea4413-56d2-40fd-a5ac-75fdbfa5dfa5
    type: title
    task:
      id: 0dea4413-56d2-40fd-a5ac-75fdbfa5dfa5
      version: -1
      name: Cleanup eDiscovery Search
      description: Proceeds to cleanup the eDiscovery search based on the cleanup input.
      type: title
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "27"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 6580
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "34":
    id: "34"
    taskid: ac28ee48-9886-4b01-8e3a-c0816eecab78
    type: condition
    task:
      id: ac28ee48-9886-4b01-8e3a-c0816eecab78
      version: -1
      name: Is any email found?
      description: Checks whether the estimate statistics operation found any matching emails.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "35"
      Email found:
      - "32"
    separatecontext: false
    conditions:
    - label: Email found
      condition:
      - - operator: greaterThan
          left:
            value:
              simple: MsGraph.eDiscovery.EstimateStatistics.mailboxCount
            iscontext: true
          right:
            value:
              simple: "0"
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4490
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "35":
    id: "35"
    taskid: 7baeb44e-0084-4841-953a-729355cefaa5
    type: regular
    task:
      id: 7baeb44e-0084-4841-953a-729355cefaa5
      version: -1
      name: Print no emails found
      description: Prints text to war room (Markdown supported)
      scriptName: Print
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "2"
    scriptarguments:
      value:
        simple: No emails found
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -270,
          "y": 7240
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "36":
    id: "36"
    taskid: 865d4ce7-87b5-40ad-8abc-c6133ea01611
    type: regular
    task:
      id: 865d4ce7-87b5-40ad-8abc-c6133ea01611
      version: -1
      name: Finalize the email search query
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "46"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        complex:
          root: inputs.kql
          transformers:
          - operator: ConcatFormat
            args:
              ctx_data: {}
              ctx_inc: {}
              ctx_inputs: {}
              keep_symbol_to_null: {}
              prefix:
                value:
                  simple: (
              suffix:
                value:
                  simple: )
              variable_markers: {}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 1205,
          "y": 1625
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "37":
    id: "37"
    taskid: 8d35f52e-2886-47f1-8130-228dbdca7bda
    type: regular
    task:
      id: 8d35f52e-2886-47f1-8130-228dbdca7bda
      version: -1
      name: 'Set scope: all tenant mailboxes (recipients filter)'
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "55"
    scriptarguments:
      key:
        simple: DataSourceScopes
      value:
        simple: allTenantMailboxes
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 1205,
          "y": 1965
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "38":
    id: "38"
    taskid: f6c5a22f-4426-453c-89fb-c455c0852063
    type: regular
    task:
      id: f6c5a22f-4426-453c-89fb-c455c0852063
      version: -1
      name: Use provided KQL query as-is (no exclusion)
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "42"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        simple: ${inputs.kql}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -460,
          "y": 1795
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "39":
    id: "39"
    taskid: 53f4067d-32d6-450d-b57a-017f00600c7d
    type: regular
    task:
      id: 53f4067d-32d6-450d-b57a-017f00600c7d
      version: -1
      name: Build exclusion clause
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "40"
    scriptarguments:
      key:
        simple: ScopeClause
      value:
        complex:
          root: inputs.mailbox_exclusion
          transformers:
          - operator: splitAndTrim
            args:
              delimiter:
                value:
                  simple: ','
          - operator: join
            args:
              separator:
                value:
                  simple: ' OR participants:'
          - operator: ConcatFormat
            args:
              ctx_data: {}
              ctx_inc: {}
              ctx_inputs: {}
              keep_symbol_to_null: {}
              prefix:
                value:
                  simple: 'NOT (participants:'
              suffix:
                value:
                  simple: )
              variable_markers: {}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 1460
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "40":
    id: "40"
    taskid: 4d20c77e-8215-4b9a-a297-d572c2e18bf0
    type: regular
    task:
      id: 4d20c77e-8215-4b9a-a297-d572c2e18bf0
      version: -1
      name: Wrap KQL query for exclusion filtering
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "47"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        complex:
          root: inputs.kql
          transformers:
          - operator: ConcatFormat
            args:
              ctx_data: {}
              ctx_inc: {}
              ctx_inputs: {}
              keep_symbol_to_null: {}
              prefix:
                value:
                  simple: (
              suffix:
                value:
                  simple: )
              variable_markers: {}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 1625
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "41":
    id: "41"
    taskid: 2d6195c1-1d25-46e5-81ac-7b5dc6a7f67c
    type: regular
    task:
      id: 2d6195c1-1d25-46e5-81ac-7b5dc6a7f67c
      version: -1
      name: Set DataSourceScopes
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "55"
    scriptarguments:
      key:
        simple: DataSourceScopes
      value:
        simple: allTenantMailboxes
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 1965
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "42":
    id: "42"
    taskid: ca0bca0b-daa6-43b8-bcfe-bd9b408d3e6f
    type: regular
    task:
      id: ca0bca0b-daa6-43b8-bcfe-bd9b408d3e6f
      version: -1
      name: 'Set scope: all tenant mailboxes (no exclusion)'
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "55"
    scriptarguments:
      key:
        simple: DataSourceScopes
      value:
        simple: allTenantMailboxes
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -460,
          "y": 1965
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "43":
    id: "43"
    taskid: 63b997cb-bb9c-4232-b473-195f512e09f4
    type: regular
    task:
      id: 63b997cb-bb9c-4232-b473-195f512e09f4
      version: -1
      name: Use provided KQL query as-is (whole-tenant scope)
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "44"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        simple: ${inputs.kql}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 1795
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "44":
    id: "44"
    taskid: 30ff0c96-f2d4-4cb9-9ef7-fce35b84a0b8
    type: regular
    task:
      id: 30ff0c96-f2d4-4cb9-9ef7-fce35b84a0b8
      version: -1
      name: 'Set scope: custom mailbox scope from input'
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "55"
    scriptarguments:
      key:
        simple: DataSourceScopes
      value:
        simple: ${inputs.mailbox_scope}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 1965
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "45":
    id: "45"
    taskid: e34a31af-d9f5-41a2-9a45-173ebc4f66a1
    type: regular
    task:
      id: e34a31af-d9f5-41a2-9a45-173ebc4f66a1
      version: -1
      name: Store found case ID
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "7"
    scriptarguments:
      key:
        simple: ResolvedCaseId
      value:
        complex:
          root: MsGraph.eDiscoveryCase
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: MsGraph.eDiscoveryCase.DisplayName
                iscontext: true
              right:
                value:
                  simple: inputs.case
                iscontext: true
          accessor: CaseId
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 910
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "46":
    id: "46"
    taskid: 4e05ced4-64d2-4420-9142-f973a0ffc8d3
    type: regular
    task:
      id: 4e05ced4-64d2-4420-9142-f973a0ffc8d3
      version: -1
      name: Add recipients filter to KQL query
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "37"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        simple: ${ContentQuery} AND ${ParticipantsClause}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 1205,
          "y": 1795
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "47":
    id: "47"
    taskid: df7ea8d5-3b82-4cd2-ae70-b8836bd27455
    type: regular
    task:
      id: df7ea8d5-3b82-4cd2-ae70-b8836bd27455
      version: -1
      name: Add exclusion clause to KQL query
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "41"
    scriptarguments:
      key:
        simple: ContentQuery
      value:
        simple: ${ContentQuery} AND ${ScopeClause}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 1795
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "48":
    id: "48"
    taskid: aed47801-15d1-4a27-a24a-1ccba376f185
    type: regular
    task:
      id: aed47801-15d1-4a27-a24a-1ccba376f185
      version: -1
      name: Generate search name automatically
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "16"
    scriptarguments:
      key:
        simple: ResolvedSearchName
      value:
        simple: XSOAR-Search-${incident.id}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -12.5,
          "y": 3535
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "51":
    id: "51"
    taskid: c8983c79-3fd9-488d-bb60-7963afe28fec
    type: condition
    task:
      id: c8983c79-3fd9-488d-bb60-7963afe28fec
      version: -1
      name: Which preview mode should be used?
      description: Determines whether to preview results before purging, based on the preview input.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      Preview:
      - "20"
      "false":
      - "31"
      manual:
      - "52"
    separatecontext: false
    conditions:
    - label: Preview
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.preview
            iscontext: true
          right:
            value:
              simple: "true"
    - label: "false"
      condition:
      - - operator: isEqualString
          left:
            value:
              simple: inputs.preview
            iscontext: true
          right:
            value:
              simple: "false"
    - label: manual
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.preview
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4835
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "52":
    id: "52"
    taskid: 0047d740-5682-4985-b3d7-9e14a0a1e73f
    type: condition
    task:
      id: 0047d740-5682-4985-b3d7-9e14a0a1e73f
      version: -1
      name: 'Analyst: confirm whether to preview found emails'
      description: Asks the analyst whether to preview the found emails before proceeding with deletion.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      Preview:
      - "20"
      export:
      - "22"
      "false":
      - "31"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 5010
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "53":
    id: "53"
    taskid: 77d9ff54-9db1-4286-8d0d-b3bddeb5dc25
    type: regular
    task:
      id: 77d9ff54-9db1-4286-8d0d-b3bddeb5dc25
      version: -1
      name: Save resolved search name
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "11"
    scriptarguments:
      key:
        simple: ResolvedSearchName
      value:
        simple: ${inputs.search_name}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 2670
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "55":
    id: "55"
    taskid: f766c27d-3a2b-4921-9ea8-c1350a1c5009
    type: condition
    task:
      id: f766c27d-3a2b-4921-9ea8-c1350a1c5009
      version: -1
      name: Was a custom search description provided?
      description: Checks whether a custom search description was provided, or if a default one should be generated.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      Generate new description:
      - "56"
      Reuse existing description:
      - "57"
    separatecontext: false
    conditions:
    - label: Generate new description
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.description
            iscontext: true
          right:
            value: {}
    - label: Reuse existing description
      condition:
      - - operator: isNotEmpty
          left:
            value:
              simple: inputs.description
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 2165
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "56":
    id: "56"
    taskid: 989beff6-8095-48b2-87cc-1599230e4bc2
    type: regular
    task:
      id: 989beff6-8095-48b2-87cc-1599230e4bc2
      version: -1
      name: Generate default search description
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "10"
    scriptarguments:
      key:
        simple: ResolvedDescription
      value:
        simple: Created by XSOAR for incident ${incident.id}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 2340
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "57":
    id: "57"
    taskid: 70aa15dc-26b3-44ee-8777-ff15897db1fe
    type: regular
    task:
      id: 70aa15dc-26b3-44ee-8777-ff15897db1fe
      version: -1
      name: Save provided search description
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "10"
    scriptarguments:
      key:
        simple: ResolvedDescription
      value:
        simple: ${inputs.description}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 2340
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "58":
    id: "58"
    taskid: 5fb1b974-2985-480f-a50c-a96272c7cb35
    type: regular
    task:
      id: 5fb1b974-2985-480f-a50c-a96272c7cb35
      version: -1
      name: Store newly created search ID
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "64"
    scriptarguments:
      key:
        simple: ResolvedSearchId
      value:
        simple: ${ExistingSearchID}
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 940,
          "y": 3885
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "59":
    id: "59"
    taskid: d68a2d28-3c84-4439-91bb-38d5a3da3e62
    type: regular
    task:
      id: d68a2d28-3c84-4439-91bb-38d5a3da3e62
      version: -1
      name: Store newly created case ID
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "7"
    scriptarguments:
      key:
        simple: ResolvedCaseId
      value:
        complex:
          root: MsGraph.eDiscoveryCase
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: MsGraph.eDiscoveryCase.DisplayName
                iscontext: true
              right:
                value:
                  simple: inputs.case
                iscontext: true
          accessor: CaseId
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 50,
          "y": 910
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "60":
    id: "60"
    taskid: b953f91e-607a-4ab9-8d0a-5bb2fcb89f82
    type: regular
    task:
      id: b953f91e-607a-4ab9-8d0a-5bb2fcb89f82
      version: -1
      name: Store found search ID
      description: Set a value in context under the key you entered.
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "64"
    scriptarguments:
      key:
        simple: ResolvedSearchId
      value:
        complex:
          root: MsGraph.eDiscoverySearch
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: MsGraph.eDiscoverySearch.DisplayName
                iscontext: true
              right:
                value:
                  simple: ResolvedSearchName
                iscontext: true
          accessor: SearchId
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 3885
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "62":
    id: "62"
    taskid: ff45c5db-b918-44ae-a7e2-18322177c397
    type: regular
    task:
      id: ff45c5db-b918-44ae-a7e2-18322177c397
      version: -1
      name: 'Notify: export results are not yet ready'
      description: Prints text to war room (Markdown supported)
      scriptName: Print
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "31"
    scriptarguments:
      value:
        simple: |-
          ### Export Still In Progress

          The eDiscovery export task is still running, and the file is not ready yet.

          Please wait a few minutes and then re-run the **Download export file** task manually to retrieve the results.
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 40,
          "y": 5720
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "64":
    id: "64"
    taskid: e2964f4a-40fc-4dad-9f23-bad2f2ba6c03
    type: title
    task:
      id: e2964f4a-40fc-4dad-9f23-bad2f2ba6c03
      version: -1
      name: Run Search Statistics
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "19"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 367.5,
          "y": 4060
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "66":
    id: "66"
    taskid: b9542dc9-c9f7-4486-ac51-7ab1c46fd1b6
    type: condition
    task:
      id: b9542dc9-c9f7-4486-ac51-7ab1c46fd1b6
      version: -1
      name: Was the search auto-generated?
      description: Checks whether the eDiscovery search was auto-generated by the playbook (i.e., no search_name input was provided). If auto-generated, the search is deleted as part of cleanup. User-named searches are preserved.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "2"
      "yes":
      - "28"
    separatecontext: false
    conditions:
    - label: "yes"
      condition:
      - - operator: isEmpty
          left:
            value:
              simple: inputs.search_name
            iscontext: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 695,
          "y": 6900
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
view: |-
  {
    "linkLabelsPosition": {
      "1_2_#default#": 0.53,
      "20_21_statistics": 0.52,
      "26_2_#error#": 0.85,
      "34_35_#default#": 0.38,
      "51_31_false": 0.32
    },
    "paper": {
      "dimensions": {
        "height": 7360,
        "width": 2045,
        "x": -460,
        "y": 100
      }
    }
  }
inputs:
- key: case
  value: {}
  required: true
  description: eDiscovery case to use. Looked up by name; created if missing.
  playbookInputQuery:
- key: mailbox_scope
  value:
    simple: allTenantMailboxes
  required: false
  description: 'One of: recipientsOnly, allTenantMailboxes, allCaseCustodians, allCaseNoncustodialDataSources, allTenantSites. Drives data_source_scopes and KQL composition.'
  playbookInputQuery:
- key: kql
  value: {}
  required: false
  description: KQL query identifying the emails to search/delete. Additional clauses are composed around it depending on mailbox_scope.
  playbookInputQuery:
- key: recipients
  value: {}
  required: false
  description: CSV of email addresses. Required when mailbox_scope=recipientsOnly. Optional when mailbox_scope=allCaseCustodians.
  playbookInputQuery:
- key: mailbox_exclusion
  value: {}
  required: false
  description: CSV of mailboxes to exclude. Honored only when mailbox_scope=allTenantMailboxes.
  playbookInputQuery:
- key: search_name
  value: {}
  required: false
  description: When provided, plays into the force semantics (force=true delete-and-recreate, force=false reuse). When omitted, an auto-name like XSOAR-Search-${incident.id}-${ts} is generated.
  playbookInputQuery:
- key: description
  value: {}
  required: false
  description: eDiscovery search description. Defaults to "Created by XSOAR for incident ${incident.id}" when empty.
  playbookInputQuery:
- key: force
  value:
    simple: "false"
  required: false
  description: Only meaningful when search_name is provided. true ⇒ delete-and-recreate. false ⇒ reuse existing.
  playbookInputQuery:
- key: preview
  value:
    simple: "true"
  required: false
  description: '"true" / "false" / empty=manual. Whether to pause for analyst review before delete.'
  playbookInputQuery:
- key: preview_mode
  value:
    simple: statistics
  required: false
  description: '"statistics" (count + size from estimate) or "export" (run export job, download report).'
  playbookInputQuery:
- key: export_format
  value:
    simple: msg
  required: false
  description: File format for the export when preview_mode=export. "msg" produces individual .msg files inside a ZIP (preferred for analyst review). "pst" produces a single PST archive. Ignored when preview_mode=statistics.
  playbookInputQuery:
- key: delete_type
  value:
    simple: Soft
  required: false
  description: '"Hard" / "Soft" / empty=manual (also lets analyst pick Skip).'
  playbookInputQuery:
- key: cleanup
  value:
    simple: auto
  required: false
  description: '"auto" / "true" / "false". auto  delete the search only if it was auto-generated.'
  playbookInputQuery:
inputSections:
- inputs:
  - case
  - mailbox_scope
  - kql
  - recipients
  - mailbox_exclusion
  - search_name
  - description
  - force
  - preview
  - preview_mode
  - export_format
  - delete_type
  - cleanup
  name: General (Inputs group)
  description: Generic group for inputs
outputSections:
- outputs: []
  name: General (Outputs group)
  description: Generic group for outputs
outputs: []
tests:
- No tests
fromversion: 6.10.0