SearchIncidentsSummary
Searches Cortex XSOAR Incidents and returnrs the most relevant fields. Default search range is the last 30 days, if you want to change this, use the fromDate argument. Returns the id, name, type, severity, status, owner, and created/closed times to context. You can add additional fields using the add_field_to_context argument. This automation runs using the default Limited User role, unless you explicitly change the permissions. Based on the SearchIncidentsV2 from the Common Scripts pack, but more efficient.
python · Common Scripts
Source
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 special = ["n", "t", "\\", '"', "'", "7", "r"] def check_if_found_incident(res: list): if res and isinstance(res, list) and isinstance(res[0].get("Contents"), dict): if "data" not in res[0]["Contents"]: raise DemistoException(res[0].get("Contents")) elif res[0]["Contents"]["data"] is None: return False return True else: raise DemistoException(f"failed to get incidents from xsoar.\nGot: {res}") def is_valid_args(args: dict): array_args: list[str] = ["id", "name", "status", "notstatus", "reason", "level", "owner", "type", "query"] error_msg: list[str] = [] for _key, value in args.items(): if _key in array_args: try: if _key == "id": if not isinstance(value, int | str | list): error_msg.append( f"Error while parsing the incident id with the value: {value}. The given type: " f"{type(value)} is not a valid type for an ID. The supported id types are: int, list and str" ) elif isinstance(value, str): _ = bytes(value, "utf-8").decode("unicode_escape") else: _ = bytes(value, "utf-8").decode("unicode_escape") except UnicodeDecodeError as ex: error_msg.append(f'Error while parsing the argument: "{_key}" \nError:\n- "{ex!s}"') if len(error_msg) != 0: raise DemistoException("\n".join(error_msg)) return True def apply_filters(incidents: list, args: dict): names_to_filter = set(argToList(args.get("name"))) types_to_filter = set(argToList(args.get("type"))) filtered_incidents = [] fields = ["id", "name", "type", "severity", "status", "owner", "created", "closed"] if args.get("add_fields_to_context"): fields = fields + args.get("add_fields_to_context", "").split(",") fields = [x.strip() for x in fields] # clear out whitespace for incident in incidents: if names_to_filter and incident["name"] not in names_to_filter: continue if types_to_filter and incident["type"] not in types_to_filter: continue style_incident = {} for field in fields: style_incident[field] = incident.get(field, incident["CustomFields"].get(field, "n/a")) filtered_incidents.append(style_incident) return filtered_incidents def add_incidents_link(data: list): server_url = demisto.demistoUrls().get("server") for incident in data: incident_link = urljoin(server_url, f'#/Details/{incident.get("id")}') incident["incidentLink"] = incident_link return data def search_incidents(args: dict): # pragma: no cover if not is_valid_args(args): return None if fromdate := arg_to_datetime(args.get("fromdate")): from_date = fromdate.isoformat() args["fromdate"] = from_date if todate := arg_to_datetime(args.get("todate")): to_date = todate.isoformat() args["todate"] = to_date if args.get("trimevents") == "0": args.pop("trimevents") # handle list of ids if args.get("id"): args["id"] = ",".join(argToList(args.get("id"), transform=str)) res: list = execute_command("getIncidents", args, extract_contents=False) incident_found: bool = check_if_found_incident(res) if incident_found is False: return "Incidents not found.", {}, {} data = apply_filters(res[0]["Contents"]["data"], args) data = add_incidents_link(data) headers: list[str] = ["id", "name", "severity", "status", "owner", "created", "closed", "incidentLink"] if args.get("add_fields_to_context"): add_headers: list[str] = args.get("add_fields_to_context", "").split(",") headers = headers + add_headers md: str = tableToMarkdown(name="Incidents found", t=data, headers=headers) return md, data, res def main(): # pragma: no cover args: dict = demisto.args() try: readable_output, outputs, raw_response = search_incidents(args) if search_results_label := args.get("searchresultslabel"): for output in outputs: output["searchResultsLabel"] = search_results_label results = CommandResults( outputs_prefix="foundIncidents", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ignore_auto_extract=True, ) return_results(results) except DemistoException as error: return_error(str(error), error) if __name__ in ("__main__", "__builtin__", "builtins"): # pragma: no cover main()
README
Searches Cortex XSOAR Incidents. Default search range is the last 30 days, if you want to change this, use the fromDate argument.
Returns the id, name, type, severity, status, owner, and created/closed times to context. You can add additional fields using the add_field_to_context argument.
This automation runs using the default Limited User role, unless you explicitly change the permissions. Based on the SearchIncidentsV2 from the Common Scripts pack, but more efficient.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | Utility |
Inputs
| Argument Name | Description |
|---|---|
| id | A comma-separated list of incident IDs by which to filter the results. |
| name | A comma-separated list of incident names by which to filter the results. |
| status | A comma-separated list of incident statuses by which to filter the results. For example: assigned. |
| notstatus | A comma-separated list of incident statuses to exclude from the results. For example: assigned. |
| reason | A comma-separated list of incident close reasons by which to filter the results. |
| fromdate | Filter by from date (e.g. “3 days ago” or 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z), default is “30 days ago” |
| todate | Filter by to date (e.g. “3 days ago” or 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z) |
| fromclosedate | Filter by from close date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z) |
| toclosedate | Filter by to close date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z) |
| fromduedate | Filter by from due date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z) |
| toduedate | Filter by to due date (e.g. 2006-01-02T15:04:05+07:00 or 2006-01-02T15:04:05Z) |
| level | Filter by Severity |
| owner | Filter by incident owners |
| details | Filter by incident details |
| type | Filter by incident type |
| query | Use free form query (use Lucene syntax) as filter. All other filters will be ignored when this filter is used. |
| page | Filter by the page number |
| trimevents | The number of events to return from the alert JSON. The default is 0, which returns all events. Note that the count is from the head of the list, regardless of event time or other properties. |
| size | Number of incidents per page (per fetch) |
| sort | Sort in format of field.asc,field.desc,… |
| searchresultslabel | If provided, the value of this argument will be set under the searchResultsLabel context key for each incident found. |
| add_fields_to_context | A comma seperated list of fields to return to the context, (default: id,name,type,severity,status,owner,created,closed) |
Outputs
| Path | Description | Type |
|---|---|---|
| foundIncidents.id | A list of incident IDs returned from the query. | Unknown |
| foundIncidents.name | A list of incident names returned from the query. | Unknown |
| foundIncidents.severity | A list of incident severities returned from the query. | Unknown |
| foundIncidents.status | A list of incident statuses returned from the query. | Unknown |
| foundIncidents.owner | A list of incident owners returned from the query. | Unknown |
| foundIncidents.created | A list of the incident create date returned from the query. | Unknown |
| foundIncidents.closed | A list of incident close dates returned from the query. | Unknown |
| foundIncidents.incidentLink | A list with links to the incidents returned from the query. | Unknown |
| foundIncidents.searchResultsLabel | The value provided in the searchresultslabel argument. | String |