Microsoft Graph
Unified gateway to security insights - all from a unified Microsoft Graph Security API.
Analytics & SIEM · Microsoft Graph Security
Details
| ID | Microsoft Graph |
|---|---|
| Provider | Microsoft |
| Category | Analytics & SIEM |
| From Version | 5.0.0 |
| Docker Image | demisto/crypto:1.0.0.10120494 |
| Supported Modules | Agentix Cloud Runtime Security Cloud Posture Security XSIAM EDR Cortex Cloud |
README
⚠️ Microsoft Graph Security Legacy Alerts Deprecation
Note: Microsoft has deprecated the Legacy Alerts API. As of April 10, 2026, the Legacy Alerts endpoint no longer returns data. This integration now exclusively uses the Alerts v2 API. For more details, see the Microsoft documentation.
Unified gateway to security insights - all from a unified Microsoft Graph Security API.
This integration was integrated and tested with version 1.0 of Microsoft Graph.
Authentication
For more details about the authentication used in this integration, see Microsoft Integrations - Authentication
Note: The eDiscovery and Threat Assessment commands are only supported when using the Authorization Code flow with Delegated (work or school account) permission type.
When using the Authorization Code flow for this integration, you should log in as an administrator or a user with administrative privileges (Security Reader or Security Administrator) after running the msg-generate-login-url command and the login window appears. For more information, see here.
Fetch Incidents and Alerts
Use the Fetch incidents type parameter to control what this integration ingests. You can select Alerts, Incidents, or both:
- Alerts - Each Microsoft Graph Security alert is fetched on its own.
- Incidents - Each Microsoft Graph Security incident is fetched on its own, with all of its associated alerts embedded within it (retrieved via
$expand=alerts) and stored as raw JSON. This gives you one grouped incident that already contains its underlying alerts, instead of many separate alert incidents.
You can narrow what is fetched using the Alerts Filter and Incidents Filter parameters. These accept an OData $filter expression, for example severity eq 'medium' and status eq 'active'. For the supported syntax and operators, see Microsoft query parameters.
Important Notes
- Due to API limitations, the msg-search-alerts command does not filter Office 365 provider alerts.\
For more information, see: https://github.com/microsoftgraph/security-api-solutions/issues/56. - The following properties are supported as filters:
- Alerts Filter parameter (and alert filter arguments): assignedTo, classification, determination, createdDateTime, lastUpdateDateTime, severity, serviceSource and status. See Microsoft optional alert query parameters.
- Incidents Filter parameter: assignedTo, classification, createdDateTime, determination, lastUpdateDateTime, severity, and status. See Microsoft optional incident query parameters.
- The filter should be provided as an OData
$filterexpression, for exampleseverity eq 'medium' and status eq 'active'. For the general syntax and operators, see Microsoft query parameters.
- The header include-unknown-enum-members is used when fetching alerts. It ensures that fields with unknown values are correctly mapped to the appropriate service. Learn More.
- When using Threat Assessment, only the following properties are supported as filters for the filter parameter: expectedAssessment, ContentType, status and requestSource.
- When using Threat Assessment for information protection, the following limits apply to any request:
- For email, the resource is a unique network message ID/recipient pair. For example, submitting an email with the same message ID sent to the same person multiple times in a 15 minutes period will trigger the limit per resource limits listed in the following table. However, you can submit up to 150 unique emails every 15 minutes (tenant limit).
Operation Limit per tenant Limit per resource (email, URL, file) POST 150 requests per 15 minutes and 10000 requests per 24 hours. 1 request per 15 minutes and 3 requests per 24 hours.
Required Permissions
- User.Read.All - Application (Only required if using the deprecated commands:
msg-get-userandmsg-get-users) - SecurityIncident.Read.All - Delegated or Application (required for the command
msg-list-security-incidentand Fetch Incidents) - SecurityIncident.ReadWrite.All - Delegated or Application (required for the command
msg-update-security-incidentand Fetch Incidents) - ThreatHunting.Read.All - Delegated or Application (required for the command
msg-advanced-hunting)
Alerts:
- SecurityAlert.Read.All - Application (required for the commands:
msg-search-alertsandmsg-get-alert-details) - SecurityAlert.ReadWrite.All - Application (required for updating alerts with the commands:
msg-update-alertandmsg-create-alert-comment)
eDiscovery:
- eDiscovery.Read.All - Delegated (Required for the
list-ediscoverycommands) - eDiscovery.ReadWrite.All - Delegated (Required for the
create/update/delete-ediscovery,msg-export-result-ediscovery-datacommands) - eDiscovery.Download.Read - Delegated (Required for the msg-list-case-operation, download_file=True command)
More information about defining this permission can be found here.
Threat Assessment:
- Mail.Read.Shared - Delegated
- ThreatAssessment.ReadWrite.All - Delegated
- User.Read.All - Delegated
Configure Microsoft Graph Security on Cortex
- Navigate to Settings > Integrations > Servers & Services.
- Search for Microsoft Graph Security.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required Azure Cloud When selecting the Custom option, the Host URL parameter must be filled. More information about National clouds can be found here. False Host URL The host URL. When using this parameter, select the Custom option for the Azure Cloud. More information about National clouds can be found here. False Application ID or Client ID The app registration ID. True Token or Tenant ID The tenant ID. True Key or Client Secret The app registration secret. False Authorization code Get the authorization code from steps 3-5 in the self deployed authorization process. False Application redirect URI (for self-deployed mode) The app registration redirect URI. False Certificate Thumbprint Used for certificate authentication, as it appears in the “Certificates & secrets” page of the app. False Private Key Used for certificate authentication. The private key of the registered certificate. False Use Azure Managed Identities Relevant only if the integration is running on Azure VM. If selected, authenticates based on the value provided for the Azure Managed Identities Client ID field. If no value is provided for the Azure Managed Identities Client ID field, authenticates based on the System Assigned Managed Identity. For additional information, see the Help tab. False Azure Managed Identities Client ID The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. False Trust any certificate (not secure) Whether to trust any certificate. If True, not secure. False Use system proxy settings Whether to use system proxy settings. False Use a self-deployed Azure application Whether to use a self-deployed application. False Fetch incidents Whether to fetch incidents. False Incident type The incident type to apply. False First fetch timestamp ( <number> <time unit>, e.g., 12 hours, 7 days)<number> <time unit>, for example 1 hour, 30 minutes.False Fetch limit per type The maximum number of items to fetch per type. Applies to both alerts and incidents. Note that when fetching incidents, no more than 50 can be fetched per cycle, due to a Microsoft limitation. False Fetch incidents type Select which record types to fetch. You can select Alerts, Incidents, or both. False Alerts Service Sources Relevant only when fetching Alerts (incidents have no service source). Multiple serviceSourcevalues can be provided, separated by commas, for example “microsoftDefenderForEndpoint,microsoftCloudAppSecurity”. If empty, alerts of all service sources will be fetched.False Alerts Filter Use this field to filter fetched alerts according to their properties. Applies only when fetching Alerts. Overrides the service sources list, if given. Filter should be in the format “{property} eq ‘{property-value}’”. Multiple filters can be applied separated with “ and “, for example “createdDateTime eq YYYY-MM-DD and severity eq ‘high’”. False Incidents Filter Use this field to filter fetched incidents according to their properties. Applies only when fetching Incidents. Filter should be in the format “{property} eq ‘{property-value}’”. Multiple filters can be applied separated with “ and “, for example “severity eq ‘high’ and status eq ‘active’”. False Microsoft 365 Defender context When selected, the hunting query result is also saved to the Microsoft 365 Defender context path. Relevant only for the msg-advanced-hunting command. False - Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
msg-auth-test
Tests connectivity to Microsoft Graph Security.
Base Command
msg-auth-test
Input
| Argument Name | Description | Required |
|---|---|---|
| permission_type | Which permissions the integration should have. Possible values are: ediscovery, alerts, alerts, ediscovery. Default is ediscovery. | Optional |
Context Output
There is no context output for this command.
Command example
!msg-auth-test permission_type=ediscovery
Human Readable Output
Authentication was successful.
msg-search-alerts
List alerts (security issues) within a customer’s tenant that Microsoft or partner security solutions have identified.
Base Command
msg-search-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| last_modified | When the alert was last modified in the following string format - YYYY-MM-DD. Possible values are: Last24Hours, Last48Hours, LastWeek. | Optional |
| severity | Alert severity - set by vendor/provider. Possible values are: unknown, informational, low, medium, high. | Optional |
| category | Category of the alert, e.g., credentialTheft, ransomware (Categories can be added or removed by vendors.). | Optional |
| time_from | The start time (creation time of alert) for the search in the following string format - YYYY-MM-DD. | Optional |
| time_to | The end time (creation time of alert) for the search in the following string format - YYYY-MM-DD. | Optional |
| filter | Use this field to filter on any of the alert properties in the format “{property} eq ‘{property-value}’”, e.g. “category eq ‘ransomware’”. | Optional |
| classification | Use this field to filter by alert’s classification. Possible values are: unknown, truePositive, falsePositive, benignPositive. | Optional |
| service_source | Use this field to filter the alerts by the service or product that created this alert. Possible values are: microsoftDefenderForEndpoint, microsoftDefenderForIdentity, microsoftDefenderForOffice365, microsoft365Defender, microsoftAppGovernance, microsoftDefenderForCloudApps. | Optional |
| status | Use this field to filter by alert’s status. Possible values are: unknown, new, inProgress, resolved. | Optional |
| page | Page number to return, zero indexed. | Optional |
| page_size | Number of results in a page. Default is 50. The limit is 2000. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Alert.ID | string | Alert ID. |
| MsGraph.Alert.Title | string | Alert title. |
| MsGraph.Alert.Category | string | Alert category. |
| MsGraph.Alert.Severity | string | Alert severity. |
| MsGraph.Alert.CreatedDate | date | Alert created date. |
| MsGraph.Alert.Status | string | Alert status. |
| MsGraph.Alert.ActorDisplayName | Unknown | Alert actor name. |
| MsGraph.Alert.AlertWebUrl | String | Alert web URL. |
| MsGraph.Alert.AssignedTo | Unknown | Alert assignee. |
| MsGraph.Alert.Classification | Unknown | Alert classification. |
| MsGraph.Alert.Description | String | Alert description. |
| MsGraph.Alert.DetectionSource | String | Alert detection source. |
| MsGraph.Alert.DetectorId | String | Alert detector ID. |
| MsGraph.Alert.Determination | Unknown | Alert determination. |
| MsGraph.Alert.Evidence.@odata.Type | String | Alert evidence. |
| MsGraph.Alert.Evidence.AzureAdDeviceId | String | Evidence Azure device ID. |
| MsGraph.Alert.Evidence.CreatedDate | Date | Evidence creation time. |
| MsGraph.Alert.Evidence.DefenderAvStatus | String | Evidence Defender AV status. |
| MsGraph.Alert.Evidence.DeviceDnsName | String | Evidence device DNS name. |
| MsGraph.Alert.Evidence.FirstSeenDateTime | Date | Evidence first seen time. |
| MsGraph.Alert.Evidence.HealthStatus | String | Evidence health status. |
| MsGraph.Alert.Evidence.MdeDeviceId | String | Evidence MDE device ID. |
| MsGraph.Alert.Evidence.OnboardingStatus | String | Evidence onboarding status. |
| MsGraph.Alert.Evidence.OsBuild | Number | Evidence OS build. |
| MsGraph.Alert.Evidence.OsPlatform | String | Evidence OS platform. |
| MsGraph.Alert.Evidence.RbacGroupId | Number | Evidence RBAC group ID. |
| MsGraph.Alert.Evidence.RbacGroupName | String | Evidence RBAC group name. |
| MsGraph.Alert.Evidence.RemediationStatus | String | Evidence remediation status. |
| MsGraph.Alert.Evidence.RemediationStatusDetails | Unknown | Evidence remediation status details. |
| MsGraph.Alert.Evidence.RiskScore | String | Evidence risk score. |
| MsGraph.Alert.Evidence.Tags | String | Evidence tags. |
| MsGraph.Alert.Evidence.Verdict | String | Evidence verdict. |
| MsGraph.Alert.Evidence.Version | String | Evidence version. |
| MsGraph.Alert.Evidence.VmMetadata | Unknown | Evidence VM metadata. |
| MsGraph.Alert.FirstActivityDateTime | Date | Evidence first activity time. |
| MsGraph.Alert.IncidentId | String | Alert incident ID. |
| MsGraph.Alert.IncidentWebUrl | String | Alert incident URL. |
| MsGraph.Alert.LastActivityDateTime | Date | Alert last activity time. |
| MsGraph.Alert.LastUpdateDateTime | Date | Alert last update time. |
| MsGraph.Alert.ProviderAlertId | String | Alert provider ID. |
| MsGraph.Alert.RecommendedActions | String | Alert recommended action. |
| MsGraph.Alert.ResolvedDateTime | Date | Alert closing time. |
| MsGraph.Alert.ServiceSource | String | Alert service source. |
| MsGraph.Alert.TenantId | String | Alert tenant ID. |
| MsGraph.Alert.ThreatDisplayName | Unknown | Alert threat display name. |
| MsGraph.Alert.ThreatFamilyName | Unknown | Alert threat family name. |
Human Readable Output
Microsoft Security Graph Alerts
ID IncidentId Status Severity DetectionSource ServiceSource Title Category CreatedDate LastUpdateDateTime id new medium customTi microsoftDefenderForEndpoint test alert None 2022-10-03T03:39:21.7562976Z 2023-04-17T11:01:31.7566667Z
msg-get-alert-details
Get details for a specific alert.
Base Command
msg-get-alert-details
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The alert ID - Provider-generated GUID/unique identifier. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Alert.ID | string | Alert ID. |
| MsGraph.Alert.Title | string | Alert title. |
| MsGraph.Alert.Category | string | Alert category. |
| MsGraph.Alert.Severity | string | Alert severity. |
| MsGraph.Alert.CreatedDate | date | Alert created date. |
| MsGraph.Alert.Status | string | Alert status. |
| MsGraph.Alert.@odata.Context | String | Alert odata context. |
| MsGraph.Alert.ActorDisplayName | Unknown | Alert actor name. |
| MsGraph.Alert.AlertWebUrl | String | Alert web URL. |
| MsGraph.Alert.AssignedTo | Unknown | Alert assignee. |
| MsGraph.Alert.Classification | Unknown | Alert classification. |
| MsGraph.Alert.Comments.Comment | String | Alert comment. |
| MsGraph.Alert.Comments.CreatedByDisplayName | String | Alert comment creator name. |
| MsGraph.Alert.Comments.CreatedDate | Date | Alert comment creation time. |
| MsGraph.Alert.Description | String | Alert description. |
| MsGraph.Alert.DetectionSource | String | Alert detection source. |
| MsGraph.Alert.DetectorId | String | Alert detector ID. |
| MsGraph.Alert.Determination | Unknown | Alert determination. |
| MsGraph.Alert.Evidence.@odata.Type | String | Alert evidence. |
| MsGraph.Alert.Evidence.CreatedDate | Date | Evidence creation time. |
| MsGraph.Alert.Evidence.DetectionStatus | Unknown | Evidence detection status. |
| MsGraph.Alert.Evidence.ImageFile.FileName | String | Evidence image file name. |
| MsGraph.Alert.Evidence.ImageFile.FilePath | String | Evidence image file path. |
| MsGraph.Alert.Evidence.ImageFile.FilePublisher | Unknown | Evidence image file publisher. |
| MsGraph.Alert.Evidence.ImageFile.FileSize | Unknown | Evidence image file size. |
| MsGraph.Alert.Evidence.ImageFile.Issuer | Unknown | Evidence image file issuer. |
| MsGraph.Alert.Evidence.ImageFile.Sha1 | String | Evidence image file SHA1 hash. |
| MsGraph.Alert.Evidence.ImageFile.Sha256 | String | Evidence image file SHA256 hash. |
| MsGraph.Alert.Evidence.ImageFile.Signer | Unknown | Evidence image file signer. |
| MsGraph.Alert.Evidence.MdeDeviceId | Unknown | Evidence MDE device ID. |
| MsGraph.Alert.Evidence.ParentProcessCreationDateTime | Date | Evidence parent process creation time. |
| MsGraph.Alert.Evidence.ParentProcessId | Number | Evidence parent process process ID. |
| MsGraph.Alert.Evidence.ParentProcessImageFile | Unknown | Evidence parent process image file. |
| MsGraph.Alert.Evidence.ProcessCommandLine | String | Evidence process command line. |
| MsGraph.Alert.Evidence.ProcessCreationDateTime | Date | Evidence process creation time. |
| MsGraph.Alert.Evidence.ProcessId | Number | Evidence process ID. |
| MsGraph.Alert.Evidence.RemediationStatus | String | Evidence remediation status. |
| MsGraph.Alert.Evidence.RemediationStatusDetails | Unknown | Evidence remediation status details. |
| MsGraph.Alert.Evidence.UserAccount.AccountName | String | Evidence user account name. |
| MsGraph.Alert.Evidence.UserAccount.AzureAdUserId | Unknown | Evidence user account Azure AD user ID. |
| MsGraph.Alert.Evidence.UserAccount.DisplayName | String | Evidence user account display name. |
| MsGraph.Alert.Evidence.UserAccount.DomainName | Unknown | Evidence user account domain name. |
| MsGraph.Alert.Evidence.UserAccount.UserPrincipalName | Unknown | Evidence user account user principal name. |
| MsGraph.Alert.Evidence.UserAccount.UserSid | String | Evidence user account user SID. |
| MsGraph.Alert.Evidence.Verdict | String | Evidence verdict. |
| MsGraph.Alert.Evidence.FileDetails.FileName | String | Evidence file details file name. |
| MsGraph.Alert.Evidence.FileDetails.FilePath | String | Evidence file details file path. |
| MsGraph.Alert.Evidence.FileDetails.FilePublisher | Unknown | Evidence file details file publisher. |
| MsGraph.Alert.Evidence.FileDetails.FileSize | Unknown | Evidence file details file size. |
| MsGraph.Alert.Evidence.FileDetails.Issuer | Unknown | Evidence file details file issuer. |
| MsGraph.Alert.Evidence.FileDetails.Sha1 | String | Evidence file details SHA1 hash. |
| MsGraph.Alert.Evidence.FileDetails.Sha256 | String | Evidence file details SHA256 hash. |
| MsGraph.Alert.Evidence.FileDetails.Signer | Unknown | Evidence file details file signer. |
| MsGraph.Alert.Evidence.CֹountryLetterCode | Unknown | Evidence country letter code. |
| MsGraph.Alert.Evidence.IpAddress | String | Evidence IP address. |
| MsGraph.Alert.Evidence.AzureAdDeviceId | Unknown | Evidence Azure AD device ID. |
| MsGraph.Alert.Evidence.DefenderAvStatus | String | Evidence Defender AV status. |
| MsGraph.Alert.Evidence.DeviceDnsName | String | Evidence device DNS name. |
| MsGraph.Alert.Evidence.FirstSeenDateTime | Date | Evidence first seen time. |
| MsGraph.Alert.Evidence.HealthStatus | String | Evidence health status. |
| MsGraph.Alert.Evidence.OnboardingStatus | String | Evidence onboarding status. |
| MsGraph.Alert.Evidence.OsBuild | Unknown | Evidence OS build. |
| MsGraph.Alert.Evidence.OsPlatform | String | Evidence OS platform. |
| MsGraph.Alert.Evidence.RbacGroupId | Number | Evidence RBAC group ID. |
| MsGraph.Alert.Evidence.RbacGroupName | String | Evidence RBAC group name. |
| MsGraph.Alert.Evidence.RiskScore | String | Evidence risk score. |
| MsGraph.Alert.Evidence.Version | String | Evidence version. |
| MsGraph.Alert.Evidence.VmMetadata | Unknown | Evidence VM metadata. |
| MsGraph.Alert.FirstActivityDateTime | Date | Evidence first activity time. |
| MsGraph.Alert.IncidentId | String | Alert incident ID. |
| MsGraph.Alert.IncidentWebUrl | String | Alert incident URL. |
| MsGraph.Alert.LastActivityDateTime | Date | Alert last activity time. |
| MsGraph.Alert.LastUpdateDateTime | Date | Alert last update time. |
| MsGraph.Alert.ProviderAlertId | String | Alert provider ID. |
| MsGraph.Alert.RecommendedActions | String | Alert recommended action. |
| MsGraph.Alert.ResolvedDateTime | Date | Alert closing time. |
| MsGraph.Alert.ServiceSource | String | Alert service source. |
| MsGraph.Alert.TenantId | String | Alert tenant ID. |
| MsGraph.Alert.ThreatDisplayName | Unknown | Alert threat display name. |
| MsGraph.Alert.ThreatFamilyName | Unknown | Alert threat family name. |
Human Readable Output
Microsoft Security Graph Alert Details -
ID IncidentId Status Severity DetectionSource ServiceSource Title Category CreatedDate LastUpdateDateTime new medium customTi microsoftDefenderForEndpoint test alert None 2022-10-03T03:39:21.7562976Z 2023-04-17T11:01:31.7566667Z
msg-update-alert
Update an editable alert property within any integrated solution to keep alert status and assignments in sync across solutions using its reference ID.
Base Command
msg-update-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The Alert ID. Provider-generated GUID/unique identifier. | Required |
| assigned_to | Name of the analyst the alert is assigned to for triage, investigation, or remediation. | Optional |
| status | Alert lifecycle status (stage). Possible values are: unknown, newAlert, inProgress, resolved, new. | Optional |
| classification | Use this field to update the alert’s classification. Possible values are: unknown, truePositive, falsePositive, informationalExpectedActivity. | Optional |
| determination | Use this field to update the alert’s determination. Possible values are: unknown, malware, phishing, other, securityTesting, multiStagedAttack, maliciousUserActivity, lineOfBusinessApplication, unwantedSoftware. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Alert.ID | string | Alert ID. |
| MsGraph.Alert.Status | string | Alert status, will appear only if changed. |
Human Readable Output
Alert has been successfully updated.
msg-create-alert-comment
Create a comment for an existing alert.
Base Command
msg-create-alert-comment
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The Alert ID - Provider-generated GUID/unique identifier. | Required |
| comment | The comment to add to each alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.AlertComment.ID | String | The alert ID that the comment was added to. |
| MsGraph.AlertComment.Comments.Comment | String | The comment itself |
| MsGraph.AlertComment.Comments.CreatedByDisplayName | String | The comment’s creator display name |
| MsGraph.AlertComment.Comments.CreatedDate | Date | The comment’s creation time |
Human Readable Output
Microsoft Security Graph Create Alert Comment -
comment createdByDisplayName createdDate comment Cortex XSOAR MS Graph Dev 2023-04-17T10:57:18.5231438Z comment Cortex XSOAR MS Graph Dev 2023-04-17T11:01:31.7427859Z comment Cortex XSOAR MS Graph Dev 2023-04-17T13:30:22.3995128Z
ms-graph-security-auth-reset
Run this command if for some reason you need to rerun the authentication process.
Base Command
ms-graph-security-auth-reset
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
eDiscovery Commands
msg-list-ediscovery-cases
Lists edicovery cases.
Base Command
msg-list-ediscovery-cases
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. If provided, only this id will be returned. | Optional |
| limit | The maximum number of results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.CaseId | String | The ID of the eDiscovery case. |
| MsGraph.eDiscoveryCase.CaseStatus | String | The case status. Possible values are: unknown, active, pendingDelete, closing, closed, and closedWithError. |
| MsGraph.eDiscoveryCase.CreatedDateTime | Date | The date and time when the entity was created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z |
| MsGraph.eDiscoveryCase.Description | String | The case description. |
| MsGraph.eDiscoveryCase.DisplayName | String | The case name. |
| MsGraph.eDiscoveryCase.ExternalId | String | The external case number for customer reference. |
| MsGraph.eDiscoveryCase.LastModifiedDateTime | Date | The latest date and time when the case was modified. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z |
| MsGraph.eDiscoveryCase.ClosedBy.User.DisplayName | String | The user who closed the case. |
| MsGraph.eDiscoveryCase.LastModifiedBy.User.DisplayName | String | The user who last modified the case. |
| MsGraph.eDiscoveryCase.ClosedDateTime | Date | The date and time when the case was closed. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z |
Command example
!msg-list-ediscovery-cases limit=5
Context Example
{
"MsGraph": {
"eDiscoveryCase": [
{
"CaseId": "06386565-47d4-410b-96f9-007978319c02",
"CaseStatus": "active",
"ClosedBy": {
"User": {
"DisplayName": ""
}
},
"CreatedDateTime": "2023-06-18T10:55:12.63Z",
"Description": "",
"DisplayName": "a",
"ExternalId": "123",
"LastModifiedBy": {
"User": {
"DisplayName": "Content Test"
}
},
"LastModifiedDateTime": "2023-06-20T12:25:05.797Z"
},
{
"CaseId": "44bbe68b-0da1-42b4-9ad0-00e8b52f64e2",
"CaseStatus": "active",
"ClosedBy": {
"User": {
"DisplayName": ""
}
},
"CreatedDateTime": "2023-06-18T11:59:33.44Z",
"Description": "",
"DisplayName": "asassdda",
"ExternalId": "",
"LastModifiedBy": {
"User": {
"DisplayName": "Content Test"
}
},
"LastModifiedDateTime": "2023-06-18T11:59:33.44Z"
},
{
"CaseId": "f108b7fa-d177-438e-9679-01cd79e3df3f",
"CaseStatus": "active",
"ClosedBy": {
"User": {
"DisplayName": ""
}
},
"CreatedDateTime": "2023-06-20T07:08:01.95Z",
"Description": "wrking",
"DisplayName": "justw orkok?",
"ExternalId": "",
"LastModifiedBy": {
"User": {
"DisplayName": "Content Test"
}
},
"LastModifiedDateTime": "2023-06-20T07:08:01.95Z"
},
{
"CaseId": "f346c6f5-1d66-4fab-a46b-0abc99c2cef0",
"CaseStatus": "active",
"ClosedBy": {
"User": {
"DisplayName": ""
}
},
"CreatedDateTime": "2023-06-18T11:54:59.873Z",
"Description": "",
"DisplayName": "asasdda",
"ExternalId": "",
"LastModifiedBy": {
"User": {
"DisplayName": "Content Test"
}
},
"LastModifiedDateTime": "2023-06-18T11:54:59.873Z"
},
{
"CaseId": "1a346a94-5220-46ae-a821-0bbbadf4009d",
"CaseStatus": "active",
"ClosedBy": {
"User": {
"DisplayName": ""
}
},
"CreatedDateTime": "2023-06-12T07:05:27.557Z",
"Description": "Test Case 104 description",
"DisplayName": "Test Case 104",
"ExternalId": "",
"LastModifiedBy": {
"User": {
"DisplayName": "Content Test"
}
},
"LastModifiedDateTime": "2023-06-12T07:05:27.557Z"
}
]
}
}
Human Readable Output
Results
Display Name Description External Id Case Status Case Id Created Date Time Last Modified Date Time Last Modified By Name a 123 active 06386565-47d4-410b-96f9-007978319c02 2023-06-18T10:55:12.63Z 2023-06-20T12:25:05.797Z Content Test asassdda active 44bbe68b-0da1-42b4-9ad0-00e8b52f64e2 2023-06-18T11:59:33.44Z 2023-06-18T11:59:33.44Z Content Test justw orkok? wrking active f108b7fa-d177-438e-9679-01cd79e3df3f 2023-06-20T07:08:01.95Z 2023-06-20T07:08:01.95Z Content Test asasdda active f346c6f5-1d66-4fab-a46b-0abc99c2cef0 2023-06-18T11:54:59.873Z 2023-06-18T11:54:59.873Z Content Test Test Case 104 Test Case 104 description active 1a346a94-5220-46ae-a821-0bbbadf4009d 2023-06-12T07:05:27.557Z 2023-06-12T07:05:27.557Z Content Test
msg-create-ediscovery-case
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.
Base Command
msg-create-ediscovery-case
Input
| Argument Name | Description | Required |
|---|---|---|
| display_name | The name of the eDiscovery case. | Required |
| description | The case description. | Optional |
| external_id | The external case number for customer reference. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.CaseId | String | The ID of the eDiscovery case. |
| MsGraph.eDiscoveryCase.CaseStatus | String | The case status. Possible values are unknown, active, pendingDelete, closing, closed, and closedWithError. |
| MsGraph.eDiscoveryCase.CreatedDateTime | Date | The date and time when the entity was created. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z |
| MsGraph.eDiscoveryCase.Description | String | The case description. |
| MsGraph.eDiscoveryCase.DisplayName | String | The case name. |
| MsGraph.eDiscoveryCase.ExternalId | String | The external case number for customer reference. |
| MsGraph.eDiscoveryCase.LastModifiedDateTime | Date | The latest date and time when the case was modified. The Timestamp type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z |
Command example
!msg-create-ediscovery-case display_name=`my case name11234` external_id=123 description=`description of the case`
Context Example
{
"MsGraph": {
"eDiscoveryCase": {
"CaseId": "6dfd17fe-43c5-411f-a194-abdc9492bfa0",
"CaseStatus": "active",
"CreatedDateTime": "2023-07-06T07:42:34.897Z",
"Description": "description of the case",
"DisplayName": "my case name11234",
"ExternalId": "123",
"LastModifiedDateTime": "2023-07-06T07:42:34.897Z"
}
}
}
Human Readable Output
Results
Display Name Description External Id Case Status Case Id Created Date Time Last Modified Date Time my case name11234 description of the case 123 active 6dfd17fe-43c5-411f-a194-abdc9492bfa0 2023-07-06T07:42:34.897Z 2023-07-06T07:42:34.897Z
msg-update-ediscovery-case
Update an eDiscovery case.
Base Command
msg-update-ediscovery-case
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| display_name | The name of the eDiscovery case. | Required |
| description | The case description. | Optional |
| external_id | The external case number for customer reference. | Optional |
Context Output
There is no context output for this command.
Command example
!msg-update-ediscovery-case case_id=6dfd17fe-43c5-411f-a194-abdc9492bfa0 display_name=`new display name` external_id=123 description=`new description of the case`
Human Readable Output
Case with id 6dfd17fe-43c5-411f-a194-abdc9492bfa0 was updated successfully.
msg-close-ediscovery-case
Close an eDiscovery case.
When the legal case or investigation supported by a eDiscovery (Standard) case is completed, you can close the case. Here’s what happens when you close a case:
If the case contains any eDiscovery holds, they’ll be turned off. After the hold is turned off, a 30-day grace period (called a delay hold) is applied to content locations that were on hold. This helps prevent content from being immediately deleted and provides admins the opportunity to search for and restore content before it may be permanently deleted after the delay hold period expires. For more information, see Removing content locations from an eDiscovery hold.
Closing a case only turns off the holds that are associated with that case. If other holds are placed on a content location (such as a Litigation Hold, a retention policy, or a hold from a different eDiscovery (Standard) case) those holds will still be maintained.
The case is still listed on the eDiscovery (Standard) page in the Microsoft Purview compliance portal. The details, holds, searches, and members of a closed case are retained.
You can edit a case after it’s closed. For example, you can add or remove members, create searches, and export search results. The primary difference between active and closed cases is that eDiscovery holds are turned off when a case is closed.
Base Command
msg-close-ediscovery-case
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
Context Output
There is no context output for this command.
Command example
!msg-close-ediscovery-case case_id=6dfd17fe-43c5-411f-a194-abdc9492bfa0
Human Readable Output
Case with id 6dfd17fe-43c5-411f-a194-abdc9492bfa0 was closed successfully.
msg-reopen-ediscovery-case
Reopen an eDiscovery case. When you reopen an eDiscovery (Premium) case, any holds that were in place when the case was closed won’t be automatically reinstated. After the case is reopened, you’ll have to go to the Holds tab and turn on the previous holds. To turn on a hold, select it to display the flyout page, and then set the Status toggle to On.
Base Command
msg-reopen-ediscovery-case
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
Context Output
There is no context output for this command.
Command example
!msg-reopen-ediscovery-case case_id=6dfd17fe-43c5-411f-a194-abdc9492bfa0
Human Readable Output
Case with id 6dfd17fe-43c5-411f-a194-abdc9492bfa0 was reopened successfully.
msg-delete-ediscovery-case
Delete an eDiscovery case. Before you can delete a case, you must first delete all holds listed on the holds page of the case. That includes deleting holds with a status of Off. Default hold policies can only be deleted when the hold is turned off. You must close an active case to turn off any default hold policies in the case. Once the holds are turned off for default hold policies, they can be deleted.
Base Command
msg-delete-ediscovery-case
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
Context Output
There is no context output for this command.
Command example
!msg-delete-ediscovery-case case_id=6dfd17fe-43c5-411f-a194-abdc9492bfa0
Human Readable Output
Case was deleted successfully.
msg-create-ediscovery-custodian
Create a new ediscoveryCustodian object. After the custodian object is created, you will need to create the custodian’s userSource to reference their mailbox and OneDrive for Business site.
Base Command
msg-create-ediscovery-custodian
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| Custodian’s primary SMTP address. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCustodian.CreatedDateTime | Date | Date and time when the custodian was added to the case. |
| MsGraph.eDiscoveryCustodian.CustodianId | String | The ID for the custodian in the specified case. Read-only. |
| MsGraph.eDiscoveryCustodian.CustodianStatus | String | Status of the custodian. Possible values are: active, released. |
| MsGraph.eDiscoveryCustodian.DisplayName | String | Display name of the custodian. |
| MsGraph.eDiscoveryCustodian.Email | String | Email address of the custodian. |
| MsGraph.eDiscoveryCustodian.HoldStatus | String | The hold status of the custodian.The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.eDiscoveryCustodian.LastModifiedDateTime | Date | Date and time the custodian object was last modified. |
Command example
!msg-create-ediscovery-custodian case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 email=testbox2@yoursite.onmicrosoft.com
Context Example
{
"MsGraph": {
"eDiscoveryCustodian": {
"CreatedDateTime": "2023-07-06T07:53:36.9441479Z",
"CustodianId": "0af7ca2b84bc4cff930d5d301cc4caf3",
"CustodianStatus": "active",
"DisplayName": "testbox2",
"Email": "yourmail@yoursite.onmicrosoft.com",
"HoldStatus": "notApplied",
"LastModifiedDateTime": "2023-07-06T07:53:36.9441479Z"
}
}
}
Human Readable Output
Results
Display Name Custodian Status Custodian Id Created Date Time Last Modified Date Time Hold Status testbox2 yourmail@yoursite.onmicrosoft.com active 0af7ca2b84bc4cff930d5d301cc4caf3 2023-07-06T07:53:36.9441479Z 2023-07-06T07:53:36.9441479Z notApplied
msg-list-ediscovery-custodians
List custodians on a given eDiscovery case.
Base Command
msg-list-ediscovery-custodians
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the custodian on the given eDiscovery case. If provided, only this ID will be returned. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCustodian.CreatedDateTime | Date | Date and time when the custodian was added to the case. |
| MsGraph.eDiscoveryCustodian.CustodianId | String | The ID for the custodian in the specified case. Read-only. |
| MsGraph.eDiscoveryCustodian.CustodianStatus | String | Status of the custodian. Possible values are: active, released. |
| MsGraph.eDiscoveryCustodian.DisplayName | String | Display name of the custodian. |
| MsGraph.eDiscoveryCustodian.Email | String | Email address of the custodian. |
| MsGraph.eDiscoveryCustodian.HoldStatus | String | The hold status of the custodian. The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.eDiscoveryCustodian.LastModifiedDateTime | Date | Date and time the custodian object was last modified. |
| MsGraph.eDiscoveryCustodian.ReleasedDateTime | Date | Date and time the custodian was released from the case. |
Command example
!msg-list-ediscovery-custodians all_results=true case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Context Example
{
"MsGraph": {
"eDiscoveryCustodian": {
"CreatedDateTime": "2023-07-06T07:53:36.9441479Z",
"CustodianId": "0af7ca2b84bc4cff930d5d301cc4caf3",
"CustodianStatus": "active",
"DisplayName": "testbox2",
"Email": "mail@yoursite.onmicrosoft.com",
"HoldStatus": "notApplied",
"LastModifiedDateTime": "2023-07-06T07:53:36.9441479Z"
}
}
}
Human Readable Output
Results
Display Name Custodian Status Custodian Id Created Date Time Last Modified Date Time Hold Status testbox2 mail@yoursite.onmicrosoft.com active 0af7ca2b84bc4cff930d5d301cc4caf3 2023-07-06T07:53:36.9441479Z 2023-07-06T07:53:36.9441479Z notApplied
msg-activate-ediscovery-custodian
Activate a custodian that has been released from a case to make them part of the case again. For details, see https://learn.microsoft.com/en-us/microsoft-365/compliance/ediscovery-manage-new-custodians?view=o365-worldwide#re-activate-custodian.
Base Command
msg-activate-ediscovery-custodian
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
Context Output
There is no context output for this command.
Command example
!msg-activate-ediscovery-custodian custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Human Readable Output
Custodian with id 0af7ca2b84bc4cff930d5d301cc4caf3 Case was reactivated on case with id 84abfff1-dd69-4559-8f4e-8225e0d505c5 successfully.
msg-release-ediscovery-custodian
Release a custodian from a case. For details, see https://learn.microsoft.com/en-us/microsoft-365/compliance/manage-new-custodians#release-a-custodian-from-a-case.
Base Command
msg-release-ediscovery-custodian
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
Context Output
There is no context output for this command.
Command example
!msg-release-ediscovery-custodian custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Human Readable Output
Custodian with id 0af7ca2b84bc4cff930d5d301cc4caf3 was released from case with id 84abfff1-dd69-4559-8f4e-8225e0d505c5 successfully.
msg-create-ediscovery-custodian-site-source
Create a new siteSource object associated with an eDiscovery custodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
Base Command
msg-create-ediscovery-custodian-site-source
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
| site | URL of the site; for example, https://contoso.sharepoint.com/sites/HumanResources. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.CustodianSiteSource.CreatedBy.Application.DisplayName | String | The name of the application who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.Application.ID | String | The ID of the application who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.DisplayName | String | The name of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.ID | String | The ID of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedDateTime | Date | The date and time the siteSource was created. |
| MsGraph.CustodianSiteSource.DisplayName | String | The display name of the siteSource. This will be the name of the SharePoint site. |
| MsGraph.CustodianSiteSource.HoldStatus | String | The hold status of the siteSource. The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.CustodianSiteSource.SiteSourceId | String | The ID of the siteSource. |
Command example
!msg-create-ediscovery-custodian-site-source custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 site=https://yourdev.sharepoint.com/sites/site_test_1
Context Example
{
"MsGraph": {
"CustodianSiteSource": {
"CreatedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"CreatedDateTime": "0001-01-01T00:00:00Z",
"DisplayName": "site_test_1",
"HoldStatus": "notApplied",
"SiteSourceId": "862f0a64-e7db-46e0-a97f-9156b4f693ee"
}
}
}
Human Readable Output
Results
Display Name Site Source Id Hold Status Created Date Time Created By Name Created By UPN Created By App Name site_test_1 862f0a64-e7db-46e0-a97f-9156b4f693ee notApplied 0001-01-01T00:00:00Z Content Test ContentTest@yoursite.onmicrosoft.com Cortex XSOAR - MS Graph Security Dev
msg-create-ediscovery-custodian-user-source
Create a new userSource object associated with an eDiscovery custodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
Base Command
msg-create-ediscovery-custodian-user-source
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
| SMTP address of the user. | Required | |
| included_sources | Specifies which sources are included in this group. Possible values are: mailbox, site, mailbox, site. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.CustodianUserSource.CreatedBy.Application.DisplayName | String | The name of the application who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.Application.ID | String | The ID of the application who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.DisplayName | String | The name of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.ID | String | The ID of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedDateTime | Date | The date and time the userSource was created. |
| MsGraph.CustodianUserSource.DisplayName | String | The display name associated with the mailbox and site. |
| MsGraph.CustodianUserSource.Email | String | Email address of the user’s mailbox. |
| MsGraph.CustodianUserSource.HoldStatus | String | The hold status of the userSource. The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.CustodianUserSource.IncludedSources | String | Specifies which sources are included in this group. Possible values are: mailbox, site. |
| MsGraph.CustodianUserSource.UserSourceId | String | The ID of the userSource. This is not The ID of the actual group. |
Command example
!msg-create-ediscovery-custodian-user-source custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 email=testbox2@yoursite.onmicrosoft.com included_sources="mailbox, site"
Context Example
{
"MsGraph": {
"CustodianUserSource": {
"CreatedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"CreatedDateTime": "0001-01-01T00:00:00Z",
"DisplayName": "testbox2",
"Email": "testbox2@yoursite.onmicrosoft.com",
"HoldStatus": "notApplied",
"IncludedSources": "mailbox,site",
"UserSourceId": "0af7ca2b-84bc-4cff-930d-5d301cc4caf3"
}
}
}
Human Readable Output
Results
Display Name User Source Id Hold Status Created Date Time Created By Name Created By UPN Created By App Name Included Sources testbox2 testbox2@yoursite.onmicrosoft.com 0af7ca2b-84bc-4cff-930d-5d301cc4caf3 notApplied 0001-01-01T00:00:00Z Content Test ContentTest@yoursite.onmicrosoft.com Cortex XSOAR - MS Graph Security Dev mailbox,site
msg-list-ediscovery-custodian-user-sources
Get a list of the userSource objects associated with an eDiscoveryCustodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
Base Command
msg-list-ediscovery-custodian-user-sources
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
| user_source_id | The ID of the userSource. If provided, only this id will be returned. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.CustodianUserSource.CreatedBy.Application.DisplayName | String | The name of the application who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.Application.ID | String | The ID of the application who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.DisplayName | String | The name of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.ID | String | The ID of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the userSource. |
| MsGraph.CustodianUserSource.CreatedDateTime | Date | The date and time the userSource was created. |
| MsGraph.CustodianUserSource.DisplayName | String | The display name associated with the mailbox and site. |
| MsGraph.CustodianUserSource.Email | String | Email address of the user’s mailbox. |
| MsGraph.CustodianUserSource.HoldStatus | String | The hold status of the userSource. The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.CustodianUserSource.IncludedSources | String | Specifies which sources are included in this group. Possible values are: mailbox, site. |
| MsGraph.CustodianUserSource.SiteWebUrl | String | The URL of the user’s OneDrive for Business site. Read-only. |
| MsGraph.CustodianUserSource.UserSourceId | String | The ID of the userSource. This is not The ID of the actual group. |
Command example
!msg-list-ediscovery-custodian-user-sources custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Context Example
{
"MsGraph": {
"CustodianUserSource": {
"CreatedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"CreatedDateTime": "2023-07-06T08:04:21.1548801Z",
"DisplayName": "testbox2",
"Email": "testbox2@yoursite.onmicrosoft.com",
"HoldStatus": "notApplied",
"IncludedSources": "mailbox,site",
"SiteWebUrl": "https://yourdev-my.sharepoint.com/personal/testbox2_yourdev_onmicrosoft_com",
"UserSourceId": "0af7ca2b-84bc-4cff-930d-5d301cc4caf3"
}
}
}
Human Readable Output
Results
Display Name User Source Id Hold Status Created Date Time Created By Name Created By UPN Created By App Name Site Web Url Included Sources testbox2 testbox2@yoursite.onmicrosoft.com 0af7ca2b-84bc-4cff-930d-5d301cc4caf3 notApplied 2023-07-06T08:04:21.1548801Z Content Test ContentTest@yoursite.onmicrosoft.com Cortex XSOAR - MS Graph Security Dev https://yourdev-my.sharepoint.com/personal/testbox2_yourdev_onmicrosoft_com mailbox,site
msg-list-ediscovery-custodian-site-sources
Get a list of the siteSource objects associated with an eDiscoveryCustodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
Base Command
msg-list-ediscovery-custodian-site-sources
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | The ID of the eDiscovery case. on the given eDiscovery case. | Required |
| site_source_id | The ID of the siteSource. If provided, only this id will be returned. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.CustodianSiteSource.CreatedBy.Application.DisplayName | String | The name of the application who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.Application.ID | String | The ID of the application who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.DisplayName | String | The name of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.ID | String | The ID of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the siteSource. |
| MsGraph.CustodianSiteSource.CreatedDateTime | Date | The date and time the siteSource was created. |
| MsGraph.CustodianSiteSource.DisplayName | String | The display name of the siteSource. This will be the name of the SharePoint site. |
| MsGraph.CustodianSiteSource.HoldStatus | String | The hold status of the siteSource. The possible values are: notApplied, applied, applying, removing, partial. |
| MsGraph.CustodianSiteSource.SiteSourceId | String | The ID of the siteSource. |
| MsGraph.CustodianSiteSource.Site.ID | String | The unique identifier of the item. Read-only. |
| MsGraph.CustodianSiteSource.Site.WebUrl | String | URL that displays the item in the browser. Read-only. |
| MsGraph.CustodianSiteSource.Site.CreatedDate | Date | The date and time the siteSource was created. |
Command example
!msg-list-ediscovery-custodian-site-sources custodian_id=0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 site_source_id=862f0a64-e7db-46e0-a97f-9156b4f693ee
Context Example
{
"MsGraph": {
"CustodianSiteSource": {
"CreatedBy": {
"User": {
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b"
}
},
"CreatedDateTime": "2023-07-06T08:02:28.5670187Z",
"DisplayName": "site_test_1",
"HoldStatus": "removing",
"Site": {
"CreatedDate": "2023-07-06T08:02:28.5670187Z",
"ID": "862f0a64-e7db-46e0-a97f-9156b4f693ee",
"WebUrl": "https://yourdev.sharepoint.com/sites/site_test_1"
},
"SiteSourceId": "862f0a64-e7db-46e0-a97f-9156b4f693ee"
}
}
}
Human Readable Output
Results
Display Name Site Source Id Hold Status Created Date Time site_test_1 862f0a64-e7db-46e0-a97f-9156b4f693ee removing 2023-07-06T08:02:28.5670187Z
msg-apply-hold-ediscovery-custodian
Start the process of applying hold on eDiscovery custodians.
Available return statuses:
notApplied - The custodian is not on hold (all sources in it are not on hold).
applied - The custodian is on hold (all sources are on hold).
applying - The custodian is in applying hold state (applyHold operation triggered).
removing - The custodian is in removing the hold state(removeHold operation triggered).
partial - The custodian is in mixed state where some sources are on hold and some not on hold or error state.
Base Command
msg-apply-hold-ediscovery-custodian
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | A comma-seperated list of custodians ids to apply a hold to. | Required |
Context Output
There is no context output for this command.
Command example
!msg-apply-hold-ediscovery-custodian custodian_id=09f05c43ffc54ff88cf5c5e89699375d,0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Human Readable Output
Apply hold status is running.
msg-remove-hold-ediscovery-custodian
Start the process of removing hold from eDiscovery custodians.
Base Command
msg-remove-hold-ediscovery-custodian
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| custodian_id | A comma-seperated list of custodians ids to remove a hold from. | Required |
Context Output
There is no context output for this command.
Command example
!msg-remove-hold-ediscovery-custodian custodian_id=09f05c43ffc54ff88cf5c5e89699375d,0af7ca2b84bc4cff930d5d301cc4caf3 case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Human Readable Output
Remove hold status is running.
msg-create-ediscovery-non-custodial-data-source
Create a new eDiscoveryNoncustodialDataSource object.
Base Command
msg-create-ediscovery-non-custodial-data-source
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| site | URL of the site, for example, https://contoso.sharepoint.com/sites/HumanResources. | Optional |
| Email address of the user’s mailbox. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.NoncustodialDataSource.CreatedDateTime | Date | Created date and time of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.DataSourceId | String | Unique identifier of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.DataSourceStatus | String | Latest status of the nonCustodialDataSource. Possible values are: Active, Released. |
| MsGraph.NoncustodialDataSource.DisplayName | String | Display name of the noncustodialDataSource. |
| MsGraph.NoncustodialDataSource.HoldStatus | String | The hold status of the nonCustodialDataSource.The possible values are: notApplied, applied, applying, removing, partial |
| MsGraph.NoncustodialDataSource.LastModifiedDateTime | Date | Last modified date and time of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.ReleasedDateTime | Date | Date and time that the nonCustodialDataSource was released from the case. |
Command example
!msg-create-ediscovery-non-custodial-data-source case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 site=https://yourdev.sharepoint.com/sites/site_test_1
Context Example
{
"MsGraph": {
"NoncustodialDataSource": {
"CreatedDateTime": "2023-07-06T08:22:32.3121523Z",
"DataSourceId": "38394332433939353236344630434633",
"DataSourceStatus": "active",
"DisplayName": "site_test_1",
"HoldStatus": "notApplied",
"LastModifiedDateTime": "2023-07-06T08:22:32.3121523Z",
"ReleasedDateTime": "0001-01-01T00:00:00Z"
}
}
}
Human Readable Output
Results
Created Date Time Data Source Id Data Source Status Display Name Hold Status Last Modified Date Time Released Date Time 2023-07-06T08:22:32.3121523Z 38394332433939353236344630434633 active site_test_1 notApplied 2023-07-06T08:22:32.3121523Z 0001-01-01T00:00:00Z
msg-list-ediscovery-non-custodial-data-sources
Get a list of the non-custodial data sources and their properties.
Base Command
msg-list-ediscovery-non-custodial-data-sources
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| data_source_id | The ID of the dataSource. If provided, only this id will be returned. | Optional |
| limit | The maximum number of results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.NoncustodialDataSource.CreatedDateTime | Date | Created date and time of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.DataSourceId | String | Unique identifier of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.DataSourceStatus | String | Latest status of the nonCustodialDataSource. Possible values are: Active, Released. |
| MsGraph.NoncustodialDataSource.DisplayName | String | Display name of the noncustodialDataSource. |
| MsGraph.NoncustodialDataSource.HoldStatus | String | The hold status of the nonCustodialDataSource.The possible values are: notApplied, applied, applying, removing, partial |
| MsGraph.NoncustodialDataSource.LastModifiedDateTime | Date | Last modified date and time of the nonCustodialDataSource. |
| MsGraph.NoncustodialDataSource.ReleasedDateTime | Date | Date and time that the nonCustodialDataSource was released from the case. |
Command example
!msg-list-ediscovery-non-custodial-data-sources case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Context Example
{
"MsGraph": {
"NoncustodialDataSource": {
"CreatedDateTime": "2023-07-06T08:22:32.3121523Z",
"DataSourceId": "38394332433939353236344630434633",
"DisplayName": "site_test_1",
"HoldStatus": "notApplied",
"LastModifiedDateTime": "2023-07-06T08:22:32.3121523Z",
"ReleasedDateTime": "0001-01-01T00:00:00Z",
"Status": "active"
}
}
}
Human Readable Output
Results
Display Name Data Source Id Hold Status Created Date Time Last Modified Date Time Released Date Time Status site_test_1 38394332433939353236344630434633 notApplied 2023-07-06T08:22:32.3121523Z 2023-07-06T08:22:32.3121523Z 0001-01-01T00:00:00Z active
msg-create-ediscovery-search
Create a new eDiscoverySearch object.
Base Command
msg-create-ediscovery-search
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| display_name | The display name of the search. | Required |
| description | The description of the search. | Optional |
| content_query | The query string used for the search. The query string format is KQL (Keyword Query Language). For details, see https://learn.microsoft.com/en-us/microsoft-365/compliance/keyword-queries-and-search-conditions.. You can refine searches by using fields paired with values; for example, subject:”Quarterly Financials” AND Date>=06/01/2016 AND Date<=07/01/2016. | Optional |
| data_source_scopes | When specified, the collection will span across a service for an entire workload. Possible values are: none, allTenantMailboxes, allTenantSites, allCaseCustodians, allCaseNoncustodialDataSources. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoverySearch.ContentQuery | String | The query string in KQL (Keyword Query Language) query. For details, see see https://learn.microsoft.com/en-us/microsoft-365/compliance/keyword-queries-and-search-conditions.. You can refine searches by using fields paired with values; for example, subject:”Quarterly Financials” AND Date>=06/01/2016 AND Date<=07/01/2016. |
| MsGraph.eDiscoverySearch.CreatedBy.Application.DisplayName | String | Name of the application who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.Application.ID | String | ID of the application who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.DisplayName | String | Name of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.ID | String | ID of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedDateTime | Date | The date and time the eDiscovery search was created. |
| MsGraph.eDiscoverySearch.DataSourceScopes | String | When specified, the collection will span across a service for an entire workload. Possible values are: none, allTenantMailboxes, allTenantSites, allCaseCustodians, allCaseNoncustodialDataSources. |
| MsGraph.eDiscoverySearch.Description | String | The description of the eDiscovery search. |
| MsGraph.eDiscoverySearch.DisplayName | String | The display name of the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedDateTime | Date | The last date and time the eDiscovery search was modified. |
| MsGraph.eDiscoverySearch.SearchId | String | The ID for the eDiscovery search. |
Command example
!msg-create-ediscovery-search case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 display_name=`my search` data_source_scopes=allCaseNoncustodialDataSources
Context Example
{
"MsGraph": {
"eDiscoverySearch": {
"ContentQuery": "",
"CreatedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"CreatedDateTime": "2023-07-06T08:25:36.9874937Z",
"DataSourceScopes": "allCaseNoncustodialDataSources",
"Description": "",
"DisplayName": "my search",
"LastModifiedDateTime": "2023-07-06T08:25:36.9874937Z",
"SearchId": "e7282eff-ba81-43cb-9027-522a343f6692"
}
}
}
Human Readable Output
Results
Display Name Data Source Scopes Search Id Created By Name Created By App Name Created By UPN Created Date Time Last Modified Date Time my search allCaseNoncustodialDataSources e7282eff-ba81-43cb-9027-522a343f6692 Content Test Cortex XSOAR - MS Graph Security Dev ContentTest@yoursite.onmicrosoft.com 2023-07-06T08:25:36.9874937Z 2023-07-06T08:25:36.9874937Z
msg-update-ediscovery-search
Update an eDiscoverySearch object.
Base Command
msg-update-ediscovery-search
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. | Required |
| display_name | The display name of the search. | Required |
| description | The description of the search. | Optional |
| content_query | The query string used for the search. The query string format is KQL (Keyword Query Language). For details, see Keyword queries and search conditions for Content Search and eDiscovery. You can refine searches by using fields paired with values, for example, subject:”Quarterly Financials” AND Date>=06/01/2016 AND Date<=07/01/2016. | Optional |
| data_source_scopes | When specified, the collection will span across a service for an entire workload. Possible values are: none, allTenantMailboxes, allTenantSites, allCaseCustodians, allCaseNoncustodialDataSources. | Optional |
Context Output
There is no context output for this command.
Command example
!msg-update-ediscovery-search case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 display_name=newname search_id=e7282eff-ba81-43cb-9027-522a343f6692
Human Readable Output
eDiscovery search e7282eff-ba81-43cb-9027-522a343f6692 was updated successfully.
msg-list-ediscovery-searchs
Get the list of eDiscoverySearch resources from an eDiscovery case.
Base Command
msg-list-ediscovery-searchs
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. If provided, only this id will be returned. | Optional |
| limit | The maximum number of results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoverySearch.ContentQuery | String | The query string in KQL (Keyword Query Language) query. For details, see Keyword queries and search conditions for Content Search and eDiscovery. You can refine searches by using fields paired with values; for example, subject:”Quarterly Financials” AND Date>=06/01/2016 AND Date<=07/01/2016. |
| MsGraph.eDiscoverySearch.CreatedBy.Application.DisplayName | String | Name of the application who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.Application.ID | String | ID of the application who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.DisplayName | String | Name of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.ID | String | ID of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedBy.User.UserPrincipalName | String | Internet-style login name of the user who created the eDiscovery search. |
| MsGraph.eDiscoverySearch.CreatedDateTime | Date | The date and time the eDiscovery search was created. |
| MsGraph.eDiscoverySearch.DataSourceScopes | String | When specified, the collection will span across a service for an entire workload. Possible values are: none, allTenantMailboxes, allTenantSites, allCaseCustodians, allCaseNoncustodialDataSources. |
| MsGraph.eDiscoverySearch.Description | String | The description of the eDiscovery search. |
| MsGraph.eDiscoverySearch.DisplayName | String | The display name of the eDiscovery search. |
| MsGraph.eDiscoverySearch.SearchId | String | The ID for the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedDateTime | String | The last date and time the eDiscovery search was modified. |
| MsGraph.eDiscoverySearch.LastModifiedBy.Application.DisplayName | String | Name of the application who last modified the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedBy.Application.ID | String | ID of the application who last modified the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedBy.User.DisplayName | String | Name of the user who last modified the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedBy.User.ID | String | ID of the user who last modified the eDiscovery search. |
| MsGraph.eDiscoverySearch.LastModifiedBy.User.UserPrincipalName | String | Internet-style login name of the user who last modified the eDiscovery search. |
Command example
!msg-list-ediscovery-searchs case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5
Context Example
{
"MsGraph": {
"eDiscoverySearch": {
"ContentQuery": "",
"CreatedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"CreatedDateTime": "2023-07-06T08:25:36.9874937Z",
"DataSourceScopes": "allCaseNoncustodialDataSources",
"Description": "",
"DisplayName": "newname",
"LastModifiedBy": {
"Application": {
"DisplayName": "Cortex XSOAR - MS Graph Security Dev",
"ID": "734f96d8-b19c-4ab1-9382-e04aa9a5debd"
},
"User": {
"DisplayName": "Content Test",
"ID": "38c41451-94b8-44cc-8c02-649208c43b6b",
"UserPrincipalName": "ContentTest@yoursite.onmicrosoft.com"
}
},
"LastModifiedDateTime": "2023-07-06T08:27:51.5611704Z",
"SearchId": "e7282eff-ba81-43cb-9027-522a343f6692"
}
}
}
Human Readable Output
Results
Display Name Data Source Scopes Search Id Created By Name Created By App Name Created By UPN Created Date Time Last Modified Date Time newname allCaseNoncustodialDataSources e7282eff-ba81-43cb-9027-522a343f6692 Content Test Cortex XSOAR - MS Graph Security Dev ContentTest@yoursite.onmicrosoft.com 2023-07-06T08:25:36.9874937Z 2023-07-06T08:27:51.5611704Z
msg-purge-ediscovery-data
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.
Base Command
msg-purge-ediscovery-data
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. | Required |
| purge_type | Whether the action is soft delete or hard delete. Possible values are: permanentlyDelete, recoverable. | Optional |
| purge_areas | Define the locations to be in scope of the purge action. Possible values are: teamsMessages, mailboxes. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.Purge.OperationID | String | The ID of the purge operation. Use this ID to retrieve the operation status via ‘msg-list-case-operation’. |
| MsGraph.eDiscoveryCase.Purge.Status | String | The status of the purge operation. |
Command example
!msg-purge-ediscovery-data case_id=00000000-0000-0000-0000-000000000000 search_id=11111111-1111-1111-1111-111111111111 purge_type=permanentlyDelete purge_areas=mailboxes
Context Example
{
"MsGraph": {
"eDiscoveryCase": {
"Purge": {
"OperationID": "example-operation-id",
"Status": "succeeded"
}
}
}
}
Human Readable Output
eDiscovery purge status is succeeded.
- Operation ID: example-operation-id
msg-delete-ediscovery-search
Delete an eDiscoverySearch object.
Base Command
msg-delete-ediscovery-search
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. | Optional |
Context Output
There is no context output for this command.
Command example
!msg-delete-ediscovery-search case_id=84abfff1-dd69-4559-8f4e-8225e0d505c5 search_id=e7282eff-ba81-43cb-9027-522a343f6692
Human Readable Output
eDiscovery search e7282eff-ba81-43cb-9027-522a343f6692 was deleted successfully.
Threat Assessment Commands
msg-create-mail-assessment-request
Create and retrieve a mail threat assessment.
Note:
- The message given in the command’s argument message_id has to contain X-MS-Exchange-Organization-Network-Message-Id header in the message or in the X-MS-Office365-Filtering-Correlation-Id header in quarantined messages.
-
Delegated Mail permissions (Mail.Read or Mail.Read.Shared) are required to access the mail received by the user (recipient email and message user), which means that if the authenticated user is different from the user specified in the recipient_email and message_user, then Read and manage permissions on behalf of the given user need to be added for the authenticated user via Microsoft 365 admin center.
- Go to Microsoft 365 admin center.
- Choose the user email which will be provided in the command’s arguments.
- Click on Manage product licenses.
- Go to Mail.
- Under Mailbox permissions, click on Read and manage permissions.
- click on Add permissions.
- Choose the authenticated user email from the list of given users.
- Click on add.
Base Command
msg-create-mail-assessment-request
Input
| Argument Name | Description | Required |
|---|---|---|
| recipient_email | The email of the user who recieved the mail. | Required |
| expected_assessment | the expected assessment: blocked or unblocked | Required |
| category | The category of the threat: phishing, malware or spam. | Required |
| message_user | Message user, the user’s id or the user’s email. | Required |
| message_id | Message id, Message has to contain ‘X-MS-Exchange-Organization-Network-Message-Id’ header in the message or the ‘X-MS-Office365-Filtering-Correlation-Id’ header in quarantined messages. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGraphMail.MailAssessment.ID | String | Request id. |
| MSGraphMail.MailAssessment.CreatedDateTime | Date | Created data of the threat assessment request. |
| MSGraphMail.MailAssessment.ContentType | String | The content type of threat assessment. |
| MSGraphMail.MailAssessment.ExpectedAssessment | String | The expected assessment from submitter. Possible values are: block, unblock. |
| MSGraphMail.MailAssessment.Category | String | The threat category. Possible values are: spam, phishing, malware. |
| MSGraphMail.MailAssessment.Status | String | The assessment process status. Possible values are: pending, completed. |
| MSGraphMail.MailAssessment.RequestSource | String | The source of threat assessment request. Possible values are: administrator. |
| MSGraphMail.MailAssessment.RecipientEmail | String | The mail recipient whose policies are used to assess the mail. |
| MSGraphMail.MailAssessment.DestinationRoutingReason | String | The reason for mail routed to its destination. Possible values are: none, mailFlowRule, safeSender, blockedSender, advancedSpamFiltering, domainAllowList, domainBlockList, notInAddressBook, firstTimeSender, autoPurgeToInbox, autoPurgeToJunk, autoPurgeToDeleted, outbound, notJunk, junk. |
| MSGraphMail.MailAssessment.MessageID | String | Extracted from the message URI which is The resource URI of the mail message for assessment. |
| MSGraphMail.MailAssessment.CreatedUserID | String | User id. |
| MSGraphMail.MailAssessment.CreatedUsername | String | Username. |
| MSGraphMail.MailAssessment.ResultType | String | Result of the request. |
| MSGraphMail.MailAssessment.ResultMessage | String | Message of the result. |
Command example
!msg-create-mail-assessment-request recipient_email="avishai@demistodev.onmicrosoft.com" expectedAssessment=unblock category=spam user_id=3fa9f28b-eb0e-463a-ba7b-8089fe9991e2 user_message=AAMkAGY3OTQyMzMzLWYxNjktNDE0My05NmZhLWQ5MGY1YjIyNzBkNABGAAAAAACYCKjWAnXBTrnhgWJCcLX7BwDrxRwRjq-zTrN6vWSzK4OWAAAAAAEJAADrxRwRjq-zTrN6vWSzK4OWAAY5aBb-AAA=
Context Example
{
"id": "11922306-b25b-4605-ff0d-08d772fcf996",
"createdDateTime": "2019-11-27T05:45:14.0962061Z",
"contentType": "mail",
"expectedAssessment": "unblock",
"category": "spam",
"status": "completed",
"requestSource": "administrator",
"recipientEmail": "avishai@demistodev.onmicrosoft.com",
"destinationRoutingReason": "notJunk",
"messageUri": "",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
},
"results": [
{
"id": "63798129-a62c-4f9e-2c6d-08d772fcfb0e",
"createdDateTime": "2019-11-27T05:45:16.55Z",
"resultType": "checkPolicy",
"message": "No policy was hit."
},
{
"id": "d38c2448-79eb-467e-2495-08d772fdb7d1",
"createdDateTime": "2019-11-27T05:50:33.243Z",
"resultType": "rescan",
"message": "Not Spam"
}
]
}
Human Readable Output
Mail assessment request
ID Created DateTime Content Type Expected Assessment Category Status Request Source Recipient Email Destination Routing Reason Created User ID Created Username 11922306-b25b-4605-ff0d-08d772fcf996 “2019-11-27T05:45:14.0962061Z” unblock spam completed administrator avishai@demistodev.onmicrosoft.com notJunk 63798129-a62c-4f9e-2c6d-08d772fcfb0e No policy was hit.
msg-create-email-file-assessment-request
Create and retrieve an email file threat assessment.
Note: File has to contain X-MS-Exchange-Organization-Network-Message-Id header in the message or in the X-MS-Office365-Filtering-Correlation-Id header in quarantined messages.
Base Command
msg-create-email-file-assessment-request
Input
| Argument Name | Description | Required |
|---|---|---|
| recipient_email | The email of the user who recieved the mail. | Required |
| expected_assessment | the expected assessment: blocked or unblocked | Required |
| category | The category of the threat: phishing, malware or spam. | Required |
| content_data | content of an email file. | Optional |
| entry_id | entry id of file uploaded in the war room. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGraphMail.EmailAssessment.ID | String | Request id. |
| MSGraphMail.EmailAssessment.CreatedDateTime | Date | Created data of the threat assessment request. |
| MSGraphMail.EmailAssessment.ContentType | String | The content type of threat assessment. |
| MSGraphMail.EmailAssessment.ExpectedAssessment | String | The expected assessment from submitter. Possible values are: block, unblock. |
| MSGraphMail.EmailAssessment.Category | String | The threat category. Possible values are: spam, phishing, malware. |
| MSGraphMail.EmailAssessment.Status | String | The assessment process status. Possible values are: pending, completed. |
| MSGraphMail.EmailAssessment.RequestSource | String | The source of threat assessment request. Possible values are: administrator. |
| MSGraphMail.EmailAssessment.RecipientEmail | String | The mail recipient whose policies are used to assess the mail. |
| MSGraphMail.EmailAssessment.DestinationRoutingReason | String | The reason for mail routed to its destination. Possible values are: none, mailFlowRule, safeSender, blockedSender, advancedSpamFiltering, domainAllowList, domainBlockList, notInAddressBook, firstTimeSender, autoPurgeToInbox, autoPurgeToJunk, autoPurgeToDeleted, outbound, notJunk, junk. |
| MSGraphMail.EmailAssessment.CreatedUserID | String | User id. |
| MSGraphMail.EmailAssessment.CreatedUsername | String | Username. |
| MSGraphMail.EmailAssessment.ResultType | String | Result of the request. |
| MSGraphMail.EmailAssessment.ResultMessage | String | Message of the result. |
Command example
!msg-create-email-file-assessment-request recipient_email="avishai@demistodev.onmicrosoft.com" expectedAssessment=unblock category=phishing entry_id=12359704829584
Context Example
{
"id": "76598306-b25b-4605-ff0d-03kgmtfcf996",
"createdDateTime": "2019-11-27T05:45:14.0962061Z",
"contentType": "mail",
"expectedAssessment": "unblock",
"category": "phishing",
"status": "completed",
"requestSource": "administrator",
"recipientEmail": "avishai@demistodev.onmicrosoft.com",
"destinationRoutingReason": "notJunk",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
},
"results": [
{
"id": "63798129-a62c-4f9e-2c6d-08d772fcfb0e",
"createdDateTime": "2019-11-27T05:45:16.55Z",
"resultType": "checkPolicy",
"message": "Phishing attempt."
}
]
}
Human Readable Output
Mail assessment request
ID Created DateTime Content Type Expected Assessment Category Status Request Source Recipient Email Destination Routing Reason Created User ID Created Username 76598306-b25b-4605-ff0d-03kgmtfcf996 “2019-11-27T05:45:14.0962061Z” unblock phishing completed administrator avishai@demistodev.onmicrosoft.com notJunk 63798129-a62c-4f9e-2c6d-08d772fcfb0e Phishing attempt.
msg-create-file-assessment-request
Create and retrieve a file threat assessment.
Base Command
msg-create-file-assessment-request
Input
| Argument Name | Description | Required |
|---|---|---|
| file_name | The file name. | Required |
| expected_assessment | the expected assessment: blocked or unblocked | Required |
| category | The category of the threat: phishing, malware or spam. | Required |
| content_data | content of an email file. | Optional |
| entry_id | entry id of file uploaded in the war room. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGraphMail.FileAssessment.ID | String | Request id. |
| MSGraphMail.FileAssessment.CreatedDateTime | Date | Created data of the threat assessment request. |
| MSGraphMail.FileAssessment.ContentType | String | The content type of threat assessment. |
| MSGraphMail.FileAssessment.ExpectedAssessment | String | The expected assessment from submitter. Possible values are: block, unblock. |
| MSGraphMail.FileAssessment.Category | String | The threat category. Possible values are: phishing, malware. |
| MSGraphMail.FileAssessment.Status | String | The assessment process status. Possible values are: pending, completed. |
| MSGraphMail.FileAssessment.RequestSource | String | The source of threat assessment request. Possible values are: administrator. |
| MSGraphMail.FileAssessment.FileName | String | The file name. |
| MSGraphMail.FileAssessment.CreatedUserID | String | User id. |
| MSGraphMail.FileAssessment.CreatedUsername | String | Username. |
| MSGraphMail.FileAssessment.ResultType | String | Result of the request. |
| MSGraphMail.FileAssessment.ResultMessage | String | Message of the result. |
Command example
!msg-create-file-assessment-request file_name="test_file.txt" expectedAssessment=block category=phishing entry_id=1235970482958bkf4
Context Example
{
"id": "0796306-b456-4605-ff0d-03kgmtfcf876",
"createdDateTime": "2019-11-27T05:45:14.0962061Z",
"contentType": "file",
"expectedAssessment": "block",
"category": "phishing",
"status": "completed",
"requestSource": "administrator",
"fileName": "test_file.txt",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
},
"results": [
{
"id": "63798129-a62c-4f9e-2c6d-08d772fcfb0e",
"createdDateTime": "2019-11-27T05:45:16.55Z",
"resultType": "checkPolicy",
"message": "Phishing attempt."
}
]
}
Human Readable Output
Mail assessment request
ID Created DateTime Content Type Expected Assessment Category Status Request Source File Name Created User ID Created Username 0796306-b456-4605-ff0d-03kgmtfcf876 “2019-11-27T05:45:14.0962061Z” file block phishing completed administrator test_file.txt 63798129-a62c-4f9e-2c6d-08d772fcfb0e Phishing attempt.
msg-create-url-assessment-request
Create and retrieve url threat assessment.
Base Command
msg-create-url-assessment-request
Input
| Argument Name | Description | Required |
|---|---|---|
| url | The URL. | Required |
| expected_assessment | the expected assessment: blocked or unblocked | Required |
| category | The category of the threat: phishing, malware or spam. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGraphMail.UrlAssessment.ID | String | Request id. |
| MSGraphMail.UrlAssessment.CreatedDateTime | Date | Created data of the threat assessment request. |
| MSGraphMail.UrlAssessment.ContentType | String | The content type of threat assessment. |
| MSGraphMail.UrlAssessment.ExpectedAssessment | String | The expected assessment from submitter. Possible values are: block, unblock. |
| MSGraphMail.UrlAssessment.Category | String | The threat category. Possible values are: spam, phishing, malware. |
| MSGraphMail.UrlAssessment.Status | String | The assessment process status. Possible values are: pending, completed. |
| MSGraphMail.UrlAssessment.RequestSource | String | The source of threat assessment request. Possible values are: administrator. |
| MSGraphMail.UrlAssessment.Url | String | The url. |
| MSGraphMail.UrlAssessment.CreatedUserID | String | User id. |
| MSGraphMail.UrlAssessment.CreatedUsername | String | Username. |
| MSGraphMail.UrlAssessment.ResultType | String | Result of the request. |
| MSGraphMail.UrlAssessment.ResultMessage | String | Message of the result. |
| MSGraphMail.UrlAssessment.RecipientEmail | String | Recipient Email. |
| MSGraphMail.UrlAssessment.DestinationRoutingReason | String | Destination Routing Reason. |
Command example
!msg-create-url-assessment-request url="httpp://support.clean-mx.de/clean-mx/viruses.php" expectedAssessment=block category=malware
Context Example
{
"id": "0796306-b456-4605-ff0d-03okmtgcf876",
"createdDateTime": "2019-11-27T05:45:14.0962061Z",
"contentType": "url",
"expectedAssessment": "block",
"category": "malware",
"status": "completed",
"requestSource": "administrator",
"url": "httpp://support.clean-mx.de/clean-mx/viruses.php",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
},
"results": [
{
"id": "63798129-a62c-4f9e-2c6d-08d772fcfb0e",
"createdDateTime": "2019-11-27T05:45:16.55Z",
"resultType": "checkPolicy",
"message": "Malware attempt."
}
]
}
Human Readable Output
Mail assessment request
ID Created DateTime Content Type Expected Assessment Category Status Request Source URL Created User ID Created Username 0796306-b456-4605-ff0d-03okmtgcf876 “2019-11-27T05:45:14.0962061Z” url block malware completed administrator httpp://support.clean-mx.de/clean-mx/viruses.php 63798129-a62c-4f9e-2c6d-08d772fcfb0e Malware attempt.
msg-list-threat-assessment-requests
Retrieve all threat assessment requests.
Base Command
msg-list-threat-assessment-requests
Input
| Argument Name | Description | Required |
|---|---|---|
| request_id | The request id. | Optional |
| filter | Available fields for filter are:expectedAssessment,ContentType,status,requestSource. Example:category eq ‘malware’ | Optional |
| order_by | Drop -down: id, createdDateTime, ContentType, expectedAssessment, category, status, requestSource, category | Optional |
| sort_order | desc or asc. | Optional |
| limit | Default is 50. | Optional |
| next_token | the retrieved token from first run when there’s more data to retrieve. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MSGraphMail.AssessmentRequest.ID | String | Request id. |
| MSGraphMail.AssessmentRequest.CreatedDateTime | Date | Created data of the threat assessment request. |
| MSGraphMail.AssessmentRequest.ContentType | String | The content type of threat assessment. |
| MSGraphMail.AssessmentRequest.ExpectedAssessment | String | The expected assessment from submitter. Possible values are: block, unblock. |
| MSGraphMail.AssessmentRequest.Category | String | The threat category. Possible values are: spam, phishing, malware. |
| MSGraphMail.AssessmentRequest.Status | String | The assessment process status. Possible values are: pending, completed. |
| MSGraphMail.AssessmentRequest.RequestSource | String | The source of threat assessment request. Possible values are: administrator. |
| MSGraphMail.AssessmentRequest.DestinationRoutingReason | String | The destination Routing Reason. |
| MSGraphMail.AssessmentRequest.RecipientEmail | String | The recipient email. |
| MSGraphMail.AssessmentRequest.URL | String | The url. |
| MSGraphMail.AssessmentRequest.FileName | String | The file name. |
| MSGraphMail.AssessmentRequest.CreatedUserID | String | User id. |
| MSGraphMail.AssessmentRequest.CreatedUsername | String | Username. |
| MSGraphMail.AssessmentRequest.ResultType | String | Result of the request. |
| MSGraphMail.AssessmentRequest.ResultMessage | String | Message of the result. |
| MsGraph.AssessmentRequestNextToken.next_token | String | the next token from the previous run. |
Command example
#### Context Example
```json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#informationProtection/threatAssessmentRequests",
"@odata.nextLink": "https://graph.microsoft.com/v1.0/informationProtection/threatAssessmentRequests?$skiptoken=eyJQYWdlQ29va2llIjoiPHJvdyBpZF9JZGVudGl0",
"value": [
{
"@odata.type": "#microsoft.graph.mailAssessmentRequest",
"id": "49c5ef5b-1f65-444a-e6b9-08d772ea2059",
"createdDateTime": "2019-11-27T03:30:18.6890937Z",
"contentType": "mail",
"expectedAssessment": "block",
"category": "spam",
"status": "pending",
"requestSource": "administrator",
"recipientEmail": "avishaibrandies@microsoft.com",
"destinationRoutingReason": "notJunk",
"messageUri": "https://graph.microsoft.com/v1.0/users/c52ce8db-3e4b-4181-93c4-7d6b6bffaf60/messages/AAMkADU3MWUxOTU0LWNlOTEt=",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
}
},
{
"@odata.type": "#microsoft.graph.emailFileAssessmentRequest",
"id": "ab2ad9b3-2213-4091-ae0c-08d76ddbcacf",
"createdDateTime": "2019-11-20T17:05:06.4088076Z",
"contentType": "mail",
"expectedAssessment": "block",
"category": "malware",
"status": "completed",
"requestSource": "administrator",
"recipientEmail": "tifc@a830edad9050849EQTPWBJZXODQ.onmicrosoft.com",
"destinationRoutingReason": "notJunk",
"contentData": "",
"createdBy": {
"user": {
"id": "c52ce8db-3e4b-4181-93c4-7d6b6bffaf60",
"displayName": "Ronald Admin"
}
}
}
]
}
Human Readable Output
###Next Token is: eyJQYWdlQ29va2llIjoiPHJvdyBpZF9JZGVudGl
Mail assessment request
ID Created DateTime Content Type Expected Assessment Category Status Request Source Recipient Email Created User ID Created Username destinationRoutingReason 49c5ef5b-1f65-444a-e6b9-08d772ea2059 “2019-11-27T03:30:18.6890937Z” block spam pending administrator avishaibrandies@microsoft.com 63798129-a62c-4f9e-2c6d-08d772fcfb0e spam attempt. notJunk ab2ad9b3-2213-4091-ae0c-08d76ddbcacf 2019-11-20T17:05:06.4088076Z block malware pending administrator avishaibrandies@microsoft.com 63798129-a62c-4f9e-2c6d-08d772fcfb0e Malware attempt. notJunk
msg-generate-login-url
Generate the login URL used for the authorization code flow.
Base Command
msg-generate-login-url
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
Human Readable Output
Authorization instructions
- Click on the login URL to sign in and grant Cortex XSOAR permissions for your Azure Service Management.
You will be automatically redirected to a link with the following structure:
REDIRECT_URI?code=AUTH_CODE&session_state=SESSION_STATE- Copy the
AUTH_CODE(without thecode=prefix, and thesession_stateparameter)
and paste it in your instance configuration under the Authorization code parameter.
msg-advanced-hunting
Advanced hunting is a threat-hunting tool that uses specially constructed queries to examine the past 30 days of event data in Microsoft Graph Security.
To save result in context to ‘Microsoft365Defender’ as well, you can check the ‘Microsoft 365 Defender context’ checkbox in Instance Setting.
Base Command
msg-advanced-hunting
Input
| Argument Name | Description | Required |
|---|---|---|
| query | Advanced hunting query. | Required |
| limit | Number of entries. Enter -1 for unlimited query, In case a limit also appears in the query, priority will be given to the query. | Optional |
| timeout | The time limit in seconds for the http request to run | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Hunt.query | String | The query used, also acted as a key. |
| MsGraph.Hunt.results | Unknown | The results of the query. |
| Microsoft365Defender.Hunt.query | String | The query used, also acted as a key. |
| Microsoft365Defender.Hunt.results | Unknown | The results of the query. |
Command example
!msg-advanced-hunting query=AlertInfo limit=1
Context Example
{
"Microsoft365Defender": {
"Hunt": {
"query": "AlertInfo | limit 1 ",
"results": [
{
"AlertId": "abc123",
"AttackTechniques": "",
"Category": "Exfiltration",
"DetectionSource": "Microsoft Data Loss Prevention",
"ServiceSource": "Microsoft Data Loss Prevention",
"Severity": "Medium",
"Timestamp": "2024-03-19T03:00:08Z",
"Title": "DLP policy (Custom policy) matched for email with subject (Splunk Report: High Or Critical Priority Host With Malware - 15 min)"
}
]
}
},
"MsGraph": {
"Hunt": {
"query": "AlertInfo | limit 1 ",
"results": [
{
"AlertId": "abc123",
"AttackTechniques": "",
"Category": "Exfiltration",
"DetectionSource": "Microsoft Data Loss Prevention",
"ServiceSource": "Microsoft Data Loss Prevention",
"Severity": "Medium",
"Timestamp": "2024-03-19T03:00:08Z",
"Title": "DLP policy (Custom policy) matched for email with subject (Splunk Report: High Or Critical Priority Host With Malware - 15 min)"
}
]
}
}
}
Human Readable Output
See Results Above
msg-list-security-incident
Get a list of incident objects that Microsoft 365 Defender created to track attacks in an organization. If you want a specific incident, enter an incident ID.
Base Command
msg-list-security-incident
Input
| Argument Name | Description | Required |
|---|---|---|
| incident_id | Incident’s ID. | Optional |
| limit | Number of incidents in the list. Maximum is 50. Default is 50. | Optional |
| timeout | The time limit in seconds for the http request to run. Default is 50. | Optional |
| status | The status of the incident. Possible values are: active, redirected, resolved, inProgress, unknownFutureValue, awaitingAction. | Optional |
| assigned_to | Owner of the incident. | Optional |
| severity | Indicates the possible impact on assets. The higher the severity, the greater the impact. Typically higher severity items require the most immediate attention. Possible values are: unknown, informational, low, medium, high, unknownFutureValue. | Optional |
| classification | The specification for the incident. | Optional |
| odata | Filter incidents using ‘odata’ query. | Optional |
| extra_data | Whether to include each incident’s related alerts in the response. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Incident.assignedTo | string | Owner of the incident, or null if no owner is assigned. Free editable text. |
| MsGraph.Incident.classification | string | The specification for the incident. Possible values are unknown, falsePositive, truePositive, informationalExpectedActivity, unknownFutureValue. |
| MsGraph.Incident.comments | string | Array of comments created by the Security Operations (SecOps) team when the incident is managed. |
| MsGraph.Incident.createdDateTime | date | Time when the incident was first created. |
| MsGraph.Incident.customTags | string | Array of custom tags associated with an incident. |
| MsGraph.Incident.description | string | Description of the incident. |
| MsGraph.Incident.determination | string | Specifies the determination of the incident. Possible values are unknown, apt, malware, securityPersonnel, securityTesting, unwantedSoftware, other, multiStagedAttack, compromisedUser, phishing, maliciousUserActivity, clean, insufficientData, confirmedUserActivity, lineOfBusinessApplication, unknownFutureValue. |
| MsGraph.Incident.displayName | string | The incident name. |
| MsGraph.Incident.id | number | Unique identifier to represent the incident. |
| MsGraph.Incident.incidentWebUrl | string | The URL for the incident page in the Microsoft 365 Defender portal. |
| MsGraph.Incident.lastModifiedBy | string | The identity that last modified the incident. |
| MsGraph.Incident.lastUpdateDateTime | string | Time when the incident was last updated. |
| MsGraph.Incident.redirectIncidentId | string | Only populated in case an incident is grouped with another incident, as part of the logic that processes incidents. In such a case, the status property is redirected. |
| MsGraph.Incident.severity | string | Indicates the possible impact on assets. The higher the severity, the greater the impact. Typically higher severity items require the most immediate attention. Possible values are unknown, informational, low, medium, high, unknownFutureValue. |
| MsGraph.Incident.status | string | The status of the incident. Possible values are active, resolved, inProgress, redirected, unknownFutureValue, and awaitingAction. |
| MsGraph.Incident.tenantId | string | The Microsoft Entra tenant in which the alert was created. |
| MsGraph.Incident.systemTags | string | The system tags associated with the incident. |
Command example
!msg-list-security-incident limit=1
Context Example
{
"MsGraph": {
"Incident": {
"@odata.count": 26176,
"value": [
{
"Assigned to": null,
"Classification": "unknown",
"Created date time": "2024-03-19T08:08:33.2533333Z",
"Custom tags": "",
"Determination": "unknown",
"Display name": "DLP policy (Custom policy) matched for email with subject (Splunk Report: High Or Critical Priority Host With Malware - 15 min) involving one user",
"Severity": "medium",
"Status": "active",
"System tags": "",
"Updated date time": "2024-03-19T08:08:33.36Z",
"id": "12345"
}
]
}
}
}
Human Readable Output
Incidents
Display name id Severity Status Assigned to Custom tags System tags Classification Determination Created date time Updated date time DLP policy (Custom policy) matched for email with subject (Splunk Report: High Or Critical Priority Host With Malware - 15 min) involving one user 12345 medium active unknown unknown 2024-03-19T08:08:33.2533333Z 2024-03-19T08:08:33.36Z
msg-update-security-incident
Update the incident with the given ID.
Base Command
msg-update-security-incident
Input
| Argument Name | Description | Required |
|---|---|---|
| incident_id | Incident’s ID. | Required |
| status | Categorize incidents (as Active, Resolved, or Redirected). Possible values are: active, resolved, redirected, unknownFutureValue. | Optional |
| assigned_to | Owner of the incident. | Optional |
| determination | Determination of the incident. Possible values are: unknown, apt, malware, securityPersonnel, unwantedSoftware, other, multiStagedAttack, compromisedUser, phishing, maliciousUserActivity, notMalicious. | Optional |
| classification | The specification for the incident. Possible values are: unknown, falsePositive, truePositive, informationalExpectedActivity, unknownFutureValue. | Optional |
| severity | Indicates the possible impact on assets. The higher the severity, the bigger the impact. Typically, higher severity items require the most immediate attention. The possible values are: unknown, informational, low, medium, high, unknownFutureValue. | Optional |
| resolving_comment | User input that explains the resolution of the incident and the classification choice. It contains free editable text. | Optional |
| custom_tags | Array of custom tags associated with an incident. | Optional |
| timeout | The time limit in seconds for the http request to run. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.Incident.assignedTo | String | Owner of the incident, or null if no owner is assigned. Free editable text. |
| MsGraph.Incident.classification | String | The specification for the incident. Possible values are unknown, falsePositive, truePositive, informationalExpectedActivity, unknownFutureValue. |
| MsGraph.Incident.comments | String | Array of comments created by the Security Operations (SecOps) team when the incident is managed. |
| MsGraph.Incident.createdDateTime | Date | Time when the incident was first created. |
| MsGraph.Incident.customTags | String | Array of custom tags associated with an incident. |
| MsGraph.Incident.description | String | Description of the incident. |
| MsGraph.Incident.determination | String | Specifies the determination of the incident. Possible values are unknown, apt, malware, securityPersonnel, securityTesting, unwantedSoftware, other, multiStagedAttack, compromisedUser, phishing, maliciousUserActivity, clean, insufficientData, confirmedUserActivity, lineOfBusinessApplication, unknownFutureValue. |
| MsGraph.Incident.displayName | String | The incident name. |
| MsGraph.Incident.id | String | Unique identifier to represent the incident. |
| MsGraph.Incident.incidentWebUrl | String | The URL for the incident page in the Microsoft 365 Defender portal. |
| MsGraph.Incident.lastModifiedBy | String | The identity that last modified the incident. |
| MsGraph.Incident.lastUpdateDateTime | Date | Time when the incident was last updated. |
| MsGraph.Incident.redirectIncidentId | String | Only populated in case an incident is grouped with another incident, as part of the logic that processes incidents. In such a case, the status property is redirected. |
| MsGraph.Incident.severity | String | Indicates the possible impact on assets. The higher the severity, the greater the impact. Typically higher severity items require the most immediate attention. Possible values are unknown, informational, low, medium, high, unknownFutureValue. |
| MsGraph.Incident.status | String | The status of the incident. Possible values are active, resolved, inProgress, redirected, unknownFutureValue, and awaitingAction. |
| MsGraph.Incident.tenantId | String | The Microsoft Entra tenant in which the alert was created. |
| MsGraph.Incident.systemTags | String collection | The system tags associated with the incident. |
Command example
!msg-update-security-incident incident_id=12345
Context Example
{
"MsGraph": {
"Incidents": {
"assignedTo": "test5",
"classification": "unknown",
"comments": [],
"createdDateTime": "2024-03-17T15:50:31.9033333Z",
"customTags": [],
"description": null,
"determination": "unknown",
"displayName": "Exfiltration incident involving one user",
"id": "12345",
"incidentWebUrl": "https://security.microsoft.com/incidents/12345?tid=abc123",
"lastModifiedBy": "Microsoft 365 Defender-AlertCorrelation",
"lastUpdateDateTime": "2024-03-19T07:24:34.7066667Z",
"redirectIncidentId": null,
"severity": "medium",
"status": "active",
"systemTags": [],
"tenantId": "abc123"
}
}
}
Human Readable Output
Updated incident No. 12345
Display name id Severity Status Assigned to Custom tags System tags Classification Determination Created date time Updated date time Exfiltration incident involving one user 12345 medium active test5 unknown unknown 2024-03-17T15:50:31.9033333Z 2024-03-19T07:24:34.7066667Z msg-run-estimate-statistics
Starts an eDiscovery estimate statistics operation in Microsoft Purview. The operation calculates the size and number of items matching the search query.
Base Command
msg-run-estimate-statistics
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. | Required |
| statistics_options | Bitwise options that specify the statistics to generate. The possible values are: includeRefiners, includeQueryStats, includeUnindexedStats, advancedIndexing, locationsWithoutHits. The advancedIndexing and locationsWithoutHits values are only considered if includeUnindexedStats is set. Possible values are: includeRefiners, includeQueryStats, includeUnindexedStats, advancedIndexing, locationsWithoutHits. | Optional |
Context Output
There is no context output for this command.
msg-get-last-estimate-statistics-operation
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.
Base Command
msg-get-last-estimate-statistics-operation
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the eDiscovery search. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscovery.EstimateStatistics.CaseID | String | The ID of the eDiscovery case. |
| MsGraph.eDiscovery.EstimateStatistics.SearchID | String | The ID of the eDiscovery search. |
| MsGraph.eDiscovery.EstimateStatistics.OperationID | String | The ID of the last estimate statistics operation. |
| MsGraph.eDiscovery.EstimateStatistics.Status | String | The current status of the last estimate statistics operation (e.g., running, succeeded, failed). |
| MsGraph.eDiscovery.EstimateStatistics.PercentProgress | Number | The percent progress of the last estimate statistics operation. |
| MsGraph.eDiscovery.EstimateStatistics.CreatedDateTime | Date | The date and time when the estimate operation was created. |
| MsGraph.eDiscovery.EstimateStatistics.CompletedDateTime | Date | The date and time when the estimate operation completed. |
| MsGraph.eDiscovery.EstimateStatistics.IndexedItemsCount | Number | The number of indexed items found in the search. |
| MsGraph.eDiscovery.EstimateStatistics.IndexedItemsSize | Number | The total size (in bytes) of indexed items. |
| MsGraph.eDiscovery.EstimateStatistics.UnindexedItemsCount | Number | The number of unindexed items found in the search. |
| MsGraph.eDiscovery.EstimateStatistics.UnindexedItemsSize | Number | The total size (in bytes) of unindexed items. |
| MsGraph.eDiscovery.EstimateStatistics.TotalItemsCount | Number | The total number of items (indexed + unindexed). |
| MsGraph.eDiscovery.EstimateStatistics.TotalItemsSize | Number | The total size (in bytes) of all items (indexed + unindexed). |
msg-list-ediscovery-case-hold-policy
Get a list of the ediscoveryHoldPolicy objects and their properties.
Base Command
msg-list-ediscovery-case-hold-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| hold_policy_id | The ID of the legal hold policy. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.HoldPolicy.ID | String | The ID of the eDiscovery hold policy. |
| MsGraph.eDiscoveryCase.HoldPolicy.DisplayName | String | The display name of the legal hold. |
| MsGraph.eDiscoveryCase.HoldPolicy.Description | String | The legal hold description. |
| MsGraph.eDiscoveryCase.HoldPolicy.ContentQuery | String | KQL query that specifies content to be held. If empty, all content in the specified locations is held. |
| MsGraph.eDiscoveryCase.HoldPolicy.IsEnabled | Boolean | Indicates whether the hold is enabled and actively holding content. |
| MsGraph.eDiscoveryCase.HoldPolicy.Status | String | The status of the legal hold. Possible values are Pending, Error, Success. |
| MsGraph.eDiscoveryCase.HoldPolicy.Errors | String | Lists any errors that happened while placing the hold. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedDateTime | Date | The date and time the legal hold was created. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedDateTime | Date | The date and time the legal hold was last modified. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.ID | String | The unique identifier of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.DisplayName | String | The display name of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.TenantId | String | The tenant ID of the application identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.ID | String | The unique identifier of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.DisplayName | String | The display name of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.TenantId | String | The tenant ID of the application instance identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.ID | String | The unique identifier of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.DisplayName | String | The display name of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.TenantId | String | The tenant ID of the conversation identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.ID | String | The identifier describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.DisplayName | String | The display name describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.TenantId | String | The tenant ID of the conversation identity type. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.ID | String | The unique identifier of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.DisplayName | String | The display name of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.TenantId | String | The tenant ID of the device identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.ID | String | The unique identifier of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.DisplayName | String | The display name of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.TenantId | String | The tenant ID of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.ID | String | The unique identifier of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.DisplayName | String | The display name of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.TenantId | String | The tenant ID of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.ID | String | The unique identifier of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.DisplayName | String | The display name of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.TenantId | String | The tenant ID of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.ID | String | The unique identifier of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.DisplayName | String | The display name of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.TenantId | String | The tenant ID of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.ID | String | The unique identifier of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.DisplayName | String | The display name of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.TenantId | String | The tenant ID of the user identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.ID | String | The unique identifier of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.DisplayName | String | The display name of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.TenantId | String | The tenant ID of the application identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.ID | String | The unique identifier of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.DisplayName | String | The display name of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.TenantId | String | The tenant ID of the application instance identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.ID | String | The unique identifier of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.DisplayName | String | The display name of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.TenantId | String | The tenant ID of the conversation identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.ID | String | The identifier describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.DisplayName | String | The display name describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.TenantId | String | The tenant ID of the conversation identity type. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.ID | String | The unique identifier of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.DisplayName | String | The display name of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.TenantId | String | The tenant ID of the device identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.ID | String | The unique identifier of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.DisplayName | String | The display name of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.TenantId | String | The tenant ID of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.ID | String | The unique identifier of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.DisplayName | String | The display name of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.TenantId | String | The tenant ID of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.ID | String | The unique identifier of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.DisplayName | String | The display name of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.TenantId | String | The tenant ID of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.ID | String | The unique identifier of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.DisplayName | String | The display name of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.TenantId | String | The tenant ID of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.ID | String | The unique identifier of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.DisplayName | String | The display name of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.TenantId | String | The tenant ID of the user identity associated with this action. |
msg-export-result-ediscovery-data
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).
Base Command
msg-export-result-ediscovery-data
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| search_id | The ID of the search. | Required |
| additional_options | The additional options for the export. Possible values are: none, teamsAndYammerConversations, cloudAttachments, allDocumentVersions, subfolderContents, listAttachments, htmlTranscripts, advancedIndexing, allItemsInFolder, includeFolderAndPath, condensePaths, friendlyName, splitSource, includeReport. | Required |
| export_criteria | The portion of the estimate results to be exported. Possible values are: searchHits, partiallyIndexed. | Required |
| export_format | The desired format of the exported emails. Possible values are: pst, msg. | Required |
| cloud_attachment_version | The versions of cloud attachments to include in messages. Possible values are: latest, recent10, recent100, all. Default is latest. | Optional |
| description | The description of the export result. | Optional |
| display_name | The display name of the export result. | Required |
| document_version | The versions of files in SharePoint to include. Possible values are: latest, recent10, recent100, all. Default is latest. | Optional |
| export_location | Location scope for partially indexed items. You can choose to include partially indexed items only in responsive locations with search hits or in all targeted locations. Possible values are: responsiveLocations, nonresponsiveLocations. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.Export.OperationID | String | The ID of the export operation. Use this ID to retrieve the operation status via ‘msg-list-case-operation’. |
| MsGraph.eDiscoveryCase.Export.CaseID | String | The ID of the eDiscovery case the export belongs to. |
| MsGraph.eDiscoveryCase.Export.Location | String | The Location header URL returned for the export operation. |
Command example
!msg-export-result-ediscovery-data case_id=00000000-0000-0000-0000-000000000000 search_id=11111111-1111-1111-1111-111111111111 additional_options=none export_criteria=searchHits export_format=pst display_name="Example Export"
Context Example
{
"MsGraph": {
"eDiscoveryCase": {
"Export": {
"CaseID": "00000000-0000-0000-0000-000000000000",
"Location": "https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/00000000-0000-0000-0000-000000000000/operations/example-operation-id",
"OperationID": "example-operation-id"
}
}
}
}
Human Readable Output
eDiscovery export request was submitted successfully.
- Case ID: 00000000-0000-0000-0000-000000000000
- Operation ID: example-operation-id
msg-delete-ediscovery-case-hold-policy
Delete an eDiscovery hold policy. This command submits a deletion request to Microsoft Graph; the policy may not be removed immediately and can take some time to complete.
Base Command
msg-delete-ediscovery-case-hold-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| hold_policy_id | The policy ID that is intended to be deleted. | Required |
Context Output
There is no context output for this command.
msg-list-case-operation
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).
Base Command
msg-list-case-operation
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| operation_id | The ID of the operation. | Optional |
| limit | Number of total results to return. Default is 50. | Optional |
| all_results | Show all results if true. Possible values are: true, false. Default is false. | Optional |
| download_file | Download the export report when an export file link is available. This only applies if operation_id is provided. For authorization or permission errors while downloading, see: https://learn.microsoft.com/en-us/graph/api/security-caseoperation-get?view=graph-rest-1.0&tabs=http#response-1. Possible values are: true, false. Default is false. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.Operation.ID | String | The ID of the case operation. Read-only. |
| MsGraph.eDiscoveryCase.Operation.Action | String | The type of action the operation represents (caseAction). Example values: contentExport, applyTags, convertToPdf, index, estimateStatistics, addToReviewSet, holdUpdate, purgeData, exportReport, exportResult, holdPolicySync. |
| MsGraph.eDiscoveryCase.Operation.Status | String | The status of the case operation. Possible values: notStarted, submissionFailed, running, succeeded, partiallySucceeded, failed. |
| MsGraph.eDiscoveryCase.Operation.PercentProgress | Number | The progress of the operation. |
| MsGraph.eDiscoveryCase.Operation.CreatedDateTime | Date | The date and time the operation was created. |
| MsGraph.eDiscoveryCase.Operation.CompletedDateTime | Date | The date and time the operation was completed. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Application.ID | String | The unique identifier of the application associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Application.DisplayName | String | The display name of the application associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Application.TenantId | String | The tenant ID of the application identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ApplicationInstance.ID | String | The unique identifier of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ApplicationInstance.DisplayName | String | The display name of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ApplicationInstance.TenantId | String | The tenant ID of the application instance identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Conversation.ID | String | The unique identifier of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Conversation.DisplayName | String | The display name of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Conversation.TenantId | String | The tenant ID of the conversation identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ConversationIdentityType.ID | String | The identifier describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ConversationIdentityType.DisplayName | String | The display name describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.ConversationIdentityType.TenantId | String | The tenant ID of the conversation identity type. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Device.ID | String | The unique identifier of the device associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Device.DisplayName | String | The display name of the device associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Device.TenantId | String | The tenant ID of the device identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Encrypted.ID | String | The unique identifier of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Encrypted.DisplayName | String | The display name of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Encrypted.TenantId | String | The tenant ID of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.OnPremises.ID | String | The unique identifier of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.OnPremises.DisplayName | String | The display name of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.OnPremises.TenantId | String | The tenant ID of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Guest.ID | String | The unique identifier of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Guest.DisplayName | String | The display name of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Guest.TenantId | String | The tenant ID of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Phone.ID | String | The unique identifier of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Phone.DisplayName | String | The display name of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.Phone.TenantId | String | The tenant ID of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.User.ID | String | The unique identifier of the user associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.User.DisplayName | String | The display name of the user associated with this action. |
| MsGraph.eDiscoveryCase.Operation.CreatedBy.User.TenantId | String | The tenant ID of the user identity associated with this action. |
| MsGraph.eDiscoveryCase.Operation.ResultInfo.Code | Number | The result code (2xx success, 4xx client error, 5xx server error). |
| MsGraph.eDiscoveryCase.Operation.ResultInfo.Message | String | The result message. |
| MsGraph.eDiscoveryCase.Operation.ResultInfo.Subcode | Number | The result subcode. |
| File.Size | Number | The size of the file. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.Name | String | The name of the file. |
| File.SSDeep | String | The SSDeep hash of the file. |
| File.EntryID | String | The entry ID of the file. |
| File.Info | String | File information. |
| File.Type | String | The file type. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Extension | String | The file extension. |
msg-create-ediscovery-case-hold-policy
Create a new ediscoveryHoldPolicy object.
Base Command
msg-create-ediscovery-case-hold-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| display_name | The display name of the legal hold policy. | Required |
| description | The description of the legal hold policy. | Optional |
| content_query | KQL query specifying content to be held in the specified locations. Learn about KQL (https://learn.microsoft.com/en-us/kusto/query/?view=azure-data-explorer&preserve-view=true). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MsGraph.eDiscoveryCase.HoldPolicy.ID | String | The ID of the eDiscovery hold policy. |
| MsGraph.eDiscoveryCase.HoldPolicy.DisplayName | String | The display name of the legal hold. |
| MsGraph.eDiscoveryCase.HoldPolicy.Description | String | The legal hold description. |
| MsGraph.eDiscoveryCase.HoldPolicy.ContentQuery | String | KQL query that specifies content to be held. If empty, all content in the specified locations is held. |
| MsGraph.eDiscoveryCase.HoldPolicy.IsEnabled | Boolean | Indicates whether the hold is enabled and actively holding content. |
| MsGraph.eDiscoveryCase.HoldPolicy.Status | String | The status of the legal hold. Possible values are Pending, Error, Success. |
| MsGraph.eDiscoveryCase.HoldPolicy.Errors | String | Lists any errors that happened while placing the hold. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedDateTime | Date | The date and time the legal hold was created. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedDateTime | Date | The date and time the legal hold was last modified. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.ID | String | The unique identifier of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.DisplayName | String | The display name of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Application.TenantId | String | The tenant ID of the application identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.ID | String | The unique identifier of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.DisplayName | String | The display name of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ApplicationInstance.TenantId | String | The tenant ID of the application instance identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.ID | String | The unique identifier of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.DisplayName | String | The display name of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Conversation.TenantId | String | The tenant ID of the conversation identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.ID | String | The identifier describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.DisplayName | String | The display name describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.ConversationIdentityType.TenantId | String | The tenant ID of the conversation identity type. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.ID | String | The unique identifier of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.DisplayName | String | The display name of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Device.TenantId | String | The tenant ID of the device identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.ID | String | The unique identifier of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.DisplayName | String | The display name of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Encrypted.TenantId | String | The tenant ID of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.ID | String | The unique identifier of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.DisplayName | String | The display name of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.OnPremises.TenantId | String | The tenant ID of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.ID | String | The unique identifier of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.DisplayName | String | The display name of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Guest.TenantId | String | The tenant ID of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.ID | String | The unique identifier of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.DisplayName | String | The display name of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.Phone.TenantId | String | The tenant ID of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.ID | String | The unique identifier of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.DisplayName | String | The display name of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.CreatedBy.User.TenantId | String | The tenant ID of the user identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.ID | String | The unique identifier of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.DisplayName | String | The display name of the application associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Application.TenantId | String | The tenant ID of the application identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.ID | String | The unique identifier of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.DisplayName | String | The display name of the application instance associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ApplicationInstance.TenantId | String | The tenant ID of the application instance identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.ID | String | The unique identifier of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.DisplayName | String | The display name of the conversation (team or channel) associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Conversation.TenantId | String | The tenant ID of the conversation identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.ID | String | The identifier describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.DisplayName | String | The display name describing whether the conversation identifies a team or channel. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.ConversationIdentityType.TenantId | String | The tenant ID of the conversation identity type. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.ID | String | The unique identifier of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.DisplayName | String | The display name of the device associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Device.TenantId | String | The tenant ID of the device identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.ID | String | The unique identifier of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.DisplayName | String | The display name of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Encrypted.TenantId | String | The tenant ID of the encrypted identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.ID | String | The unique identifier of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.DisplayName | String | The display name of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.OnPremises.TenantId | String | The tenant ID of the on-premises identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.ID | String | The unique identifier of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.DisplayName | String | The display name of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Guest.TenantId | String | The tenant ID of the guest identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.ID | String | The unique identifier of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.DisplayName | String | The display name of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.Phone.TenantId | String | The tenant ID of the phone identity associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.ID | String | The unique identifier of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.DisplayName | String | The display name of the user associated with this action. |
| MsGraph.eDiscoveryCase.HoldPolicy.LastModifiedBy.User.TenantId | String | The tenant ID of the user identity associated with this action. |
msg-update-ediscovery-case-hold-policy
Update the properties of an ediscoveryHoldPolicy object.
Base Command
msg-update-ediscovery-case-hold-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the eDiscovery case. | Required |
| hold_policy_id | The policy ID that is intended to be updated. | Required |
| description | The description of the legal hold policy. | Optional |
| content_query | KQL query specifying content to be held in the specified locations. Learn about KQL (https://learn.microsoft.com/en-us/kusto/query/?view=azure-data-explorer&preserve-view=true). | Optional |
Context Output
There is no context output for this command.
<~PLATFORM>
License Requirements
The following configuration parameters require one of these licenses: Cortex XSIAM or Agentix:
- Fetch incidents
</~PLATFORM>
Configuration parameters
azure_cloud— Azure Cloudhost— Host URLcreds_auth_id—creds_tenant_id—creds_enc_key—auth_id— Application ID or Client IDtenant_id— Token or Tenant IDenc_key— Key or Client Secretcreds_certificate— Certificate Thumbprintcertificate_thumbprint— Certificate Thumbprintprivate_key— Private Keyredirect_uri— Application redirect URI (for self-deployed mode)auth_code— Authorization codeuse_managed_identities— Use Azure Managed Identitiesmanaged_identities_client_id—insecure— Trust any certificate (not secure)proxy— Use system proxy settingsself_deployed— Use a self-deployed Azure applicationisFetch— Fetch incidentsincidentFetchInterval— Incidents Fetch IntervalincidentType— Incident typefetch_incidents_type— Fetch incidents typefetch_time— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)fetch_limit— Fetch limit per typefetch_service_sources— Alerts Service Sourcesfetch_filter— Alerts Filterfetch_incidents_filter— Incidents Filtermicrosoft_365_defender_context— Microsoft 365 Defender context
Commands (48)
-
ms-graph-security-auth-resetRun this command if for some reason you need to rerun the authentication process.
-
msg-activate-ediscovery-custodianActivate a custodian that has been released from a case to make them part of the case again. For details, see https://learn.microsoft.com/en-us/microsoft-365/compliance/ediscovery-manage-new-custodians?view=o365-worldwide#re-activate-custodian.
-
msg-advanced-huntingAdvanced hunting is a threat-hunting tool that uses specially constructed queries to examine the past 30 days of event data in Microsoft Graph Security.
-
msg-apply-hold-ediscovery-custodianStart the process of applying hold on eDiscovery custodians. Available return statuses: notApplied - The custodian is not on hold (all sources in it are not on hold). applied - The custodian is on hold (all sources are on hold). applying - The custodian is in applying the hold state (applyHold operation triggered). removing - The custodian is in removing the hold state(removeHold operation triggered). partial - The custodian is in a mixed state where some sources are on hold and some not on hold or error state.
-
msg-auth-testTests connectivity to Microsoft Graph Security.
-
msg-close-ediscovery-caseClose an eDiscovery case. When the legal case or investigation supported by a eDiscovery (Standard) case is completed, you can close the case. Here's what happens when you close a case: If the case contains any eDiscovery holds, they'll be turned off. After the hold is turned off, a 30-day grace period (called a delay hold) is applied to content locations that were on hold. This helps prevent content from being immediately deleted and provides admins the opportunity to search for and restore content before it may be permanently deleted after the delay hold period expires. For more information, see Removing content locations from an eDiscovery hold. Closing a case only turns off the holds that are associated with that case. If other holds are placed on a content location (such as a Litigation Hold, a retention policy, or a hold from a different eDiscovery (Standard) case) those holds will still be maintained. The case is still listed on the eDiscovery (Standard) page in the Microsoft Purview compliance portal. The details, holds, searches, and members of a closed case are retained. You can edit a case after it's closed. For example, you can add or remove members, create searches, and export search results. The primary difference between active and closed cases is that eDiscovery holds are turned off when a case is closed.
-
msg-create-alert-commentCreate a comment for an existing alert.
-
msg-create-ediscovery-caseCreate 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.
-
msg-create-ediscovery-case-hold-policyCreate a new ediscoveryHoldPolicy object.
-
msg-create-ediscovery-custodianCreate a new ediscoveryCustodian object. After the custodian object is created, you will need to create the custodian's userSource to reference their mailbox and OneDrive for Business site.
-
msg-create-ediscovery-custodian-site-sourceCreate a new siteSource object associated with an eDiscovery custodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
-
msg-create-ediscovery-custodian-user-sourceCreate a new userSource object associated with an eDiscovery custodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
-
msg-create-ediscovery-non-custodial-data-sourceCreate a new eDiscoveryNoncustodialDataSource object.
-
msg-create-ediscovery-searchCreate a new eDiscoverySearch object.
-
msg-create-email-file-assessment-requestCreate email file assessment request.
-
msg-create-file-assessment-requestCreate file assessment request.
-
msg-create-mail-assessment-requestCreate and retrieve a mail threat assessment.
-
msg-create-url-assessment-requestCreate the URL assessment request.
-
msg-delete-ediscovery-caseDelete an eDiscovery case. Before you can delete a case, you must first delete all holds listed on the holds page of the case. That includes deleting holds with a status of Off. Default hold policies can only be deleted when the hold is turned off. You must close an active case to turn off any default hold policies in the case. Once the holds are turned off for default hold policies, they can be deleted.
-
msg-delete-ediscovery-case-hold-policyDelete an eDiscovery hold policy. This command submits a deletion request to Microsoft Graph; the policy may not be removed immediately and can take some time to complete.
-
msg-delete-ediscovery-searchDelete an eDiscoverySearch object.
-
msg-export-result-ediscovery-dataExport 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).
-
msg-generate-login-urlGenerate the login URL used for authorization code flow.
-
msg-get-alert-detailsGet details for a specific alert.
-
msg-get-last-estimate-statistics-operationRetrieves 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.
-
msg-get-userDeprecatedDeprecated. Use the Entra ID Users integration instead.
-
msg-get-usersDeprecatedDeprecated. Use the Entra ID Users integration instead.
-
msg-list-case-operationGet 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).
-
msg-list-ediscovery-case-hold-policyGet a list of the ediscoveryHoldPolicy objects and their properties.
-
msg-list-ediscovery-casesGet a list of the eDiscovery cases.
-
msg-list-ediscovery-custodian-site-sourcesGet a list of the siteSource objects associated with an eDiscoveryCustodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
-
msg-list-ediscovery-custodian-user-sourcesGet a list of the userSource objects associated with an eDiscoveryCustodian. Use the msg-list-ediscovery-custodians command in order to get all available custodians.
-
msg-list-ediscovery-custodiansGet a list of the custodians on a given eDiscovery case.
-
msg-list-ediscovery-non-custodial-data-sourcesGet a list of the non-custodial data sources and their properties.
-
msg-list-ediscovery-searchsGet a list of eDiscoverySearch resources from an eDiscovery case.
-
msg-list-security-incidentGet a list of incident objects that Microsoft graph created to track attacks in an organization. If you want a specific incident, just enter incident_id.
-
msg-list-threat-assessment-requestsGet a list of the threat assessment requests.
-
msg-purge-ediscovery-dataDeletes 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.
-
msg-release-ediscovery-custodianRelease a custodian from a case. For details, see https://learn.microsoft.com/en-us/microsoft-365/compliance/manage-new-custodians#release-a-custodian-from-a-case.
-
msg-remove-hold-ediscovery-custodianStart the process of removing a hold from eDiscovery custodians.
-
msg-reopen-ediscovery-caseReopen an eDiscovery case. When you reopen an eDiscovery (Premium) case, any holds that were in place when the case was closed won't be automatically reinstated. After the case is reopened, you'll have to go to the Holds tab and turn on the previous holds. To turn on a hold, select it to display the flyout page, and then set the Status toggle to On.
-
msg-run-estimate-statisticsStarts an eDiscovery estimate statistics operation in Microsoft Purview. The operation calculates the size and number of items matching the search query.
-
msg-search-alertsGet a list of alerts (security issues) within a customer's tenant that Microsoft or partner security solutions have identified.
-
msg-update-alertUpdate an editable alert property within any integrated solution to keep alert status and assignments in sync across solutions using its reference ID.
-
msg-update-ediscovery-caseUpdate an eDiscovery case.
-
msg-update-ediscovery-case-hold-policyUpdate the properties of an ediscoveryHoldPolicy object.
-
msg-update-ediscovery-searchUpdate an eDiscoverySearch object.
-
msg-update-security-incidentUpdate the incident with the given ID.
import itertools import json import re from types import SimpleNamespace from unittest.mock import MagicMock import demistomock as demisto import pytest from CommonServerPython import DemistoException, CommandResults, PollResult from MicrosoftGraphSecurity import ( MANAGED_IDENTITIES_TOKEN_URL, MsGraphClient, Resources, activate_ediscovery_custodian_command, advanced_hunting_command, capitalize_dict_keys_first_letter, close_ediscovery_case_command, create_alert_comment_command, create_data_to_update, create_ediscovery_non_custodial_data_source_command, create_email_file_request_command, create_file_assessment_request_command, create_filter_query, create_mail_assessment_request_command, create_search_alerts_filters, create_url_assessment_request_command, created_by_fields_to_hr, fetch_alerts, fetch_incidents, fetch_incidents_and_alerts, get_alert_details_command, get_list_security_incident_command, get_message_user, get_users_command, list_ediscovery_case_command, list_ediscovery_custodian_command, list_ediscovery_custodian_site_sources_command, list_ediscovery_non_custodial_data_source_command, list_ediscovery_search_command, list_threat_assessment_requests_command, main, purge_ediscovery_data_command, release_ediscovery_custodian_command, reopen_ediscovery_case_command, search_alerts_command, set_url_suffix_list_incidents, to_msg_command_results, update_ediscovery_case_command, update_ediscovery_search_command, update_incident_command, create_ediscovery_case_hold_policy_command, delete_ediscovery_case_hold_policy_command, update_ediscovery_case_policy_command, list_ediscovery_case_hold_policy_command, list_case_operation_command, _extract_export_download_url, _extract_filename_from_headers, _download_operation_export_file, export_result_ediscovery_data_command, ) client_mocker = MsGraphClient( tenant_id="tenant_id", auth_id="auth_id", enc_key="enc_key", app_name="app_name", base_url="url", verify="use_ssl", proxy="proxy", self_deployed="self_deployed", ) def load_json(path): with open(path, encoding="utf-8") as f: return json.load(f) @pytest.mark.parametrize( "api_response, keys_to_replace, expected_output", [ ( {"keyOne": {"keyTwo": {"keyThree": "a"}, "keyFour": {"keyFive": "b"}}}, {}, {"KeyOne": {"KeyFour": {"KeyFive": "b"}, "KeyTwo": {"KeyThree": "a"}}}, ), ( {"keyOne": {"keyTwo": "a"}, "customOverride": "a"}, {"customOverride": "SOMETHING"}, {"KeyOne": {"KeyTwo": "a"}, "SOMETHING": "a"}, ), ], ) def test_capitalize_dict_keys_first_letter(api_response, keys_to_replace, expected_output): """ Given a response from the api When calling capitalize_dict_keys_first_letter with optional keys_to_replace Then Results are recursively formatted, manual keys are replaces """ assert capitalize_dict_keys_first_letter(api_response, keys_to_replace) == expected_output def test_get_users_command(mocker): test_data = load_json("./test_data/test_get_users_command.json") mocker.patch.object(client_mocker, "get_users", return_value=test_data.get("raw_user_data")) hr, ec, _ = get_users_command(client_mocker, {}) assert hr == test_data.get("expected_hr") assert ec == test_data.get("expected_ec") def mock_request(method, url_suffix, params): return params @pytest.mark.parametrize("test_case", ["test_case_3"]) def test_get_alert_details_command(mocker, test_case): """ Given: - test case that point to the relevant test case in the json test data which include: args including alert_id, response mock, expected hr and ec outputs. - Case 3: args with alert_id, response of an Alerts v2 alert. When: - Running get_alert_details_command. Then: - Ensure that the alert was parsed correctly and right HR and EC outputs are returned. - Case 3: Should parse all the response information into the HR, and all fields from the response into the ec. """ test_data = load_json("./test_data/test_get_alert_details_command.json").get(test_case) mocker.patch.object(client_mocker, "get_alert_details", return_value=test_data.get("mock_response")) hr, ec, _ = get_alert_details_command(client_mocker, test_data.get("args")) assert hr == test_data.get("expected_hr") assert ec == test_data.get("expected_ec") @pytest.mark.parametrize( "test_case", [ "test_case_2", ], ) def test_search_alerts_command(mocker, test_case): """ Given: - test case that point to the relevant test case in the json test data which include: args, response mock, expected hr and ec outputs. - Case 2: args with limit of 1 incident, response of a search_alert command results with 2 alerts. When: - Running search_alerts_command. Then: - Ensure that the response was parsed correctly and right HR and EC outputs are returned. - Case 2: Should concat the second incident from the response, parse all only the first incident response information into the HR, and all fields from the first incident response into the ec. """ test_data = load_json("./test_data/test_search_alerts_command.json").get(test_case) mocker.patch.object(client_mocker, "search_alerts", return_value=test_data.get("mock_response")) hr, ec, _ = search_alerts_command(client_mocker, test_data.get("args")) assert hr == test_data.get("expected_hr") assert ec == test_data.get("expected_ec") @pytest.mark.parametrize( "test_case", [ "test_case_1", ], ) def test_fetch_alerts_command(mocker, test_case): """ Given: - test case that point to the relevant test case in the json test data which include a response mock. - Case 1: Response of a search_alert command results. When: - Running fetch_alerts. Then: - Ensure that the length of the results and the different fields of the fetched alerts are returned correctly. - Case 1: Ensure that the len of the alerts returned in the first iteration is 3, then 1 and then 0. """ mocker.patch("MicrosoftGraphSecurity.parse_date_range", return_value=("2020-04-19 08:14:21", "never mind")) test_data = load_json("./test_data/test_fetch_incidents_command.json").get(test_case) mocker.patch.object(client_mocker, "search_alerts", return_value=test_data.get("mock_response")) alerts, _ = fetch_alerts(client_mocker, fetch_time="1 hour", fetch_limit=10, extra_filter="", service_sources="", last_run={}) assert len(alerts) == 3 assert alerts[0].get("severity") == 2 assert alerts[2].get("occurred") == "2020-04-20T16:54:50.2722072Z" alerts, _ = fetch_alerts(client_mocker, fetch_time="1 hour", fetch_limit=1, extra_filter="", service_sources="", last_run={}) assert len(alerts) == 1 assert alerts[0].get("name") == "test alert - da637218501473413212_-1554891308" alerts, _ = fetch_alerts(client_mocker, fetch_time="1 hour", fetch_limit=0, extra_filter="", service_sources="", last_run={}) assert len(alerts) == 0 def test_fetch_incidents_command(mocker): """ Given: - A mocked /security/incidents response with two incidents, each embedding its alerts. When: - Running fetch_incidents with an empty last_run. Then: - Both incidents are mapped to XSOAR incidents (name/occurred/severity/rawJSON). - The severity is mapped via SEVERITY_MAP and the embedded alerts are kept in rawJSON. - The returned last_run advances to the newest incident's createdDateTime. """ mocker.patch("MicrosoftGraphSecurity.parse_date_range", return_value=("2020-04-19T08:14:21.000000Z", "never mind")) mock_response = { "value": [ { "id": "1", "displayName": "Incident One", "createdDateTime": "2020-04-20T10:00:00.0000000Z", "severity": "medium", "alerts": [{"id": "a1", "title": "alert one"}], }, { "id": "2", "displayName": "Incident Two", "createdDateTime": "2020-04-20T11:00:00.0000000Z", "severity": "informational", "alerts": [{"id": "a2", "title": "alert two"}], }, ] } mocker.patch.object(client_mocker, "get_incidents_request", return_value=mock_response) incidents, new_last_run = fetch_incidents(client_mocker, fetch_time="1 hour", fetch_limit=10, extra_filter="", last_run={}) assert len(incidents) == 2 assert incidents[0].get("name") == "Incident One - 1" assert incidents[0].get("severity") == 2 assert incidents[1].get("severity") == 0.5 assert '"alerts"' in incidents[0].get("rawJSON") assert new_last_run.get("time") == "2020-04-20T11:00:00.0000000Z" def test_fetch_incidents_command_dedup_by_last_run(mocker): """ Given: - A last_run cursor set to the first incident's createdDateTime. When: - Running fetch_incidents. Then: - Only the newer incident (created after the cursor) is returned. """ mock_response = { "value": [ {"id": "1", "displayName": "Old", "createdDateTime": "2020-04-20T10:00:00.0000000Z", "severity": "low"}, {"id": "2", "displayName": "New", "createdDateTime": "2020-04-20T11:00:00.0000000Z", "severity": "high"}, ] } mocker.patch.object(client_mocker, "get_incidents_request", return_value=mock_response) incidents, _ = fetch_incidents( client_mocker, fetch_time="1 hour", fetch_limit=10, extra_filter="", last_run={"time": "2020-04-20T10:00:00.0000000Z"}, ) assert len(incidents) == 1 assert incidents[0].get("name") == "New - 2" def test_fetch_incidents_and_alerts_selection_gating(mocker): """ Given: - The "Fetch incidents type" parameter set to "Incidents" only. When: - Running fetch_incidents_and_alerts. Then: - Only fetch_incidents is called (alerts are not fetched). - The combined last run is persisted under the per-type "incidents_last_run" key. """ mocker.patch.object(demisto, "getLastRun", return_value={}) set_last_run = mocker.patch.object(demisto, "setLastRun") fetch_alerts_mock = mocker.patch( "MicrosoftGraphSecurity.fetch_alerts", return_value=([{"name": "alert"}], {"time": "alerts_cursor"}) ) fetch_incidents_mock = mocker.patch( "MicrosoftGraphSecurity.fetch_incidents", return_value=([{"name": "incident"}], {"time": "incidents_cursor"}) ) result = fetch_incidents_and_alerts(client_mocker, {"fetch_incidents_type": "Incidents"}) assert fetch_alerts_mock.call_count == 0 assert fetch_incidents_mock.call_count == 1 assert result == [{"name": "incident"}] set_last_run.assert_called_once_with({"incidents_last_run": {"time": "incidents_cursor"}}) def test_fetch_incidents_and_alerts_both_types(mocker): """ Given: - The "Fetch incidents type" parameter set to both "Alerts,Incidents". When: - Running fetch_incidents_and_alerts. Then: - Both fetchers are called and their results combined. - Each type's cursor is stored under its own last-run key. """ mocker.patch.object(demisto, "getLastRun", return_value={}) set_last_run = mocker.patch.object(demisto, "setLastRun") mocker.patch("MicrosoftGraphSecurity.fetch_alerts", return_value=([{"name": "alert"}], {"time": "alerts_cursor"})) mocker.patch("MicrosoftGraphSecurity.fetch_incidents", return_value=([{"name": "incident"}], {"time": "incidents_cursor"})) result = fetch_incidents_and_alerts(client_mocker, {"fetch_incidents_type": "Alerts,Incidents"}) assert {"name": "alert"} in result assert {"name": "incident"} in result set_last_run.assert_called_once_with( {"alerts_last_run": {"time": "alerts_cursor"}, "incidents_last_run": {"time": "incidents_cursor"}} ) def test_fetch_incidents_and_alerts_migrates_old_flat_last_run(mocker): """ Given: - An instance that was upgraded from a version storing the old flat last_run format: {"time": "..."}. When: - Running fetch_incidents_and_alerts for both types. Then: - The old flat cursor is migrated to the new nested format and passed to both fetchers, so the whole fetch window is not re-fetched (preventing duplicate incidents). """ old_time = "2020-04-20T10:00:00.0000000Z" mocker.patch.object(demisto, "getLastRun", return_value={"time": old_time}) mocker.patch.object(demisto, "setLastRun") fetch_alerts_mock = mocker.patch("MicrosoftGraphSecurity.fetch_alerts", return_value=([], {"time": old_time})) fetch_incidents_mock = mocker.patch("MicrosoftGraphSecurity.fetch_incidents", return_value=([], {"time": old_time})) fetch_incidents_and_alerts(client_mocker, {"fetch_incidents_type": "Alerts,Incidents"}) assert fetch_alerts_mock.call_args.kwargs["last_run"] == {"time": old_time} assert fetch_incidents_mock.call_args.kwargs["last_run"] == {"time": old_time} @pytest.mark.parametrize( "extra_data, should_expand", [("true", True), ("false", False), (None, False)], ) def test_set_url_suffix_list_incidents_extra_data(extra_data, should_expand): """ Given: - The msg-list-security-incident args, with the extra_data arg set to true/false/unset. When: - Building the request URL suffix. Then: - $expand=alerts is included only when extra_data is true. """ args = {"limit": "50"} if extra_data is not None: args["extra_data"] = extra_data url_suffix = set_url_suffix_list_incidents(args) assert ("$expand=alerts" in url_suffix) is should_expand def test_set_url_suffix_list_incidents_extra_data_with_filter(): """ Given: - extra_data=true together with a typed filter (severity). When: - Building the request URL suffix. Then: - Both $expand=alerts and the $filter clause are present. """ args = {"limit": "50", "extra_data": "true", "severity": "high"} url_suffix = set_url_suffix_list_incidents(args) assert "$expand=alerts" in url_suffix assert "$filter=severity eq 'high'" in url_suffix def test_fetch_incidents_does_not_mutate_last_run(mocker): """ Given: - A last_run dict passed to fetch_incidents. When: - Running fetch_incidents and it advances the cursor. Then: - The original last_run argument is not mutated (a copy is returned instead). """ mock_response = { "value": [ {"id": "2", "displayName": "New", "createdDateTime": "2020-04-20T11:00:00.0000000Z", "severity": "high"}, ] } mocker.patch.object(client_mocker, "get_incidents_request", return_value=mock_response) original_last_run = {"time": "2020-04-20T10:00:00.0000000Z"} _, new_last_run = fetch_incidents( client_mocker, fetch_time="1 hour", fetch_limit=10, extra_filter="", last_run=original_last_run ) assert original_last_run == {"time": "2020-04-20T10:00:00.0000000Z"} assert new_last_run is not original_last_run assert new_last_run.get("time") == "2020-04-20T11:00:00.0000000Z" def test_fetch_alerts_does_not_mutate_last_run(mocker): """ Given: - A last_run dict passed to fetch_alerts. When: - Running fetch_alerts and it advances the cursor. Then: - The original last_run argument is not mutated (a copy is returned instead). """ mock_response = { "value": [ {"id": "2", "title": "New", "createdDateTime": "2020-04-20T11:00:00.0000000Z", "severity": "high"}, ] } mocker.patch.object(client_mocker, "search_alerts", return_value=mock_response) original_last_run = {"time": "2020-04-20T10:00:00.0000000Z"} _, new_last_run = fetch_alerts( client_mocker, fetch_time="1 hour", fetch_limit=10, extra_filter="", service_sources="", last_run=original_last_run, ) assert original_last_run == {"time": "2020-04-20T10:00:00.0000000Z"} assert new_last_run is not original_last_run assert new_last_run.get("time") == "2020-04-20T11:00:00.0000000Z" @pytest.mark.parametrize( "args, expected_params, is_fetch", [ ( {"filter": "Category eq 'Malware' and Severity eq 'High'", "status": "resolved"}, {"$filter": "(Category eq 'Malware' and Severity eq 'High') and status eq 'resolved'"}, True, ), ( {"filter": "Category eq 'Malware' and Severity eq 'High'", "status": "resolved"}, {"$top": "50", "$filter": "(Category eq 'Malware' and Severity eq 'High') and status eq 'resolved'"}, False, ), ({"page": "2"}, {"$top": "50", "$skip": 100, "$filter": ""}, False), ], ) def test_create_search_alerts_filters(args, expected_params, is_fetch): """ Given: - args, expected_params results, and is_fetch flag. - Case 1: args with filter and status fields, is_fetch is True. - Case 2: args with filter and status fields, is_fetch is False. - Case 3: args with only page field, is_fetch is False. When: - Running create_search_alerts_filters. Then: - Ensure that the right fields were parsed into the query. - Case 1: Should include both the value of the filter field from the args (wrapped in parentheses) and the status. - Case 2: Should include the filter (wrapped in parentheses) and status in the $filter field, and 50 in the $top field. - Case 3: Should return a params dict with empty $filter field, 50 in the $top field, and 100 in the $skip field. """ params = create_search_alerts_filters(args, is_fetch=is_fetch) assert params == expected_params @pytest.mark.parametrize( "user_filter", [ "severity eq 'high' or severity eq 'medium'", "severity eq 'high'", ], ) def test_create_search_alerts_filters_wraps_user_filter_in_parentheses(user_filter): """ Given: - A time window (time_from/time_to) and a user-provided OData filter that may contain an `or` clause. When: - Running create_search_alerts_filters (the fetch-alerts path). Then: - The user filter must be wrapped in parentheses so that OData `and`/`or` precedence does not let an `or` clause escape the createdDateTime time window (regression test for the "pulls ~6 months of alerts" bug). """ args = { "time_from": "2020-04-20T10:00:00Z", "time_to": "2020-04-20T11:00:00Z", "filter": user_filter, } params = create_search_alerts_filters(args, is_fetch=True) expected = "createdDateTime ge 2020-04-20T10:00:00Z and " "createdDateTime le 2020-04-20T11:00:00Z and " f"({user_filter})" assert params["$filter"] == expected @pytest.mark.parametrize( "args, expected_error", [ ({"page_size": "2001"}, "Please note that the page size limit is 2000"), ], ) def test_create_search_alerts_filters_errors(args, expected_error): """ Given: - args and expected_error. - Case 1: Args with page_size = 2001. When: - Running create_search_alerts_filters. Then: - Ensure that the right error was thrown. - Case 1: Should throw an error for page_size too big. """ with pytest.raises(DemistoException) as e: create_search_alerts_filters(args, is_fetch=False) assert str(e.value.message) == expected_error @pytest.mark.parametrize(argnames="client_id", argvalues=["test_client_id", None]) def test_test_module_command_with_managed_identities(mocker, requests_mock, client_id): """ Given: - Managed Identities client id for authentication. When: - Calling test_module. Then: - Ensure the output are as expected. """ mock_token = {"access_token": "test_token", "expires_in": "86400"} get_mock = requests_mock.get(MANAGED_IDENTITIES_TOKEN_URL, json=mock_token) requests_mock.get(re.compile(f"^{Resources.graph}.*"), json={"value": []}) params = { "managed_identities_client_id": {"password": client_id}, "use_managed_identities": "True", "resource_group": "test_resource_group", "host": Resources.graph, } mocker.patch.object(demisto, "params", return_value=params) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(demisto, "results") mocker.patch("MicrosoftApiModule.get_integration_context", return_value={}) main() assert "ok" in demisto.results.call_args[0][0]["Contents"] qs = get_mock.last_request.qs assert qs["resource"] == [Resources.graph] assert (client_id and qs["client_id"] == [client_id]) or "client_id" not in qs @pytest.mark.parametrize( "args, expected_results", [ ({"status": "new"}, {"status": "new"}), ({"assigned_to": "someone", "status": "inProgress"}, {"assignedTo": "someone", "status": "inProgress"}), ( {"determination": "malware", "classification": "truePositive"}, {"determination": "malware", "classification": "truePositive"}, ), ], ) def test_create_data_to_update(args, expected_results): """ Given: - args and expected_results. - Case 1: args with status field. - Case 2: args with assigned_to and status fields. - Case 3: args with determination and classification fields. When: - Running create_data_to_update. Then: - Ensure that the right fields were parsed into the data dict. - Case 1: Should parse only status into the data dict. - Case 2: Should parse assigned_to as assignedTo and status into the data dict. - Case 3: Should parse determination and classification into the data dict. """ data = create_data_to_update(args) assert data == expected_results @pytest.mark.parametrize( "args, expected_error", [ ( {"closed_date_time": "now"}, "No data to update was provided, please provide at least one of the " "following: assigned_to, determination, classification, status.", ), ], ) def test_create_data_to_update_errors(args, expected_error): """ Given: - args and expected_error. - Case 1: Args with only 'closed_date_time' field (not a valid update field). When: - Running create_data_to_update. Then: - Ensure that the right error was thrown. - Case 1: Should throw an error for missing relevant data to update. """ with pytest.raises(DemistoException) as e: create_data_to_update(args) assert str(e.value.message) == expected_error @pytest.mark.parametrize("test_case", ["test_case_1", "test_case_2"]) def test_create_alert_comment_command(mocker, test_case): """ Given: - test case that point to the relevant test case in the json test data which include: args including alert_id and comment to add, response mock, and expected hr and ec outputs - Case 1: Mock response of a comment with only one comment (the one that just got added). - Case 2: Mock response of a comment with two comments. When: - Running create_alert_comment_command. Then: - Ensure that the alert was parsed correctly and right HR and EC outputs are returned. - Case 1: Should return a table with one entry. - Case 2: Should return a table with two entries, one for each comment. """ test_data = load_json("./test_data/test_create_alert_comment_command.json").get(test_case) mocker.patch.object(client_mocker, "create_alert_comment", return_value=test_data.get("mock_response")) hr, ec, _ = create_alert_comment_command(client_mocker, test_data.get("args")) assert hr == test_data.get("expected_hr") assert ec == test_data.get("expected_ec") @pytest.mark.parametrize( "param, service_sources_param, expected_results", [ ("param", "service_sources_param", "param"), ("", "service_sources_param", "serviceSource in ('service_sources_param')"), ( "", "service_source1,service_source2", "serviceSource in ('service_source1','service_source2')", ), ("", "", ""), ], ) def test_create_filter_query(param, service_sources_param, expected_results): """ Given: - param and service_sources_param function arguments, and expected_results. - Case 1: param and service_sources_param function arguments filled. - Case 2: Only service_sources_param function argument filled. - Case 3: Multiple service sources are provided. - Case 4: All arguments empty. When: - Running create_filter_query. Then: - Ensure that the right option was returned. - Case 1: Should return param. - Case 2: Should return service_sources_param as query. - Case 3: Should return service_sources_param as query operator $in. - Case 4: Should return an empty string. """ filter_query = create_filter_query(param, service_sources_param) assert filter_query == expected_results def test_to_msg_command_results(): """ Given: An example msg edsicvoery response When: calling to_msg_command_results Then: 1. Outputs are replaced properly 2. data.context is stripped out 3. none is removed """ res = load_json("./test_data/list_cases_response.json") results = to_msg_command_results( raw_object_list=res.get("value"), raw_res=res, outputs_prefix="MsGraph.SomePrefix", output_key_field="SomeId", raw_keys_to_replace={"status": "SomeStatus", "id": "SomeId"}, ) assert all("@odata.context" not in o for o in results.outputs) assert all("SomeId" in o for o in results.outputs) assert all("SomeId" in o for o in results.outputs) assert all(None not in o.values() for o in results.outputs) def test_create_ediscovery_custodian_site_source_command(mocker): """ Given: An example msg edsicvoery list site source response When: calling list_ediscovery_custodian_site_sources_command Then: 1. The proper URL is used in the request 2. @odata.id is stripped out of context 3. The proper ids and output prefixes are used """ mock = mocker.patch.object( client_mocker.ms_client, "http_request", return_value=load_json("./test_data/list_site_source_single.json") ) results = list_ediscovery_custodian_site_sources_command( client_mocker, {"case_id": "case_id", "custodian_id": "custodian_id"} ) assert mock.call_args.kwargs["url_suffix"] == "security/cases/ediscoveryCases/case_id/custodians/custodian_id/siteSources" assert not any("@odata.id" in o for o in results.outputs) assert results.outputs_prefix == "MsGraph.CustodianSiteSource" assert results.outputs_key_field == "SiteSourceId" assert all("SiteSourceId" in o for o in results.outputs) assert "Created By Name" in results.readable_output @pytest.mark.parametrize( "command_function, description, external_id", list( itertools.product( [update_ediscovery_case_command, update_ediscovery_search_command], ["value", "", None], ["value", "", None] ) ), ) def test_update_ediscovery_case_command(mocker, command_function, description, external_id): """ Given: update ediscovery commands When: an empty value is recieved as an argument Then: the argument shouldnt be sent to the api (dont want to override a real value with an update) """ mock = mocker.patch.object(client_mocker.ms_client, "http_request") some_id = "some_id" command_function( client_mocker, {"display_name": "name", "description": description, "external_id": external_id, "case_id": some_id} ) assert not set(mock.call_args.kwargs["json_data"].values()) & {None, ""} def test_created_by_fields_to_hr(): """ Given A context dictionary When Calling created_by_fields_to_hr Then get the created fields flattened onto main dict """ assert created_by_fields_to_hr( {"Field1": "val1", "CreatedBy": {"User": {"DisplayName": "Bob", "UserPrincipalName": "Frank"}}} ) == {"CreatedByAppName": None, "CreatedByName": "Bob", "CreatedByUPN": "Frank", "Field1": "val1"} def test_list_ediscovery_search_command(mocker): """ Given: A raw response with one result When: calling list search command Then: Prefixes are correct, nested value is in the readable output """ raw_response = load_json("./test_data/list_search_single_response.json") mocker.patch.object(client_mocker, "list_ediscovery_search", return_value=raw_response) results = list_ediscovery_search_command(client_mocker, {}) assert results.raw_response == raw_response assert results.outputs_key_field == "SearchId" assert results.outputs_key_field == "SearchId" assert results.outputs_prefix == "MsGraph.eDiscoverySearch" assert results.outputs[0]["CreatedBy"]["User"]["DisplayName"] in results.readable_output @pytest.mark.parametrize("command_to_check", ["all", "ediscovery", "alerts"]) def test_test_auth_code_command(mocker, command_to_check): """ Given a permission set to test When Calling test_auth_code_command Then The proper permissions are called """ from MicrosoftGraphSecurity import test_auth_code_command mock_ediscovery = mocker.patch.object( client_mocker, "list_ediscovery_cases", return_value=load_json("./test_data/list_cases_response.json") ) mock_alerts = mocker.patch("MicrosoftGraphSecurity.test_function") mock_threat_assessment = mocker.patch.object( client_mocker, "list_threat_assessment_requests", return_value=load_json("./test_data/list_threat_assessment.json") ) test_auth_code_command(client_mocker, {"permission_type": command_to_check}) if command_to_check == "alerts": assert not mock_ediscovery.called assert not mock_threat_assessment.called assert mock_alerts.called elif command_to_check == "any": assert mock_ediscovery.called assert mock_alerts.called assert mock_threat_assessment.called elif command_to_check == "ediscovery": assert mock_ediscovery.called assert not mock_alerts.called assert not mock_threat_assessment.called elif command_to_check == "threat assessment": assert not mock_ediscovery.called assert not mock_alerts.called assert mock_threat_assessment.called def test_purge_ediscovery_data_command(mocker): """ Given: A purge response with no Location header. When: Calling purge_ediscovery_data_command. Then: Ensure the status is success and the null Operation ID is removed from the context outputs. """ mocker.patch.object(client_mocker, "purge_ediscovery_data", return_value=SimpleNamespace(headers={})) result = purge_ediscovery_data_command(client_mocker, {}) assert result.readable_output == "eDiscovery purge status is success.\n- Operation ID: None" assert result.outputs == {"Status": "success"} assert result.outputs_prefix == "MsGraph.eDiscoveryCase.Purge" def test_purge_ediscovery_data_command_with_operation_id(mocker): """ Given: A purge response that includes a Location header with an operation ID. When: Calling purge_ediscovery_data_command. Then: Ensure the Operation ID is extracted and returned to the context outputs. """ location = "https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/case_123/operations/op_456" mocker.patch.object(client_mocker, "purge_ediscovery_data", return_value=SimpleNamespace(headers={"Location": location})) mocker.patch.object(client_mocker, "get", return_value={"status": "succeeded"}) result = purge_ediscovery_data_command(client_mocker, {}) assert result.outputs == {"OperationID": "op_456", "Status": "succeeded"} assert "op_456" in result.readable_output def test_purge_ediscovery_data_command_with_malformed_location(mocker): """ Given: A purge response that includes a Location header without a parseable operation ID. When: Calling purge_ediscovery_data_command. Then: Ensure the null Operation ID is removed from the context outputs and the readable output shows None. """ location = "https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/case_123/" mocker.patch.object(client_mocker, "purge_ediscovery_data", return_value=SimpleNamespace(headers={"Location": location})) mocker.patch.object(client_mocker, "get", return_value={"status": "succeeded"}) result = purge_ediscovery_data_command(client_mocker, {}) assert result.outputs == {"Status": "succeeded"} assert result.readable_output == "eDiscovery purge status is succeeded.\n- Operation ID: None" def test_list_ediscovery_non_custodial_data_source_command_empty_output(mocker): mocker.patch.object(client_mocker, "list_ediscovery_noncustodial_datasources", return_value={"value": []}) assert ( list_ediscovery_non_custodial_data_source_command(client_mocker, {}).readable_output == "### Results:\n**No entries.**\n" ) def test_list_ediscovery_case_command(mocker): raw_response = load_json("./test_data/list_cases_response.json") mocker.patch.object(client_mocker, "list_ediscovery_cases", return_value=raw_response) results = list_ediscovery_case_command(client_mocker, {}) assert len(raw_response["value"]) == len(results.outputs) assert all(output["CreatedDateTime"] in results.readable_output for output in results.outputs) def test_activate_ediscovery_custodian_command(mocker): mocker.patch.object(client_mocker, "activate_edsicovery_custodian", return_value=None) assert ( activate_ediscovery_custodian_command( client_mocker, {"case_id": "caseid", "custodian_id": "custodian_id"} ).readable_output == "Custodian with id custodian_id Case was reactivated on case with id caseid successfully." ) def test_release_ediscovery_custodian_command(mocker): mocker.patch.object(client_mocker, "release_edsicovery_custodian", return_value=None) assert ( release_ediscovery_custodian_command(client_mocker, {"case_id": "caseid", "custodian_id": "custodian_id"}).readable_output == "Custodian with id custodian_id was released from case with id caseid successfully." ) def test_close_ediscovery_case_command(mocker): mocker.patch.object(client_mocker, "close_edsicovery_case", return_value=None) assert ( close_ediscovery_case_command(client_mocker, {"case_id": "caseid"}).readable_output == "Case with id caseid was closed successfully." ) def test_reopen_ediscovery_case_command(mocker): mocker.patch.object(client_mocker, "reopen_edsicovery_case", return_value=None) assert ( reopen_ediscovery_case_command(client_mocker, {"case_id": "caseid"}).readable_output == "Case with id caseid was reopened successfully." ) @pytest.mark.parametrize( "site, email, should_error", [("exists", None, False), ("", "Exists", False), ("exists", "also exists", True), (None, None, True)], ) def test_create_ediscovery_non_custodial_data_source_command_invalid_args(mocker, site, email, should_error): """ Given: Arguments that arent valid for this command When: Calling the command Then An exception is raised """ mocker.patch.object(client_mocker, "create_ediscovery_non_custodial_data_source", return_value=None) try: create_ediscovery_non_custodial_data_source_command(client_mocker, {"site": site, "email": email}) assert not should_error except ValueError: assert should_error def test_empty_list_ediscovery_custodian_command(mocker): mocker.patch.object(client_mocker, "list_ediscovery_custodians", return_value={}) assert list_ediscovery_custodian_command(client_mocker, {}).readable_output == "### Results:\n**No entries.**\n" THREAT_ASSESSMENT_COMMANDS = { "mail_assessment_request": create_mail_assessment_request_command, "email_file_assessment_request": create_email_file_request_command, "file_assessment_request": create_file_assessment_request_command, "url_assessment_request": create_url_assessment_request_command, "list_assessment_requests": list_threat_assessment_requests_command, } @pytest.mark.parametrize( "mock_func, command_name, expected_result", [ ("create_mail_assessment_request", "mail_assessment_request", "mail_assessment_request.json"), ("create_email_file_assessment_request", "email_file_assessment_request", "email_file_assessment_request.json"), ("create_file_assessment_request", "file_assessment_request", "file_assessment_request.json"), ("create_url_assessment_request", "url_assessment_request", "url_assessment_request.json"), ], ) def test_create_mail_assessment_request_command(mocker, mock_func, command_name, expected_result): """ Given: A raw response with one result When: calling list search command Then: Nested value is in the readable output """ raw_response = load_json(f"./test_data/{expected_result}") mocker.patch.object(client_mocker, mock_func, return_value={"request_id": "123"}) mocker.patch.object(client_mocker, "get_threat_assessment_request_status", return_value={"status": "completed"}) mocker.patch.object(client_mocker, "get_threat_assessment_request", return_value=raw_response) mocker.patch("MicrosoftGraphSecurity.get_content_data", return_value="content_data") mocker.patch("MicrosoftGraphSecurity.get_message_user", return_value="user_mail") mocker.patch("CommonServerPython.is_demisto_version_ge", return_value=True) results = THREAT_ASSESSMENT_COMMANDS[command_name]({}, client_mocker) assert results.raw_response == raw_response assert results.outputs.get("ID") == raw_response.get("id") assert results.outputs.get("Content Type") == raw_response.get("contentType") def test_list_threat_assessment_requests_command(mocker): raw_response = load_json("./test_data/list_threat_assessment.json") mocker.patch.object(client_mocker, "list_threat_assessment_requests", return_value=raw_response) result = list_threat_assessment_requests_command(client_mocker, {}) assert len(result) == 2 assert result[0].outputs_prefix == "MSGraphMail.AssessmentRequest" assert len(result[0].outputs) == 4 assert result[1].outputs_prefix == "MsGraph.AssessmentRequestNextToken" assert result[1].outputs == {"next_token": "test_token"} @pytest.mark.parametrize("user, expected_result", [("testuser@test.com", "test user id"), ("test user id", "test user id")]) def test_get_message_user(mocker, user, expected_result): mocker.patch.object(client_mocker, "get_user_id", return_value={"value": [{"id": "test user id"}]}) message_user = get_message_user(client_mocker, user) assert message_user == expected_result def test_advanced_hunting_command(mocker): response = load_json("./test_data/advanced_hunting_response.json") mocker.patch.object(client_mocker, "advanced_hunting_request", return_value=response) args = {"query": "AlertInfo", "limit": 2, "timeout": 50} results = advanced_hunting_command(client_mocker, args) expected_results = load_json("./test_data/advanced_hunting_results.json") assert results.outputs_prefix == expected_results["outputs_prefix"] assert results.outputs_key_field == expected_results["outputs_key_field"] assert results.outputs == expected_results["outputs"] assert results.readable_output == expected_results["readable_output"] mocker.patch.object(demisto, "params", return_value={"microsoft_365_defender_context": True}) results = advanced_hunting_command(client_mocker, args) expected_results = load_json("./test_data/advanced_hunting_results_365_defenfer.json") assert results[1].outputs_prefix == expected_results["outputs_prefix"] assert results[1].outputs_key_field == expected_results["outputs_key_field"] assert results[1].outputs == expected_results["outputs"] assert results[1].readable_output == expected_results["readable_output"] def test_get_list_security_incident_command_single_case(mocker): response = load_json("./test_data/incidents_single_response.json") mocker.patch.object(client_mocker, "get_incidents_request", return_value=response) args = {"incident_id": 12345, "limit": 1, "timeout": 50} results = get_list_security_incident_command(client_mocker, args) expected_results = load_json("./test_data/incidents_single_results.json") assert results.outputs_prefix == expected_results["outputs_prefix"] assert results.outputs_key_field == expected_results["outputs_key_field"] assert results.outputs == expected_results["outputs"] assert results.readable_output == expected_results["readable_output"] def test_get_list_security_incident_command_list_case(mocker): response = load_json("./test_data/incidents_list_response.json") mocker.patch.object(client_mocker, "get_incidents_request", return_value=response) args = {"limit": 2, "timeout": 50} results = get_list_security_incident_command(client_mocker, args) expected_results = load_json("./test_data/incidents_list_results.json") assert results.outputs_prefix == expected_results["outputs_prefix"] assert results.outputs_key_field == expected_results["outputs_key_field"] assert results.outputs == expected_results["outputs"] assert results.readable_output == expected_results["readable_output"] def test_update_incident_command(mocker): response = load_json("./test_data/incident_update_response.json") mocker.patch.object(client_mocker, "update_incident_request", return_value=response) args = { "incident_id": "12345", "custom_tags": "test1,test2", "status": "active", "classification": "unknown", "determination": "unknown", "assigned_to": "", "severity": "unknown", "resolving_comment": "resolve_test", "timeout": 50, } results = update_incident_command(client_mocker, args) expected_results = load_json("./test_data/incident_update_results.json") assert results.outputs_prefix == expected_results["outputs_prefix"] assert results.outputs_key_field == expected_results["outputs_key_field"] assert results.outputs == expected_results["outputs"] assert results.readable_output == expected_results["readable_output"] from MicrosoftGraphSecurity import ( run_estimate_statistics_command, _get_last_estimate_statistics_command, ) # ============================== # Dummy Client # ============================== class DummyEstimateClient: """Dummy client simulating Microsoft Graph eDiscovery estimate statistics operations.""" def __init__(self): # Store operations by (case_id, search_id) self.operations = {} def start_estimate_statistics_request(self, case_id, search_id, statistics_options=None): """ Simulate starting an estimate statistics request. """ self.operations[(case_id, search_id)] = { "id": "OP123", "status": "running", "percentProgress": 0, "createdDateTime": "2025-11-16T10:00:00Z", "lastActionDateTime": "2025-11-16T10:00:00Z", "indexedItemCount": 100, "indexedItemsSize": 50000, "unindexedItemCount": 2, "unindexedItemsSize": 1024, "totalItemCount": 102, "totalItemsSize": 51024, "mailboxCount": 3, "siteCount": 2, "call_count": 0, # track how many times get_last was called } def get_last_estimate_statistics_operation(self, case_id, search_id): """ Simulate polling: first call returns running, second call returns succeeded. """ op = self.operations.get((case_id, search_id)) if not op: raise KeyError(f"No estimate operation found for case {case_id}, search {search_id}") # Increment call count op["call_count"] += 1 # First call: still running if op["call_count"] == 1: op["status"] = "running" op["percentProgress"] = 50 else: op["status"] = "succeeded" op["percentProgress"] = 100 return op # ============================== # Tests # ============================== def test_run_estimate_statistics_command(): """ Given: A case_id and search_id When: Calling run_estimate_statistics_command Then: The estimate request is started and confirmation CommandResults is returned """ client = DummyEstimateClient() args = {"case_id": "CASE1", "search_id": "SEARCH1"} result = run_estimate_statistics_command(client, args) assert isinstance(result, CommandResults) assert "initiated" in result.readable_output assert ("CASE1", "SEARCH1") in client.operations def test_get_last_estimate_statistics_command_missing_operation(): """ Given: A case_id and search_id with no started operation When: Calling get_last_estimate_statistics_command Then: Raises KeyError indicating no operation found """ client = DummyEstimateClient() args = {"case_id": "CASE_UNKNOWN", "search_id": "SEARCH_UNKNOWN"} with pytest.raises(KeyError) as e: _get_last_estimate_statistics_command(args, client) assert "No estimate operation found" in str(e.value) def test_get_last_estimate_statistics_command_pending(): args = {"case_id": "case-123", "search_id": "search-456"} mock_client = MagicMock() mock_client.get_last_estimate_statistics_operation.return_value = { "status": "running", "id": "op-123", "percentProgress": 50, } result = _get_last_estimate_statistics_command(args, mock_client) assert isinstance(result, PollResult) assert result.continue_to_poll is True assert result.args_for_next_run == args assert result.response is None assert isinstance(result.partial_result, CommandResults) assert "still running" in result.partial_result.readable_output.lower() def test_get_last_estimate_statistics_command_completed(): # Arrange args = {"case_id": "case-123", "search_id": "search-456"} mock_client = MagicMock() # Simulate a completed operation response_data = { "id": "op-789", "status": "Succeeded", "percentProgress": 100, "createdDateTime": "2025-11-16T00:00:00Z", "lastActionDateTime": "2025-11-16T01:00:00Z", "indexedItemCount": 50, "indexedItemsSize": 1024, "unindexedItemCount": 5, "unindexedItemsSize": 512, "totalItemCount": 55, "totalItemsSize": 1536, "mailboxCount": 3, "siteCount": 2, } mock_client.get_last_estimate_statistics_operation.return_value = response_data result = _get_last_estimate_statistics_command(args, mock_client) assert isinstance(result, PollResult) assert result.continue_to_poll is False or result.continue_to_poll is None # completed assert isinstance(result.response, CommandResults) assert result.partial_result is None assert result.response.outputs_prefix == "MsGraph.eDiscovery.EstimateStatistics" assert result.response.raw_response == response_data assert "eDiscovery Estimate Statistics" in result.response.readable_output def test_create_ediscovery_case_hold_policy_command(mocker): """ Given: Case ID, display name, description, and content query. When: Calling create_ediscovery_case_hold_policy_command. Then: Ensure the command returns the expected CommandResults with the created hold policy. """ args = { "case_id": "case_123", "display_name": "Hold Policy 1", "description": "Test Hold Policy", "content_query": "size>100", } mock_response = { "id": "hold_123", "displayName": "Hold Policy 1", "status": "enabled", "description": "Test Hold Policy", "contentQuery": "size>100", } mocker.patch.object(client_mocker, "create_ediscovery_case_hold_policy", return_value=mock_response) result = create_ediscovery_case_hold_policy_command(client_mocker, args) assert result.outputs_prefix == "MsGraph.eDiscoveryCase.HoldPolicy" assert result.outputs_key_field == "ID" assert result.outputs["ID"] == "hold_123" assert result.outputs["DisplayName"] == "Hold Policy 1" assert "Hold Policy 1" in result.readable_output def test_delete_ediscovery_case_hold_policy_command(mocker): """ Given: Case ID and hold policy ID. When: Calling delete_ediscovery_case_hold_policy_command. Then: Ensure the command returns a success message. """ args = {"case_id": "case_123", "hold_policy_id": "hold_123"} mocker.patch.object(client_mocker, "delete_ediscovery_case_hold_policy", return_value=None) result = delete_ediscovery_case_hold_policy_command(client_mocker, args) assert "was sent successfully" in result.readable_output assert "hold_123" in result.readable_output def test_update_ediscovery_case_policy_command(mocker): """ Given: Case ID, hold policy ID, and fields to update. When: Calling update_ediscovery_case_policy_command. Then: Ensure the command returns a success message. """ args = {"case_id": "case_123", "hold_policy_id": "hold_123", "description": "Updated Description"} mocker.patch.object(client_mocker, "update_ediscovery_case_policy", return_value=None) result = update_ediscovery_case_policy_command(client_mocker, args) assert "updated successfully" in result.readable_output assert "hold_123" in result.readable_output def test_list_ediscovery_case_hold_policy_command_list(mocker): """ Given: Case ID. When: Calling list_ediscovery_case_hold_policy_command (listing all). Then: Ensure the command returns the list of hold policies. """ args = {"case_id": "case_123", "all_results": "true"} mock_response = { "value": [ {"id": "hold_1", "displayName": "Hold 1", "status": "enabled"}, {"id": "hold_2", "displayName": "Hold 2", "status": "disabled"}, ] } mocker.patch.object(client_mocker, "list_ediscovery_case_hold_policy", return_value=mock_response) result = list_ediscovery_case_hold_policy_command(client_mocker, args) assert result.outputs_prefix == "MsGraph.eDiscoveryCase.HoldPolicy" assert result.outputs_key_field == "ID" assert len(result.outputs) == 2 assert result.outputs[0]["ID"] == "hold_1" assert result.outputs[1]["ID"] == "hold_2" assert "Hold 1" in result.readable_output assert "Hold 2" in result.readable_output def test_list_ediscovery_case_hold_policy_command_get(mocker): """ Given: Case ID and hold policy ID. When: Calling list_ediscovery_case_hold_policy_command (getting one). Then: Ensure the command returns the specific hold policy. """ args = {"case_id": "case_123", "hold_policy_id": "hold_1", "all_results": "true"} mock_response = {"id": "hold_1", "displayName": "Hold 1", "status": "enabled"} mocker.patch.object(client_mocker, "get_ediscovery_case_hold_policy", return_value=mock_response) result = list_ediscovery_case_hold_policy_command(client_mocker, args) assert result.outputs_prefix == "MsGraph.eDiscoveryCase.HoldPolicy" assert result.outputs_key_field == "ID" assert len(result.outputs) == 1 assert result.outputs[0]["ID"] == "hold_1" assert "Hold 1" in result.readable_output def test_list_case_operation_command_list(mocker): """ Given: Case ID. When: Calling list_case_operation_command (listing all). Then: Ensure the command returns the list of operations. """ args = {"case_id": "case_123", "all_results": "true"} mock_response = { "value": [ {"id": "op_1", "action": "AddToReviewSet", "status": "Succeeded"}, {"id": "op_2", "action": "Export", "status": "InProgress"}, ] } mocker.patch.object(client_mocker, "list_case_operation", return_value=mock_response) result = list_case_operation_command(client_mocker, args) assert result.outputs_prefix == "MsGraph.eDiscoveryCase.Operation" assert result.outputs_key_field == "ID" assert len(result.outputs) == 2 assert result.outputs[0]["ID"] == "op_1" assert result.outputs[1]["ID"] == "op_2" assert "AddToReviewSet" in result.readable_output assert "Export" in result.readable_output def test_list_case_operation_command_get(mocker): """ Given: Case ID and operation ID. When: Calling list_case_operation_command (getting one). Then: Ensure the command returns the specific operation. """ args = {"case_id": "case_123", "operation_id": "op_1", "all_results": "true"} mock_response = {"id": "op_1", "action": "AddToReviewSet", "status": "Succeeded"} mocker.patch.object(client_mocker, "get_case_operation", return_value=mock_response) result = list_case_operation_command(client_mocker, args) assert result.outputs_prefix == "MsGraph.eDiscoveryCase.Operation" assert result.outputs_key_field == "ID" assert len(result.outputs) == 1 assert result.outputs[0]["ID"] == "op_1" assert "AddToReviewSet" in result.readable_output def test_list_case_operation_command_with_download(mocker): """ Given: Arguments requesting a specific operation ID with download_file='true'. When: Calling list_case_operation_command. Then: 1. The operation details are fetched. 2. The download helper is called. 3. A list containing [FileResult, CommandResult] is returned. """ args = {"case_id": "case_1", "operation_id": "op_1", "download_file": "true"} op_data = { "id": "op_1", "action": "Export", "status": "Succeeded", "exportFileMetadata": {"downloadUrl": "https://download.me"}, } mocker.patch.object(client_mocker, "get_case_operation", return_value=op_data) mock_file_result = {"Type": 3, "File": "export.zip", "Contents": b"data"} mocker.patch("MicrosoftGraphSecurity._download_operation_export_file", return_value=mock_file_result) results = list_case_operation_command(client_mocker, args) assert isinstance(results, list) assert len(results) == 2 assert results[0] == mock_file_result assert isinstance(results[1], CommandResults) assert results[1].outputs[0]["ID"] == "op_1" def test_export_result_ediscovery_data_command(mocker): """ Given: Case ID, search ID, and export parameters. When: Calling export_result_ediscovery_data_command. Then: Ensure the command returns the export location. """ args = {"case_id": "case_123", "search_id": "search_123", "export_criteria": "searchHits", "export_format": "standard"} mock_response = MagicMock() mock_response.headers = { "Location": "https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/case_123/operations/op_123" } mocker.patch.object(client_mocker, "export_result_ediscovery_data", return_value=mock_response) result = export_result_ediscovery_data_command(client_mocker, args) assert "eDiscovery export request was submitted successfully" in result.readable_output assert "op_123" in result.readable_output assert result.outputs_prefix == "MsGraph.eDiscoveryCase.Export" assert result.outputs["OperationID"] == "op_123" assert result.outputs["CaseID"] == "case_123" assert result.outputs["Location"] == mock_response.headers["Location"] # ========================================== # Helper Function Tests # ========================================== @pytest.mark.parametrize( "operation_data, expected_url", [ # Case 1: exportFileMetadata is a dictionary ( {"exportFileMetadata": {"downloadUrl": "https://example.com/file1.zip"}}, "https://example.com/file1.zip", ), # Case 2: exportFileMetadata is a list of dictionaries ( {"exportFileMetadata": [{"downloadUrl": "https://example.com/file2.zip"}]}, "https://example.com/file2.zip", ), # Case 3: No exportFileMetadata ({"id": "op1"}, None), # Case 4: exportFileMetadata exists but has no downloadUrl ({"exportFileMetadata": {}}, None), ], ) def test_extract_export_download_url(operation_data, expected_url): """ Given: An operation dictionary with varying structures for 'exportFileMetadata'. When: Calling _extract_export_download_url. Then: The correct download URL is extracted or None is returned. """ assert _extract_export_download_url(operation_data) == expected_url @pytest.mark.parametrize( "headers, default, expected_filename", [ # Case 1: Standard double-quoted filename ({"Content-Disposition": 'attachment; filename="export_123.zip"'}, "def.zip", "export_123.zip"), # Case 2: Unquoted filename ({"Content-Disposition": "attachment; filename=plain.csv"}, "def.zip", "plain.csv"), # Case 3: Case insensitive header key ({"content-disposition": 'attachment; filename="lower.zip"'}, "def.zip", "lower.zip"), # Case 4: Header missing ({}, "default.zip", "default.zip"), # Case 5: Header exists but no filename parameter ({"Content-Disposition": "attachment; size=100"}, "fallback.zip", "fallback.zip"), ], ) def test_extract_filename_from_headers(headers, default, expected_filename): """ Given: Response headers and a default filename. When: Calling _extract_filename_from_headers. Then: The filename is correctly parsed from the Content-Disposition header, or the default is returned if missing. """ assert _extract_filename_from_headers(headers, default) == expected_filename # ========================================== # Download Logic Tests # ========================================== def test_download_operation_export_file_success(mocker): """ Given: An operation with a valid download URL. When: Calling _download_operation_export_file. Then: The client downloads the file, and a fileResult dict is returned with the correct content and name. """ operation = {"exportFileMetadata": {"downloadUrl": "https://fake-url.com/data"}} mock_response = MagicMock() mock_response.ok = True mock_response.content = b"file_content_bytes" mock_response.headers = {"Content-Disposition": 'attachment; filename="results.csv"'} mocker.patch.object(client_mocker, "download_export_file", return_value=mock_response) result = _download_operation_export_file(client_mocker, operation) assert result["File"] == "results.csv" @pytest.mark.parametrize( "mock_attrs, expected_error_msg", [ # Case 1: HTTP Error (ok=False) ( {"ok": False, "status_code": 404, "text": "Not Found", "content": b""}, "Failed to download export file. HTTP 404. Not Found", ), # Case 2: Empty content (ok=True but content is empty) ( {"ok": True, "status_code": 200, "content": b"", "headers": {}}, "Downloaded export file is empty. HTTP 200.", ), ], ) def test_download_operation_export_file_errors(mocker, mock_attrs, expected_error_msg): """ Given: A client response that indicates failure (404 error or empty body). When: Calling _download_operation_export_file. Then: A DemistoException is raised with the specific error message. """ operation = {"exportFileMetadata": {"downloadUrl": "https://fake-url.com/data"}} mock_response = MagicMock() for key, value in mock_attrs.items(): setattr(mock_response, key, value) mocker.patch.object(client_mocker, "download_export_file", return_value=mock_response) with pytest.raises(DemistoException) as e: _download_operation_export_file(client_mocker, operation) assert expected_error_msg in str(e.value) def test_download_export_file_resets_token_to_default_scope(mocker): """ Given: A client downloading an eDiscovery export file (which uses a non-default Purview scope). When: Calling download_export_file. Then: The download uses the Purview scope, and afterwards a default-scope token is fetched to reset the shared refresh token and avoid token-scope drift (XSUP-71559). """ mock_response = MagicMock() http_request = mocker.patch.object(client_mocker.ms_client, "http_request", return_value=mock_response) get_access_token = mocker.patch.object(client_mocker.ms_client, "get_access_token") result = client_mocker.download_export_file("https://fake-url.com/data") assert result is mock_response assert http_request.call_args.kwargs["scope"] == "b26e684c-5068-4120-a679-64a5d2c909d9/.default" get_access_token.assert_called_once_with(scope=client_mocker.ms_client.scope) def test_download_export_file_reset_uses_default_not_purview_scope(mocker): """ Given: A client downloading an eDiscovery export file. When: Calling download_export_file. Then: The post-download token reset requests the client's default scope, not the Purview scope. """ mocker.patch.object(client_mocker.ms_client, "http_request", return_value=MagicMock()) get_access_token = mocker.patch.object(client_mocker.ms_client, "get_access_token") client_mocker.download_export_file("https://fake-url.com/data") reset_scope = get_access_token.call_args.kwargs["scope"] assert reset_scope == client_mocker.ms_client.scope assert reset_scope != "b26e684c-5068-4120-a679-64a5d2c909d9/.default"