Manage lists in Cortex XSOAR that can be accessed by automations and playbooks using list commands, lists arrays, separators, and delimiters.
A list is a data container where you can globally store data within Cortex XSOAR. Despite the name lists, the data can be in any text format, and can even store files. You can use lists to manage important users in your organization, sensitive endpoints, SOC shifts, and more. These lists can be used dynamically within different investigations to provide global context to each relevant incident type.
The data within lists can be accessed in automations, playbooks, or any other place where the context button appears (double-curly brackets). In a playbook, you can access the data in a list via the context button under Lists, or by using the path ${lists.<list_name>}
. You can use a list in a playbook to modify, filter, or transform parts of a list and then update the list with the changes or use the changed data in subsequent playbook tasks. You can also use a playbook task to iterate over list items.
Note
The maximum list size is 209715 characters.
Create a list
When creating a list, you can select the content type (Text, Markdown, HTML, JSON or CSS) and whether you want to limit permissions for read and write or read only.
Note
You can change the content type without editing the list. You cannot edit truncated lists that are too large to display, but you can download a truncated list.
If a valid JSON is stored within a list, it will automatically be parsed as a JSON object when you access it from within a playbook. Depending on how you store the data, you may need to transform a list into an array.
When you access a list using the built-in list or base pack commands, the data is considered to be comma-separated unless you specifically define a custom separator for the list. When using built-in commands, you do not need to split the list. However, if you want to use non-built-in commands, such as in an automation or to loop over list items, you need to split the list using a transformer.
Upload/download a list.
In a remote repository, lists can be pushed to a production environment. When the list is pushed to production, you cannot edit the list in the production environment. If a list has been pushed to production that already exists with the same name, you can resolve the conflict. You can still create lists in production.
(Multi-tenant) You can propagate lists from the Main Account to tenants.
Lists can be included in a content pack and be installed from the Marketplace.
Use Cases
These are some common use cases for creating and using lists in Cortex XSOAR.
A list of allowed executable files against which to check potentially malicious executable files.
An HTML template that you can define to use as part of a Communication task.
Store data object, for example JSON, that you can call as inputs for scripts and playbooks.
Use the getList or addToList commands in a script to take action based on the list data, for example,
res = demisto.executeCommand("getList", {"listName": demisto.args()["listName"]})
will return all list entries in the script.
List Commands
You can use the following list commands in scripts and playbook tasks.
Command | Description | Arguments |
---|---|---|
| Retrieves the contents of the specified list. |
|
| Creates a list with the supplied data. |
|
| Appends the supplied items to the specified list. If you add multiple items, make sure you use the same list separator that the list currently uses, for example a comma or a semicolon. |
|
| Adds the supplied data to the specified list and overwrites existing list data. |
|
| Removes a single item from the specified list. |
|
Example
For example, the ManageOOOUsers script uses the getList
, createList
, and setList
commands.
register_module_line('ManageOOOusers', 'start', __line__()) def _get_current_user(): current_username = demisto.executeCommand("getUsers", {"current": True}) if isError(current_username): demisto.debug(f"failed to get current username - {get_error(current_username)}") return else: return current_username[0]["Contents"][0]['username'] def main(): # get current time now = datetime.now() # args list_name = demisto.getArg("listname") username = demisto.getArg("username") option = demisto.getArg("option") days_off = now + timedelta(days=int(demisto.getArg("daysoff"))) off_until = days_off.strftime("%Y-%m-%d") # update list name to start with 'OOO', so we can't overwrite other lists with this if not list_name.startswith("OOO"): list_name = f"OOO {list_name}" current_user = _get_current_user() if not current_user and not username: return_error('Failed to get current user. Please set the username argument in the script.') if not username: # Current user was found, running script on it. username = current_user else: # check if provided username is a valid xsoar user users = demisto.executeCommand("getUsers", {}) if isError(users): return_error(f'Failed to get users: {str(get_error(users))}') users = users[0]['Contents'] users = [x['username'] for x in users] if username not in users: return_error(message=f"{username} is not a valid user") # get the out of office list, check if the list exists, if not create it: ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"] if isError(ooo_list): return_error(f'Failed to get users out of office: {str(get_error(ooo_list))}') if "Item not found" in ooo_list: demisto.results(demisto.executeCommand("createList", {"listName": list_name, "listData": []})) ooo_list = demisto.executeCommand("getList", {"listName": list_name})[0]["Contents"] # check status of the list, and add/remove the user from it. if not ooo_list: list_data = [] else: list_data = json.loads(ooo_list) if option == "add": # check if user is already in the list, and remove, to allow updating list_data = [i for i in list_data if not (i['user'] == username)] list_data.append({"user": username, "offuntil": off_until, "addedby": current_user if current_user else 'DBot'}) else: # remove the user from the list. list_data = [i for i in list_data if not (i['user'] == username)] set_list_res = demisto.executeCommand("setList", {"listName": list_name, "listData": json.dumps(list_data)}) if isError(set_list_res): return_error(f'Failed to update the list {list_name}: {str(get_error(set_list_res))}') # welcome back, or see ya later! if option == "add": demisto.results(f"Vacation mode engaged until {off_until}, enjoy the time off {username}") else: demisto.results(f"Welcome back {username}, it's like you never left!") if __name__ in ('__builtin__', 'builtins', '__main__'): main() register_module_line('ManageOOOusers', 'end', __line__())