Sophos Central

The unified console for managing Sophos products.

Data Enrichment & Threat Intelligence · Sophos Central

Details

IDSophos Central
ProviderThoma Bravo
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

The unified console for managing Sophos products.

Configure Sophos Central in Cortex

Parameter Description Required
credentials Sophos client ID and secret True
Tenant ID Tenant ID on which the commands would be executed by default. Required in case of partner/organization level credentials False
isFetch Fetch incidents False
fetch_severity Fetch Severity False
fetch_category Fetch Category False
max_fetch Fetch Limit False
fetch_time First Fetch Time False
proxy Use system proxy settings False

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.

sophos-central-alert-list


List alerts.

Base Command

sophos-central-alert-list

Input

Argument Name Description Required
limit The maximum number of items to return. Default is “50”. Maximum is “100”. Optional

Context Output

Path Type Description
SophosCentral.Alert.allowedActions String Actions that you can perform on these alerts.
SophosCentral.Alert.category String Alert category.
SophosCentral.Alert.description String Alert description.
SophosCentral.Alert.groupKey String Alert group key.
SophosCentral.Alert.id String The alert ID.
SophosCentral.Alert.managedAgentId String The alert source ID.
SophosCentral.Alert.managedAgentName String The alert source name.
SophosCentral.Alert.managedAgentType String The source that triggered the Alert.
SophosCentral.Alert.person String The ID of the referenced person object.
SophosCentral.Alert.personName String The name of the referenced person object.
SophosCentral.Alert.product String Product type.
SophosCentral.Alert.raisedAt Date When the alert was triggered.
SophosCentral.Alert.severity String Severity level for the alert.
SophosCentral.Alert.tenantId String Tenant ID for the alert.
SophosCentral.Alert.tenantName String Tenant name.
SophosCentral.Alert.type String Alert type.

Command Example

!sophos-central-alert-list limit=50

Context Example

{
    "SophosCentral": {
        "Alert": [
            {
                "allowedActions": [
                    "clearThreat"
                ],
                "category": "malware",
                "description": "Manual cleanup required: 'EICAR-AV-Test' at 'C:\\Users\\JonDoe\\Downloads\\eicarcom2.zip'",
                "groupKey": "MSxFdmVudDo6RW5kcG9pbnQ6OlRocmVhdDo6Q2xlYW51cEZhaWxlZCwxNixFSUNBUi1BVi1UZXN0",
                "id": "8e879165-81cb-4747-8608-1cc4e630a017",
                "managedAgentId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
                "managedAgentType": "computer",
                "person": "5d407889-8659-46ab-86c5-4f227302df78",
                "product": "endpoint",
                "raisedAt": "2020-11-25T09:19:18.936Z",
                "severity": "high",
                "tenantId": "11f104c5-cc4a-4a9f-bb9c-632c936dfb9f",
                "tenantName": "Cortex XSOAR",
                "type": "Event::Endpoint::Threat::CleanupFailed"
            },
            {
                "allowedActions": [
                    "clearThreat"
                ],
                "category": "runtimeDetections",
                "description": "Malicious connection detected: 'C2/Generic-B' at 'C:\\Windows\\System32\\wscript.exe' (Technical Support reference: 277413403)",
                "groupKey": "MSxFdmVudDo6RW5kcG9pbnQ6OlRocmVhdDo6Q29tbWFuZEFuZENvbnRyb2xEZXRlY3RlZCwxNixDMiUyRkdlbmVyaWMtQg",
                "id": "9641ba6e-3254-4726-962d-b2bc11e04131",
                "managedAgentId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
                "managedAgentType": "computer",
                "person": "5d407889-8659-46ab-86c5-4f227302df78",
                "product": "endpoint",
                "raisedAt": "2020-11-25T10:36:31.603Z",
                "severity": "high",
                "tenantId": "11f104c5-cc4a-4a9f-bb9c-632c936dfb9f",
                "tenantName": "Cortex XSOAR",
                "type": "Event::Endpoint::Threat::CommandAndControlDetected"
            },
            {
                "allowedActions": [
                    "acknowledge"
                ],
                "category": "updating",
                "description": "Thunderbox is out of date.",
                "groupKey": "MSxFdmVudDo6RW5kcG9pbnQ6Ok91dE9mRGF0ZSw1MTMs",
                "id": "ee527ca8-cb54-4e11-b59f-2197910176f3",
                "managedAgentId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
                "managedAgentType": "computer",
                "person": "5d407889-8659-46ab-86c5-4f227302df78",
                "product": "endpoint",
                "raisedAt": "2020-11-25T10:42:09.083Z",
                "severity": "medium",
                "tenantId": "11f104c5-cc4a-4a9f-bb9c-632c936dfb9f",
                "tenantName": "Cortex XSOAR",
                "type": "Event::Endpoint::OutOfDate"
            }
        ]
    }
}

Human Readable Output

Listed Alerts

|id|description|severity|raisedAt|allowedActions|managedAgentId|category|type|
|—|—|—|—|—|—|—|—|
| 8e879165-81cb-4747-8608-1cc4e630a017 | Manual cleanup required: ‘EICAR-AV-Test’ at ‘C:\Users\JonDoe\Downloads\eicarcom2.zip’ | high | 2020-11-25T09:19:18.936Z | clearThreat | 6e9567ea-bb50-40c5-9f12-42eb308e4c9b | malware | Event::Endpoint::Threat::CleanupFailed |
| 9641ba6e-3254-4726-962d-b2bc11e04131 | Malicious connection detected: ‘C2/Generic-B’ at ‘C:\Windows\System32\wscript.exe’ (Technical Support reference: 277413403) | high | 2020-11-25T10:36:31.603Z | clearThreat | 6e9567ea-bb50-40c5-9f12-42eb308e4c9b | runtimeDetections | Event::Endpoint::Threat::CommandAndControlDetected |
| ee527ca8-cb54-4e11-b59f-2197910176f3 | Thunderbox is out of date. | medium | 2020-11-25T10:42:09.083Z | acknowledge | 6e9567ea-bb50-40c5-9f12-42eb308e4c9b | updating | Event::Endpoint::OutOfDate |
Results on this page: 3.Maximum number of results allowed in a page: 100

sophos-central-alert-get


Get a single alert by ID.

Base Command

sophos-central-alert-get

Input

Argument Name Description Required
alert_id The alert ID. Required

Context Output

Path Type Description
SophosCentral.Alert.allowedActions String Actions that you can perform on these alerts.
SophosCentral.Alert.category String Alert category.
SophosCentral.Alert.description String Alert description.
SophosCentral.Alert.groupKey String Alert group key.
SophosCentral.Alert.id String The alert ID.
SophosCentral.Alert.managedAgentId String The alert source ID.
SophosCentral.Alert.managedAgentName String The alert source name.
SophosCentral.Alert.managedAgentType String The source that triggered the alert.
SophosCentral.Alert.person String The ID of the referenced person object.
SophosCentral.Alert.personName String The name of the referenced person object.
SophosCentral.Alert.product String Product type.
SophosCentral.Alert.raisedAt Date When the alert was triggered.
SophosCentral.Alert.severity String Severity level for the alert.
SophosCentral.Alert.tenantId String Tenant ID for the alert.
SophosCentral.Alert.tenantName String Tenant name.
SophosCentral.Alert.type String Alert type.

Command Example

!sophos-central-alert-get alert_id=8e879165-81cb-4747-8608-1cc4e630a017

Context Example

{
    "SophosCentral": {
        "Alert": {
            "allowedActions": [
                "clearThreat"
            ],
            "category": "malware",
            "description": "Manual cleanup required: 'EICAR-AV-Test' at 'C:\\Users\\JonDoe\\Downloads\\eicarcom2.zip'",
            "groupKey": "MSxFdmVudDo6RW5kcG9pbnQ6OlRocmVhdDo6Q2xlYW51cEZhaWxlZCwxNixFSUNBUi1BVi1UZXN0",
            "id": "8e879165-81cb-4747-8608-1cc4e630a017",
            "managedAgentId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
            "managedAgentType": "computer",
            "person": "5d407889-8659-46ab-86c5-4f227302df78",
            "product": "endpoint",
            "raisedAt": "2020-11-25T09:19:18.936Z",
            "severity": "high",
            "tenantId": "11f104c5-cc4a-4a9f-bb9c-632c936dfb9f",
            "tenantName": "Cortex XSOAR",
            "type": "Event::Endpoint::Threat::CleanupFailed"
        }
    }
}

Human Readable Output

Found Alert

id description severity raisedAt allowedActions managedAgentId category type
8e879165-81cb-4747-8608-1cc4e630a017 Manual cleanup required: ‘EICAR-AV-Test’ at ‘C:\Users\JonDoe\Downloads\eicarcom2.zip’ high 2020-11-25T09:19:18.936Z clearThreat 6e9567ea-bb50-40c5-9f12-42eb308e4c9b malware Event::Endpoint::Threat::CleanupFailed

sophos-central-alert-action


Take an action against alerts.

Base Command

sophos-central-alert-action

Input

Argument Name Description Required
alert_id Comma-separated list of alert IDs. Required
action Actions to perform on the alerts. Possible values are: “acknowledge”, “cleanPua”, “cleanVirus”, “authPua”, “clearThreat”, “clearHmpa”, “sendMsgPua”, and “sendMsgThreat”. Required
message Message to send for the action. Optional

Context Output

Path Type Description
SophosCentral.AlertAction.action String Actions that you can perform on the alert.
SophosCentral.AlertAction.alertId String Alert ID.
SophosCentral.AlertAction.completedAt Date Time when the action was completed.
SophosCentral.AlertAction.id String Alert action ID.
SophosCentral.AlertAction.requestedAt Date Time when the action was requested.
SophosCentral.AlertAction.result String The result of the action.
SophosCentral.AlertAction.startedAt Date Time when the action was started.
SophosCentral.AlertAction.status String Status of an alert action.

Command Example

!sophos-central-alert-action action=clearThreat alert_id=8e879165-81cb-4747-8608-1cc4e630a017 message=testmessage

Context Example

{
    "SophosCentral": {
        "AlertAction": {
            "action": "clearThreat",
            "alertId": "8e879165-81cb-4747-8608-1cc4e630a017",
            "completedAt": null,
            "id": "c75b1e4d-c62c-4b3a-8ca5-dea658a18c1b",
            "requestedAt": "2020-11-25T10:47:14.639Z",
            "result": "success",
            "startedAt": null,
            "status": "requested"
        }
    }
}

Human Readable Output

Alerts Acted Against

id action alertId result requestedAt status
c75b1e4d-c62c-4b3a-8ca5-dea658a18c1b clearThreat 8e879165-81cb-4747-8608-1cc4e630a017 success 2020-11-25T10:47:14.639Z requested

sophos-central-alert-search


Get alerts matching request.

Base Command

sophos-central-alert-search

Input

Argument Name Description Required
group_key Alert group key. Optional
start Time on which or after the alerts were raised. Use ISO time format (YYYY-MM-DDTHH:MM:SSZ). Optional
end Time before which alerts were raised. Use ISO time format (YYYY-MM-DDTHH:MM:SSZ). Optional
date_range The date range in which to search from the current time instead of a start/end time in the format (<number> <time unit>, e.g., 12 hours, 7 days). date_range will overwrite the start and end arguments if defined. Optional
product Alerts for a product(s). Possible values are: “other”, “endpoint”, “server”, “mobile”, “encryption”, “emailGateway”, “webGateway”, “phishThreat”, “wireless”, “iaas”, and “firewall”. Optional
category Alert category(s). Optional
severity Alerts for a specific severity level(s). Possible values are: “high”, “medium”, and “low”. Optional
ids List of IDs. Optional
limit The maximum number of items to return. Default is “50”. Maximum is “100”. Optional

Context Output

Path Type Description
SophosCentral.Alert.allowedActions String Actions that you can perform on these alerts.
SophosCentral.Alert.category String Alert category.
SophosCentral.Alert.description String Alert description.
SophosCentral.Alert.groupKey String Alert group key.
SophosCentral.Alert.id String The alert ID.
SophosCentral.Alert.managedAgentId String The alert source ID.
SophosCentral.Alert.managedAgentName String The alert source name.
SophosCentral.Alert.managedAgentType String The source that triggered the alert.
SophosCentral.Alert.person String The ID of the referenced person object.
SophosCentral.Alert.personName String The name of the referenced person object.
SophosCentral.Alert.product String Product type.
SophosCentral.Alert.raisedAt Date When the alert was triggered.
SophosCentral.Alert.severity String Severity level for the alert.
SophosCentral.Alert.tenantId String Tenant ID for the alert.
SophosCentral.Alert.tenantName String Tenant name.
SophosCentral.Alert.type String Alert type.

Command Example

!sophos-central-alert-search category=general product=endpoint

Context Example

{
    "SophosCentral": {
        "Alert": null
    }
}

Human Readable Output

Found Alerts

No entries.
Results on this page: 0.Maximum number of results allowed in a page: 100

sophos-central-endpoint-list


List all endpoints for a tenant.

Base Command

sophos-central-endpoint-list

Input

Argument Name Description Required
health_status Match endpoints that have any of the specified health statuses. Possible values are: “bad”, “good”, “suspicious”, and “unknown”. Optional
endpoint_type Match endpoints that have any of the specified endpoint types. Possible values are: “computer”, “server”, and “securityVm”. Optional
tamper_protection_enabled Whether tamper protection is enabled. Possible values are: “true” and “false”. Optional
lockdown_status Match endpoints that have any of the specified lockdown statuses. Possible values are: “creatingWhitelist”, “installing”, “locked”, “notInstalled”, “registering”, “starting”, “stopping”, “unavailable”, “uninstalled”, and “unlocked”. Optional
last_seen_before The datetime before which the endpoints were last seen (UTC). Optional
last_seen_after The datetime on or after which the endpoints were last seen (UTC). Optional
ids List of IDs. Optional
view Type of view to be returned in the response. Possible values are: “basic”, “summary”, and “full”. Optional
limit The maximum number of items to return. Default is “50”. Maximum is “100”. Optional

Context Output

Path Type Description
SophosCentral.Endpoint.assignedProductCodes String Code of a product assigned to the endpoint.
SophosCentral.Endpoint.associatedPersonId String The unique ID for the person associated with the endpoint.
SophosCentral.Endpoint.associatedPersonName String Name of the person associated with the endpoint.
SophosCentral.Endpoint.associatedPersonViaLogin String The login of the person associated with the endpoint.
SophosCentral.Endpoint.groupId String The unique ID for the endpoint group.
SophosCentral.Endpoint.groupName String Endpoint group name.
SophosCentral.Endpoint.hostname String The hostname of the endpoint.
SophosCentral.Endpoint.id String The unique ID for the endpoint.
SophosCentral.Endpoint.health String Health status of the endpoint.
SophosCentral.Endpoint.ipv4Addresses String IPv4 address of the endpoint.
SophosCentral.Endpoint.ipv6Addresses String IPv6 address of the endpoint.
SophosCentral.Endpoint.macAddresses String MAC address of the endpoint.
SophosCentral.Endpoint.osBuild String Operating system build.
SophosCentral.Endpoint.osIsServer Boolean Whether the operating system is a server operating system.
SophosCentral.Endpoint.osName String Operating system name as reported by the endpoint.
SophosCentral.Endpoint.osPlatform String Operating system platform type.
SophosCentral.Endpoint.tamperProtectionEnabled Boolean Whether tamper protection is enabled.
SophosCentral.Endpoint.type String The endpoint type.
SophosCentral.Endpoint.online Boolean Whether the endpoint is online.

Command Example


#### Context Example

```json
{
    "SophosCentral": {
        "Endpoint": [
            {
                "assignedProductCodes": [
                    "endpointProtection",
                    "coreAgent"
                ],
                "associatedPersonId": null,
                "associatedPersonName": null,
                "associatedPersonViaLogin": "THUNDERBOX\\JonDoe",
                "health": "bad",
                "hostname": "Thunderbox",
                "id": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
                "ipv4Addresses": [
                    "1.1.1.1"
                ],
                "ipv6Addresses": [
                    "fe80::9905:5b42:6605:5e93"
                ],
                "macAddresses": [
                    "00:00:00:B0:00:BA"
                ],
                "online": null,
                "osBuild": 18363,
                "osIsServer": false,
                "osName": "Windows 10 Pro",
                "osPlatform": "windows",
                "tamperProtectionEnabled": false,
                "type": "computer"
            },
            {
                "assignedProductCodes": [
                    "coreAgent",
                    "endpointProtection"
                ],
                "associatedPersonId": null,
                "associatedPersonName": null,
                "associatedPersonViaLogin": "WIN-CEAESQ7V08E\\Administrator",
                "health": "good",
                "hostname": "WIN-CEAESQ7V08E",
                "id": "a24b74a2-68e3-4fa5-8119-95744e0ab421",
                "ipv4Addresses": [
                    "1.1.1.1"
                ],
                "ipv6Addresses": [
                    "fe80::9905:5b42:6605:5e93"
                ],
                "macAddresses": [
                    "00:00:00:B0:00:BA"
                ],
                "online": null,
                "osBuild": 17763,
                "osIsServer": true,
                "osName": "Windows Server 2019 Standard Evaluation",
                "osPlatform": "windows",
                "tamperProtectionEnabled": false,
                "type": "server"
            }
        ]
    }
}

Human Readable Output

Listed Endpoints

|id|hostname|ipv4Addresses|ipv6Addresses|macAddresses|type|tamperProtectionEnabled|
|—|—|—|—|—|—|—|
| 6e9567ea-bb50-40c5-9f12-42eb308e4c9b | Thunderbox | 1.1.1.1 | fe80::9905:5b42:6605:5e93 | 00:00:00:B0:00:BA | computer | false |
| a24b74a2-68e3-4fa5-8119-95744e0ab421 | WIN-CEAESQ7V08E | 1.1.1.1 | fe80::9905:5b42:6605:5e93 | 00:00:00:B0:00:BA | server | false |
Results on this page: 2.Maximum number of results allowed in a page: 500

sophos-central-endpoint-scan


Scan endpoints of a tenant.

Base Command

sophos-central-endpoint-scan

Input

Argument Name Description Required
endpoint_id The endpoint ID(s). Required

Context Output

Path Type Description
SophosCentral.EndpointScan.id String Identifies a request to perform or configure the endpoint scan.
SophosCentral.EndpointScan.requestedAt Date Time when the scan was requested.
SophosCentral.EndpointScan.status String The status of an endpoint scan.

Command Example

!sophos-central-endpoint-scan endpoint_id=6e9567ea-bb50-40c5-9f12-42eb308e4c9b

Context Example

{
    "SophosCentral": {
        "EndpointScan": {
            "id": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
            "requestedAt": "2020-11-25T10:47:20.343Z",
            "status": "requested"
        }
    }
}

Human Readable Output

Scanning Endpoints

id status requestedAt
6e9567ea-bb50-40c5-9f12-42eb308e4c9b requested 2020-11-25T10:47:20.343Z

sophos-central-endpoint-tamper-get


Get tamper protection information for one or more endpoints. Potentially harmful because of the password.

Base Command

sophos-central-endpoint-tamper-get

Input

Argument Name Description Required
endpoint_id The endpoint ID(s). Required
get_password Whether to return the tamper protection password. Possible values are: “true” and “false”. Optional

Context Output

Path Type Description
SophosCentral.EndpointTamper.endpointId String ID of the endpoint in regards to the tamper settings.
SophosCentral.EndpointTamper.enabled String Whether tamper protection should be turned on for the endpoint.
SophosCentral.EndpointTamper.password String Current tamper protection password.

Command Example

!sophos-central-endpoint-tamper-get endpoint_id=6e9567ea-bb50-40c5-9f12-42eb308e4c9b

Context Example

{
    "SophosCentral": {
        "EndpointTamper": {
            "enabled": false,
            "endpointId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
            "password": null
        }
    }
}

Human Readable Output

Listed Endpoints Tamper Protection

endpointId enabled
6e9567ea-bb50-40c5-9f12-42eb308e4c9b false

sophos-central-endpoint-tamper-update


Update tamper protection information for one or more endpoints. Potentially Harmful because of the password.

Base Command

sophos-central-endpoint-tamper-update

Input

Argument Name Description Required
endpoint_id The endpoint ID(s). Required
enabled Whether tamper protection should be turned on for the endpoint. Possible values are: “true” and “false”. Required
get_password Whether to return the tamper protection password. Possible values are: “true” and “false”. Optional

Context Output

Path Type Description
SophosCentral.EndpointTamper.endpointId String ID of the endpoint in regards to the tamper settings.
SophosCentral.EndpointTamper.enabled String Whether tamper protection should be turned on for the endpoint.
SophosCentral.EndpointTamper.password String Current tamper protection password.

Command Example

!sophos-central-endpoint-tamper-update enabled=true endpoint_id=6e9567ea-bb50-40c5-9f12-42eb308e4c9b

Context Example

{
    "SophosCentral": {
        "EndpointTamper": {
            "enabled": true,
            "endpointId": "6e9567ea-bb50-40c5-9f12-42eb308e4c9b",
            "password": null
        }
    }
}

Human Readable Output

Updated Endpoints Tamper Protection

endpointId enabled
6e9567ea-bb50-40c5-9f12-42eb308e4c9b true

sophos-central-allowed-item-list


List all allowed items.

Base Command

sophos-central-allowed-item-list

Input

Argument Name Description Required
page_size he maximum size of the page requested. Default is “50”. Maximum is “100”. Optional
page Page number to return. Default is “1”. Optional

Context Output

Path Type Description
SophosCentral.AllowedItem.comment String A comment indicating why the item was allowed.
SophosCentral.AllowedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.AllowedItem.createdById String The unique ID for the user who created the item.
SophosCentral.AllowedItem.createdByName String The name for the user who created the item.
SophosCentral.AllowedItem.id String The unique ID for the allowed application.
SophosCentral.AllowedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.AllowedItem.fileName String The file name.
SophosCentral.AllowedItem.path String The path for the application.
SophosCentral.AllowedItem.sha256 String The SHA256 value for the application.
SophosCentral.AllowedItem.type String The property by which an item is allowed.
SophosCentral.AllowedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.AllowedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.AllowedItem.originPersonId String ID of the originating person.
SophosCentral.AllowedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-allowed-item-list page=1 page_size=50

Context Example

{
    "SophosCentral": {
        "AllowedItem": [
            {
                "certificateSigner": null,
                "comment": "hello world1",
                "createdAt": "2020-11-25T10:19:37.608Z",
                "fileName": null,
                "id": "b2148cc0-6ee8-440e-9c4b-cd5486b36c3c",
                "path": "/root/helloaworld/1/1",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-25T10:19:37.608Z"
            },
            {
                "certificateSigner": "notme",
                "comment": "fordemo",
                "createdAt": "2020-11-10T12:10:49.384Z",
                "fileName": null,
                "id": "718e991d-a99f-4193-b263-4eeebcac46fe",
                "path": null,
                "sha256": null,
                "type": "certificateSigner",
                "updatedAt": "2020-11-10T12:10:49.384Z"
            },
            {
                "certificateSigner": null,
                "comment": "Test-Noam",
                "createdAt": "2020-11-08T14:00:18.574Z",
                "fileName": null,
                "id": "f047c584-949a-4a59-aebd-9999ce323c1d",
                "path": "c:\\test2.exe",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-08T14:00:18.574Z"
            },
            {
                "certificateSigner": null,
                "comment": "Test",
                "createdAt": "2020-11-08T10:44:39.279Z",
                "fileName": null,
                "id": "345b4588-b843-45b1-9319-e529ddd741e6",
                "path": "c:\\1.txt",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-08T10:58:14.622Z"
            },
            {
                "certificateSigner": "hello",
                "comment": "chaaned",
                "createdAt": "2020-11-03T10:14:25.914Z",
                "fileName": null,
                "id": "6a2e26fb-6eb4-42ff-8201-6f7051757595",
                "path": null,
                "sha256": null,
                "type": "certificateSigner",
                "updatedAt": "2020-11-03T10:15:32.819Z"
            },
            {
                "certificateSigner": null,
                "comment": "chaaned",
                "createdAt": "2020-11-03T09:13:04.380Z",
                "fileName": null,
                "id": "2f804138-9632-4500-a13f-33342868e434",
                "path": "root/hello/worldrsaard",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-03T10:15:08.159Z"
            },
            {
                "certificateSigner": null,
                "comment": "hello world1",
                "createdAt": "2020-11-01T13:26:03.890Z",
                "fileName": null,
                "id": "73e555e9-3eee-42e1-879e-65d5ba968236",
                "path": "/root/helloaworld/1",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-01T13:26:03.890Z"
            },
            {
                "certificateSigner": null,
                "comment": "hello world",
                "createdAt": "2020-11-01T11:50:02.567Z",
                "fileName": null,
                "id": "595b2e6d-36b3-45bd-b94f-99a98a0a53f7",
                "path": "/root/helloaworld",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-01T11:50:02.567Z"
            },
            {
                "certificateSigner": null,
                "comment": "helloworld",
                "createdAt": "2020-11-01T11:00:47.441Z",
                "fileName": null,
                "id": "3533f7be-5064-44b6-9579-e4d7fa542444",
                "path": "/root/what",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-11-01T11:00:47.441Z"
            },
            {
                "certificateSigner": null,
                "comment": "bad comment",
                "createdAt": "2020-11-01T10:48:49.312Z",
                "fileName": "zxdfzd",
                "id": "85465c57-e598-4c8b-9c08-093c6f5eb239",
                "path": "/root/hello/word",
                "sha256": "C6F4DB9B3191E6E693CE938BD74FAB37AEE71372C8B034F5040362D8C69E4DE5",
                "type": "path",
                "updatedAt": "2020-11-01T10:48:49.312Z"
            },
            {
                "certificateSigner": "xcvxcv",
                "comment": "bad comment",
                "createdAt": "2020-11-01T10:47:24.473Z",
                "fileName": "xzcvxz",
                "id": "cffaaae7-0b3a-4ec7-84a4-fee88d297abc",
                "path": "/root",
                "sha256": null,
                "type": "certificateSigner",
                "updatedAt": "2020-11-01T10:47:24.473Z"
            },
            {
                "certificateSigner": null,
                "comment": "changedcomment",
                "createdAt": "2020-10-29T13:31:40.963Z",
                "fileName": null,
                "id": "c598b3b5-c9d9-4ff2-af9b-4d656deaa4f7",
                "path": "/root/hello",
                "sha256": null,
                "type": "path",
                "updatedAt": "2020-10-29T13:32:41.421Z"
            },
            {
                "comment": "uh",
                "createdAt": "2020-10-28T13:57:53.235Z",
                "id": "41a56d0d-5272-4be4-92dc-1c2dd42c218a",
                "type": "path",
                "updatedAt": "2020-10-28T13:58:07.906Z"
            }
        ]
    }
}

Human Readable Output

Listed Allowed Items

|id|comment|fileName|sha256|path|certificateSigner|createdAt|type|updatedAt|
|—|—|—|—|—|—|—|—|—|
| b2148cc0-6ee8-440e-9c4b-cd5486b36c3c | hello world1 | | | /root/helloaworld/1/1 | | 2020-11-25T10:19:37.608Z | path | 2020-11-25T10:19:37.608Z |
| 718e991d-a99f-4193-b263-4eeebcac46fe | fordemo | | | | notme | 2020-11-10T12:10:49.384Z | certificateSigner | 2020-11-10T12:10:49.384Z |
| f047c584-949a-4a59-aebd-9999ce323c1d | Test-Noam | | | c:\test2.exe | | 2020-11-08T14:00:18.574Z | path | 2020-11-08T14:00:18.574Z |
| 345b4588-b843-45b1-9319-e529ddd741e6 | Test | | | c:\1.txt | | 2020-11-08T10:44:39.279Z | path | 2020-11-08T10:58:14.622Z |
| 6a2e26fb-6eb4-42ff-8201-6f7051757595 | chaaned | | | | hello | 2020-11-03T10:14:25.914Z | certificateSigner | 2020-11-03T10:15:32.819Z |
| 2f804138-9632-4500-a13f-33342868e434 | chaaned | | | root/hello/worldrsaard | | 2020-11-03T09:13:04.380Z | path | 2020-11-03T10:15:08.159Z |
| 73e555e9-3eee-42e1-879e-65d5ba968236 | hello world1 | | | /root/helloaworld/1 | | 2020-11-01T13:26:03.890Z | path | 2020-11-01T13:26:03.890Z |
| 595b2e6d-36b3-45bd-b94f-99a98a0a53f7 | hello world | | | /root/helloaworld | | 2020-11-01T11:50:02.567Z | path | 2020-11-01T11:50:02.567Z |
| 3533f7be-5064-44b6-9579-e4d7fa542444 | helloworld | | | /root/what | | 2020-11-01T11:00:47.441Z | path | 2020-11-01T11:00:47.441Z |
| 85465c57-e598-4c8b-9c08-093c6f5eb239 | bad comment | zxdfzd | C6F4DB9B3191E6E693CE938BD74FAB37AEE71372C8B034F5040362D8C69E4DE5 | /root/hello/word | | 2020-11-01T10:48:49.312Z | path | 2020-11-01T10:48:49.312Z |
| cffaaae7-0b3a-4ec7-84a4-fee88d297abc | bad comment | xzcvxz | | /root | xcvxcv | 2020-11-01T10:47:24.473Z | certificateSigner | 2020-11-01T10:47:24.473Z |
| c598b3b5-c9d9-4ff2-af9b-4d656deaa4f7 | changedcomment | | | /root/hello | | 2020-10-29T13:31:40.963Z | path | 2020-10-29T13:32:41.421Z |
| 41a56d0d-5272-4be4-92dc-1c2dd42c218a | uh | | | | | 2020-10-28T13:57:53.235Z | path | 2020-10-28T13:58:07.906Z |
Current page: 1.
Results on this page: 13.
Maximum number of results allowed in a page: 100.

sophos-central-allowed-item-get


Get a single allowed item by ID.

Base Command

sophos-central-allowed-item-get

Input

Argument Name Description Required
allowed_item_id The ID of the allowed item. Required

Context Output

Path Type Description
SophosCentral.AllowedItem.comment String A comment indicating why the item was allowed.
SophosCentral.AllowedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.AllowedItem.createdById String The unique ID for the user who created the item.
SophosCentral.AllowedItem.createdByName String The name for the user who created the item.
SophosCentral.AllowedItem.id String The unique ID for the allowed application.
SophosCentral.AllowedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.AllowedItem.fileName String The file name.
SophosCentral.AllowedItem.path String The path for the application.
SophosCentral.AllowedItem.sha256 String The SHA256 value for the application.
SophosCentral.AllowedItem.type String The property by which an item is allowed.
SophosCentral.AllowedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.AllowedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.AllowedItem.originPersonId String ID of the originating person.
SophosCentral.AllowedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-allowed-item-get allowed_item_id=b2148cc0-6ee8-440e-9c4b-cd5486b36c3c

Context Example

{
    "SophosCentral": {
        "AllowedItem": {
            "certificateSigner": null,
            "comment": "hello world1",
            "createdAt": "2020-11-25T10:19:37.608Z",
            "fileName": null,
            "id": "b2148cc0-6ee8-440e-9c4b-cd5486b36c3c",
            "path": "/root/helloaworld/1/1",
            "sha256": null,
            "type": "path",
            "updatedAt": "2020-11-25T10:19:37.608Z"
        }
    }
}

Human Readable Output

Found Allowed Item

id comment path createdAt type updatedAt
b2148cc0-6ee8-440e-9c4b-cd5486b36c3c hello world1 /root/helloaworld/1/1 2020-11-25T10:19:37.608Z path 2020-11-25T10:19:37.608Z

sophos-central-allowed-item-add


Add a new allowed item.

Base Command

sophos-central-allowed-item-add

Input

Argument Name Description Required
comment Comment indicating why the item should be allowed. Required
certificate_signer The value saved for the certificateSigner. Optional
file_name The file name. Optional
path The path for the application. Optional
sha256 The SHA256 value for the application. Optional
item_type The property by which an item is allowed. Note that the specified item type requires the matching argument filled. For example, the item type “path” requires the path argument. Possible values are: “path”, “sha256”, and “certificateSigner”. Required
origin_endpoint_id The endpoint where the item to be allowed was last seen. Optional

Context Output

Path Type Description
SophosCentral.AllowedItem.comment String A comment indicating why the item was allowed.
SophosCentral.AllowedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.AllowedItem.createdById String The unique ID for the user who created the item.
SophosCentral.AllowedItem.createdByName String The name for the user who created the item.
SophosCentral.AllowedItem.id String The unique ID for the allowed application.
SophosCentral.AllowedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.AllowedItem.fileName String The file name.
SophosCentral.AllowedItem.path String The path for the application.
SophosCentral.AllowedItem.sha256 String The SHA256 value for the application.
SophosCentral.AllowedItem.type String The property by which an item is allowed.
SophosCentral.AllowedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.AllowedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.AllowedItem.originPersonId String ID of the originating person.
SophosCentral.AllowedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-allowed-item-add comment="hello world1" item_type=path path=/root/helloaworld/12

Context Example

{
    "SophosCentral": {
        "AllowedItem": {
            "certificateSigner": null,
            "comment": "hello world1",
            "createdAt": "2020-11-25T10:47:32.082Z",
            "fileName": null,
            "id": "c68f1abc-986d-43eb-b050-d9113959207a",
            "path": "/root/helloaworld/12",
            "sha256": null,
            "type": "path",
            "updatedAt": "2020-11-25T10:47:32.082Z"
        }
    }
}

Human Readable Output

Added Allowed Item

id comment path createdAt type updatedAt
c68f1abc-986d-43eb-b050-d9113959207a hello world1 /root/helloaworld/12 2020-11-25T10:47:32.082Z path 2020-11-25T10:47:32.082Z

sophos-central-allowed-item-update


Update an existing allowed item.

Base Command

sophos-central-allowed-item-update

Input

Argument Name Description Required
allowed_item_id The allowed item ID. Required
comment Comment indicating why the item should be allowed. Required

Context Output

Path Type Description
SophosCentral.AllowedItem.comment String A comment indicating why the item was allowed.
SophosCentral.AllowedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.AllowedItem.createdById String The unique ID for the user who created the item.
SophosCentral.AllowedItem.createdByName String The name for the user who created the item.
SophosCentral.AllowedItem.id String The unique ID for the allowed application.
SophosCentral.AllowedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.AllowedItem.fileName String The file name.
SophosCentral.AllowedItem.path String The path for the application.
SophosCentral.AllowedItem.sha256 String The SHA256 value for the application.
SophosCentral.AllowedItem.type String The property by which an item is allowed.
SophosCentral.AllowedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.AllowedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.AllowedItem.originPersonId String ID of the originating person.
SophosCentral.AllowedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-allowed-item-update allowed_item_id=b2148cc0-6ee8-440e-9c4b-cd5486b36c3c comment=changedcomment

Context Example

{
    "SophosCentral": {
        "AllowedItem": {
            "certificateSigner": null,
            "comment": "changedcomment",
            "createdAt": "2020-11-25T10:19:37.608Z",
            "fileName": null,
            "id": "b2148cc0-6ee8-440e-9c4b-cd5486b36c3c",
            "path": "/root/helloaworld/1/1",
            "sha256": null,
            "type": "path",
            "updatedAt": "2020-11-25T10:47:39.104Z"
        }
    }
}

Human Readable Output

Updated Allowed Item

id comment path createdAt type updatedAt
b2148cc0-6ee8-440e-9c4b-cd5486b36c3c changedcomment /root/helloaworld/1/1 2020-11-25T10:19:37.608Z path 2020-11-25T10:47:39.104Z

sophos-central-allowed-item-delete


Delete an existing allowed item.

Base Command

sophos-central-allowed-item-delete

Input

Argument Name Description Required
allowed_item_id The allowed item ID. Required

Context Output

Path Type Description
SophosCentral.DeletedAllowedItem.deletedItemId String The ID of the deleted item.

Command Example

!sophos-central-allowed-item-delete allowed_item_id=b2148cc0-6ee8-440e-9c4b-cd5486b36c3c

Context Example

{
    "SophosCentral": {
        "DeletedAllowedItem": {
            "deletedItemId": "b2148cc0-6ee8-440e-9c4b-cd5486b36c3c"
        }
    }
}

Human Readable Output

Success deleting allowed item: b2148cc0-6ee8-440e-9c4b-cd5486b36c3c

sophos-central-blocked-item-list


Get all blocked items.

Base Command

sophos-central-blocked-item-list

Input

Argument Name Description Required
page_size The maximum size of the page requested. Default is “50”. Maximum is “100”. Optional
page Page number to return. Default is “1” Optional

Context Output

Path Type Description
SophosCentral.BlockedItem.comment String A comment indicating why the item was allowed.
SophosCentral.BlockedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.BlockedItem.createdById String The unique ID for the user who created the item.
SophosCentral.BlockedItem.createdByName String The name for the user who created the item.
SophosCentral.BlockedItem.id String The unique ID for the allowed application.
SophosCentral.BlockedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.BlockedItem.fileName String The file name.
SophosCentral.BlockedItem.path String The path for the application.
SophosCentral.BlockedItem.sha256 String The SHA256 value for the application.
SophosCentral.BlockedItem.type String The property by which an item is allowed.
SophosCentral.BlockedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.BlockedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.BlockedItem.originPersonId String ID of the originating person.
SophosCentral.BlockedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-blocked-item-list page=1 page_size=50

Context Example

{
    "SophosCentral": {
        "BlockedItem": [
            {
                "certificateSigner": null,
                "comment": "hello 2world",
                "createdAt": "2020-11-25T10:19:54.523Z",
                "fileName": null,
                "id": "9b44086b-95bd-43e5-b84b-82b91725f02b",
                "path": null,
                "sha256": "c7f4db9b3191e6e693ce938bd74fab37aee71372c8a034f50b0a62d8c69e4de1",
                "type": "sha256",
                "updatedAt": null
            },
            {
                "certificateSigner": null,
                "comment": "hello world",
                "createdAt": "2020-11-01T12:55:47.476Z",
                "fileName": null,
                "id": "fd0f08db-966b-4979-8cbb-876a2bbd29c9",
                "path": null,
                "sha256": "c6f4db9b3191e6e693ce938bd74fab37aee71372c8a034f5040362d8c69e4de4",
                "type": "sha256",
                "updatedAt": null
            },
            {
                "certificateSigner": null,
                "comment": "It's just a test",
                "createdAt": "2020-11-01T10:22:55.556Z",
                "fileName": null,
                "id": "f15f7b34-e1c4-4fd2-bbcb-f5c64e6e9994",
                "path": null,
                "sha256": "b424f1cb9f1c11a4251ebbf28cd032e6267673e899dce7ac6b7deccde49917af",
                "type": "sha256",
                "updatedAt": null
            }
        ]
    }
}

Human Readable Output

Listed Blocked Items

|id|comment|sha256|createdAt|type|
|—|—|—|—|—|
| 9b44086b-95bd-43e5-b84b-82b91725f02b | hello 2world | c7f4db9b3191e6e693ce938bd74fab37aee71372c8a034f50b0a62d8c69e4de1 | 2020-11-25T10:19:54.523Z | sha256 |
| fd0f08db-966b-4979-8cbb-876a2bbd29c9 | hello world | c6f4db9b3191e6e693ce938bd74fab37aee71372c8a034f5040362d8c69e4de4 | 2020-11-01T12:55:47.476Z | sha256 |
| f15f7b34-e1c4-4fd2-bbcb-f5c64e6e9994 | It’s just a test | b424f1cb9f1c11a4251ebbf28cd032e6267673e899dce7ac6b7deccde49917af | 2020-11-01T10:22:55.556Z | sha256 |
Current page: 1.
Results on this page: 3.
Maximum number of results allowed in a page: 100.

sophos-central-blocked-item-get


Get a single blocked item by ID.

Base Command

sophos-central-blocked-item-get

Input

Argument Name Description Required
blocked_item_id The blocked item ID. Required

Context Output

Path Type Description
SophosCentral.BlockedItem.comment String A comment indicating why the item was allowed.
SophosCentral.BlockedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.BlockedItem.createdById String The unique ID for the user who created the item.
SophosCentral.BlockedItem.createdByName String The name for the user who created the item.
SophosCentral.BlockedItem.id String The unique ID for the allowed application.
SophosCentral.BlockedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.BlockedItem.fileName String The file name.
SophosCentral.BlockedItem.path String The path for the application.
SophosCentral.BlockedItem.sha256 String The SHA256 value for the application.
SophosCentral.BlockedItem.type String The property by which an item is allowed.
SophosCentral.BlockedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.BlockedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.BlockedItem.originPersonId String ID of the originating person.
SophosCentral.BlockedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-blocked-item-get blocked_item_id=9b44086b-95bd-43e5-b84b-82b91725f02b

Context Example

{
    "SophosCentral": {
        "BlockedItem": {
            "certificateSigner": null,
            "comment": "hello 2world",
            "createdAt": "2020-11-25T10:19:54.523Z",
            "fileName": null,
            "id": "9b44086b-95bd-43e5-b84b-82b91725f02b",
            "path": null,
            "sha256": "c7f4db9b3191e6e693ce938bd74fab37aee71372c8a034f50b0a62d8c69e4de1",
            "type": "sha256",
            "updatedAt": null
        }
    }
}

Human Readable Output

Found Blocked Item

id comment sha256 createdAt type
9b44086b-95bd-43e5-b84b-82b91725f02b hello 2world c7f4db9b3191e6e693ce938bd74fab37aee71372c8a034f50b0a62d8c69e4de1 2020-11-25T10:19:54.523Z sha256

sophos-central-blocked-item-add


Add a new blocked item.

Base Command

sophos-central-blocked-item-add

Input

Argument Name Description Required
comment Comment indicating why the item should be blocked. Required
certificate_signer The value saved for the certificateSigner. Optional
file_name The file name. Optional
path The path for the application. Optional
sha256 The SHA256 value for the application. Required
item_type The property by which an item is blocked. Possible value is sha256. Required

Context Output

Path Type Description
SophosCentral.BlockedItem.comment String A comment indicating why the item was allowed.
SophosCentral.BlockedItem.createdAt Date Date and time (UTC) when the allowed application was created.
SophosCentral.BlockedItem.createdById String The unique ID for the user who created the item.
SophosCentral.BlockedItem.createdByName String The name for the user who created the item.
SophosCentral.BlockedItem.id String The unique ID for the allowed application.
SophosCentral.BlockedItem.certificateSigner String The value saved for the certificateSigner.
SophosCentral.BlockedItem.fileName String The file name.
SophosCentral.BlockedItem.path String The path for the application.
SophosCentral.BlockedItem.sha256 String The SHA256 value for the application.
SophosCentral.BlockedItem.type String The property by which an item is allowed.
SophosCentral.BlockedItem.updatedAt Date Date and time (UTC) when the allowed application was updated.
SophosCentral.BlockedItem.originEndpointId String ID of the originating endpoint.
SophosCentral.BlockedItem.originPersonId String ID of the originating person.
SophosCentral.BlockedItem.originPersonName String Name of the originating person.

Command Example

!sophos-central-blocked-item-add comment="hello 2world" item_type=sha256 sha256=CAF4DB9B3191E6E693CE938BD74FAB37AEE71372C8A034F5040362D8C69E4DE4

Context Example

{
    "SophosCentral": {
        "BlockedItem": {
            "certificateSigner": null,
            "comment": "hello 2world",
            "createdAt": "2020-11-25T10:47:46.428Z",
            "fileName": null,
            "id": "9535be44-40f3-4704-94df-6afa1e563f9c",
            "path": null,
            "sha256": "caf4db9b3191e6e693ce938bd74fab37aee71372c8a034f5040362d8c69e4de4",
            "type": "sha256",
            "updatedAt": null
        }
    }
}

Human Readable Output

Added Blocked Item

id comment sha256 createdAt type
9535be44-40f3-4704-94df-6afa1e563f9c hello 2world caf4db9b3191e6e693ce938bd74fab37aee71372c8a034f5040362d8c69e4de4 2020-11-25T10:47:46.428Z sha256

sophos-central-blocked-item-delete


Delete an existing blocked item.

Base Command

sophos-central-blocked-item-delete

Input

Argument Name Description Required
blocked_item_id The blocked item ID. Required

Context Output

Path Type Description
SophosCentral.DeletedBlockedItem.deletedItemId String The ID of the deleted item.

Command Example

!sophos-central-blocked-item-delete blocked_item_id=9b44086b-95bd-43e5-b84b-82b91725f02b

Context Example

{
    "SophosCentral": {
        "DeletedBlockedItem": {
            "deletedItemId": "9b44086b-95bd-43e5-b84b-82b91725f02b"
        }
    }
}

Human Readable Output

Success deleting blocked item: 9b44086b-95bd-43e5-b84b-82b91725f02b

sophos-central-scan-exclusion-list


List all scan exclusions.

Base Command

sophos-central-scan-exclusion-list

Input

Argument Name Description Required
exclusion_type Scan exclusion type. Possible values are: “path”, “posixPath”, “virtualPath”, “process”, “web”, “pua”, “exploitMitigation”, “amsi”, “behavioral” Optional
page_size The maximum size of the page requested. Default is “50”. Maximum is “100”. Optional
page The page number to fetch. Default is “1” Optional

Context Output

Path Type Description
SophosCentral.ScanExclusion.comment String A comment indicating why the exclusion was updated.
SophosCentral.ScanExclusion.description String The exclusion description added by the system.
SophosCentral.ScanExclusion.id String The unique ID for the scanning exclusion setting.
SophosCentral.ScanExclusion.scanMode String The scan mode. Default is “onDemandAndOnAccess” for exclusions of type path, posixPath, and virtualPath and “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode.
SophosCentral.ScanExclusion.type String The scanning exclusion type.
SophosCentral.ScanExclusion.value String The exclusion value.

Command Example


#### Context Example

```json
{
    "SophosCentral": {
        "ScanExclusion": [
            {
                "comment": "Sophos temporary exclusion see KBA 133945",
                "description": "Sophos temporary exclusion see KBA 133945",
                "id": "369b0956-a7b6-44fc-b1cc-bd7b3279c663",
                "scanMode": "onDemandAndOnAccess",
                "type": "path",
                "value": "%programfiles(x86)%\\Sophos\\Sophos Anti-Virus\\"
            },
            {
                "comment": null,
                "description": null,
                "id": "6868151e-4eac-4d0a-8985-5db9bff9d6f2",
                "scanMode": "onDemandAndOnAccess",
                "type": "path",
                "value": "testpathhzh"
            },
            {
                "comment": "changed before demo",
                "description": null,
                "id": "16bac29f-17a4-4c3a-9370-8c5968c5ac7d",
                "scanMode": "onAccess",
                "type": "process",
                "value": "changedvirus.exe"
            }
        ]
    }
}

Human Readable Output

Listed Scan Exclusions

|id|value|type|description|comment|scanMode|
|—|—|—|—|—|—|
| 369b0956-a7b6-44fc-b1cc-bd7b3279c663 | %programfiles(x86)%\Sophos\Sophos Anti-Virus\ | path | Sophos temporary exclusion see KBA 133945 | Sophos temporary exclusion see KBA 133945 | onDemandAndOnAccess |
| 6868151e-4eac-4d0a-8985-5db9bff9d6f2 | testpathhzh | path | | | onDemandAndOnAccess |
| 16bac29f-17a4-4c3a-9370-8c5968c5ac7d | changedvirus.exe | process | | changed before demo | onAccess |
Current page: 1.
Results on this page: 3.
Maximum number of results allowed in a page: 100.

sophos-central-scan-exclusion-get


Get a single scan exclusion by ID.

Base Command

sophos-central-scan-exclusion-get

Input

Argument Name Description Required
exclusion_id The exclusion ID. Required

Context Output

Path Type Description
SophosCentral.ScanExclusion.comment String A comment indicating why the exclusion was updated.
SophosCentral.ScanExclusion.description String The exclusion description added by the system.
SophosCentral.ScanExclusion.id String The unique ID for the scanning exclusion setting.
SophosCentral.ScanExclusion.scanMode String The scan mode. Default is “onDemandAndOnAccess” for exclusions of type path, posixPath, and virtualPath and “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode.
SophosCentral.ScanExclusion.type String The scanning exclusion type.
SophosCentral.ScanExclusion.value String The exclusion value.

Command Example

!sophos-central-scan-exclusion-get exclusion_id=6868151e-4eac-4d0a-8985-5db9bff9d6f2

Context Example

{
    "SophosCentral": {
        "ScanExclusion": {
            "comment": null,
            "description": null,
            "id": "6868151e-4eac-4d0a-8985-5db9bff9d6f2",
            "scanMode": "onDemandAndOnAccess",
            "type": "path",
            "value": "testpathhzh"
        }
    }
}

Human Readable Output

Found Scan Exclusion

id value type scanMode
6868151e-4eac-4d0a-8985-5db9bff9d6f2 testpathhzh path onDemandAndOnAccess

sophos-central-scan-exclusion-add


Add a new scan exclusion.

Base Command

sophos-central-scan-exclusion-add

Input

Argument Name Description Required
comment A comment indicating why the exclusion was created. Optional
scan_mode The scan mode. Possible values are: “onDemand”, “onAccess”, and “onDemandAndOnAccess”. Default is “onDemandAndOnAccess” for exclusions of type path, posixPath and virtualPath, “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode. Optional
exclusion_type The scanning exclusion type. Possible values are: “path”, “posixPath”, “virtualPath”, “process”, “web”, “pua”, “exploitMitigation”, “amsi”, “behavioral”. Required
value The exclusion value. Required

Context Output

Path Type Description
SophosCentral.ScanExclusion.comment String A comment indicating why the exclusion was updated.
SophosCentral.ScanExclusion.description String The exclusion description added by the system.
SophosCentral.ScanExclusion.id String The unique ID for the scanning exclusion setting.
SophosCentral.ScanExclusion.scanMode String The scan mode. Default is “onDemandAndOnAccess” for exclusions of type path, posixPath, and virtualPath and “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode.
SophosCentral.ScanExclusion.type String The scanning exclusion type.
SophosCentral.ScanExclusion.value String The exclusion value.

Command Example

!sophos-central-scan-exclusion-add exclusion_type=path value=avsdfasdfaa

Context Example

{
    "SophosCentral": {
        "ScanExclusion": {
            "comment": null,
            "description": null,
            "id": "be7b05bf-368b-4621-8131-0776486e1c7b",
            "scanMode": "onDemandAndOnAccess",
            "type": "path",
            "value": "avsdfasdfaa"
        }
    }
}

Human Readable Output

Added Scan Exclusion

id value type scanMode
be7b05bf-368b-4621-8131-0776486e1c7b avsdfasdfaa path onDemandAndOnAccess

sophos-central-scan-exclusion-update


Update an existing scan exclusion.

Base Command

sophos-central-scan-exclusion-update

Input

Argument Name Description Required
comment A comment indicating why the exclusion was created. Optional
scan_mode The default value of scan mode is “onDemandAndOnAccess” for exclusions of type path, posixPath and virtualPath, “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode. Optional
exclusion_id The exclusion ID. Required
value The exclusion value. Optional

Context Output

Path Type Description
SophosCentral.ScanExclusion.comment String A comment indicating why the exclusion was updated.
SophosCentral.ScanExclusion.description String The exclusion description added by the system.
SophosCentral.ScanExclusion.id String The unique ID for the scanning exclusion setting.
SophosCentral.ScanExclusion.scanMode String The scan mode. Default is “onDemandAndOnAccess” for exclusions of type path, posixPath, and virtualPath and “onAccess” for process, web, pua, amsi. Behavioral and Detected Exploits (exploitMitigation) type exclusions do not support a scan mode.
SophosCentral.ScanExclusion.type String The scanning exclusion type.
SophosCentral.ScanExclusion.value String The exclusion value.

Command Example

!sophos-central-scan-exclusion-update exclusion_id=6868151e-4eac-4d0a-8985-5db9bff9d6f2

Context Example

{
    "SophosCentral": {
        "ScanExclusion": {
            "comment": null,
            "description": null,
            "id": "6868151e-4eac-4d0a-8985-5db9bff9d6f2",
            "scanMode": "onDemandAndOnAccess",
            "type": "path",
            "value": "testpathhzh"
        }
    }
}

Human Readable Output

Updated Scan Exclusion

id value type scanMode
6868151e-4eac-4d0a-8985-5db9bff9d6f2 testpathhzh path onDemandAndOnAccess

sophos-central-scan-exclusion-delete


Delete an existing scan exclusion.

Base Command

sophos-central-scan-exclusion-delete

Input

Argument Name Description Required
exclusion_id The exclusion ID. Required

Context Output

Path Type Description
SophosCentral.DeletedScanExclusion.deletedExclusionId String The ID of the deleted exclusion.

Command Example

!sophos-central-scan-exclusion-delete exclusion_id=6868151e-4eac-4d0a-8985-5db9bff9d6f2

Context Example

{
    "SophosCentral": {
        "DeletedScanExclusion": {
            "deletedExclusionId": "6868151e-4eac-4d0a-8985-5db9bff9d6f2"
        }
    }
}

Human Readable Output

Success deleting scan exclusion: 6868151e-4eac-4d0a-8985-5db9bff9d6f2

sophos-central-exploit-mitigation-list


List exploit mitigation settings for all protected applications.

Base Command

sophos-central-exploit-mitigation-list

Input

Argument Name Description Required
mitigation_type Exploit mitigation type. Possible values are: “detected” and “custom”. Optional
page_size The maximum size of the page requested. Default is “50”. Maximum is “100”. Optional
page The page number to fetch. Default is “1”. Optional
modified Whether the Exploit Mitigation application has been customized. Possible values are: “true” and “false”. Optional

Context Output

Path Type Description
SophosCentral.ExploitMitigation.category String The Exploit Mitigation category ID.
SophosCentral.ExploitMitigation.name String The name given to this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.id String The ID of this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.paths String Paths included in this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.type String Whether the application was detected by the system or created by the user.

Command Example


#### Context Example

```json
{
    "SophosCentral": {
        "ExploitMitigation": [
            {
                "category": "other",
                "id": "ff9d87d0-c944-4ca5-9f76-c5efd1f89ded",
                "name": "3bf6f110-48d8-4114-95e3-a286ac50d722",
                "paths": [
                    "newnewnewnewnew"
                ],
                "type": "custom"
            },
            {
                "category": "browsers",
                "id": "06aefe81-7f83-4768-9cec-59d86d7ee133",
                "name": "Firefox",
                "paths": [
                    "$programfiles\\Mozilla Firefox\\firefox.exe"
                ],
                "type": "detected"
            },
            {
                "category": "browsers",
                "id": "b07c6cd2-ee1b-4cf4-8bd2-d3be05e461cf",
                "name": "Google Chrome",
                "paths": [
                    "$programfiles\\Google\\Chrome\\Application\\chrome.exe"
                ],
                "type": "detected"
            },
            {
                "category": "browsers",
                "id": "df7c2b63-dda4-4dc4-a12d-471cad799dbd",
                "name": "Internet Explorer",
                "paths": [
                    "$programfiles\\Internet Explorer\\iexplore.exe"
                ],
                "type": "detected"
            },
            {
                "category": "java",
                "id": "f5d5ba2d-d905-4e7b-b3b7-abb0f30f38b3",
                "name": "Java(TM) Platform SE binary",
                "paths": [
                    "$programfiles\\java\\jre1.8.0_271\\bin\\java.exe",
                    "$programfiles\\java\\jre1.8.0_271\\bin\\javaw.exe"
                ],
                "type": "detected"
            },
            {
                "category": "java",
                "id": "9ddf4b33-9f65-4422-898e-d5b5b450e8d8",
                "name": "Java(TM) Web Launcher",
                "paths": [
                    "$programfiles\\java\\jre1.8.0_271\\bin\\jp2launcher.exe"
                ],
                "type": "detected"
            },
            {
                "category": "java",
                "id": "b44f50e0-0332-444a-bdb0-cfec43fc2def",
                "name": "Java(TM) Web Start Launcher",
                "paths": [
                    "$programfiles\\java\\jre1.8.0_271\\bin\\javaws.exe"
                ],
                "type": "detected"
            },
            {
                "category": "other",
                "id": "a49af552-55e1-4dcd-a909-2310bcb8016f",
                "name": "KeePass",
                "paths": [
                    "$programfiles\\KeePass Password Safe 2\\KeePass.exe"
                ],
                "type": "detected"
            },
            {
                "category": "browsers",
                "id": "4178130a-0d4e-435d-b4bb-db594810a43a",
                "name": "Microsoft Edge",
                "paths": [
                    "$programfiles\\Microsoft\\Edge\\Application\\msedge.exe",
                    "$windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdge.exe"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "ecbcd6a5-73d5-4060-b49f-b9de2e0587fc",
                "name": "Microsoft Excel",
                "paths": [
                    "$programfiles\\Microsoft Office\\Root\\Office16\\EXCEL.EXE"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "7907eaf2-b4f0-40e3-9dd8-f7e452ffc7cf",
                "name": "Microsoft Outlook",
                "paths": [
                    "$programfiles\\Microsoft Office\\root\\Office16\\OUTLOOK.EXE"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "6cadbe94-8e1c-4648-aa9e-b0b39e1cb1fb",
                "name": "Microsoft PowerPoint",
                "paths": [
                    "$programfiles\\Microsoft Office\\Root\\Office16\\POWERPNT.EXE"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "417fd1be-fafa-4e3b-9a9b-589f7f20b72c",
                "name": "Microsoft Word",
                "paths": [
                    "$programfiles\\Microsoft Office\\Root\\Office16\\WINWORD.EXE"
                ],
                "type": "detected"
            },
            {
                "category": "browsers",
                "id": "68026667-ca17-473d-b797-ccebe2d9da87",
                "name": "MicrosoftEdgeCP.exe",
                "paths": [
                    "$windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdgeCP.exe"
                ],
                "type": "detected"
            },
            {
                "category": "java",
                "id": "01e26718-ddf3-4aad-b465-d7279b755c32",
                "name": "OpenJDK Platform binary",
                "paths": [
                    "$programfiles\\JetBrains\\PyCharm Community Edition 2020.1.2\\jbr\\bin\\java.exe"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "9e378d93-4b62-4976-9a7c-5fdbbafa0b79",
                "name": "Pick an app",
                "paths": [
                    "$system32\\OpenWith.exe"
                ],
                "type": "detected"
            },
            {
                "category": "plugins",
                "id": "a0b96b54-6895-408c-ac68-f84ca81c248a",
                "name": "Plugin Container for Firefox",
                "paths": [
                    "$programfiles\\Mozilla Firefox\\plugin-container.exe"
                ],
                "type": "detected"
            },
            {
                "category": "other",
                "id": "3ac3fd9b-5b30-4e19-a9a4-303f553a4500",
                "name": "Skype for Business",
                "paths": [
                    "$programfiles\\Microsoft Office\\Root\\Office16\\lync.exe"
                ],
                "type": "detected"
            },
            {
                "category": "media",
                "id": "dbedc673-218a-4814-99f0-33642a65b1fd",
                "name": "Windows Media Player",
                "paths": [
                    "$programfiles\\Windows Media Player\\wmplayer.exe"
                ],
                "type": "detected"
            },
            {
                "category": "office",
                "id": "fd4f1dc8-4b4a-429e-ac27-bd757352f52c",
                "name": "Windows Wordpad Application",
                "paths": [
                    "$programfiles\\Windows NT\\Accessories\\WORDPAD.EXE"
                ],
                "type": "detected"
            },
            {
                "category": "other",
                "id": "563f4022-0a28-47f8-9bb6-7774aa7794e3",
                "name": "b2477368-4e58-4868-af90-554f948f4077",
                "paths": [
                    "wooba"
                ],
                "type": "custom"
            },
            {
                "category": "other",
                "id": "b19800cf-a98a-43dc-8efc-6de1f2a7321e",
                "name": "cde78059-3164-46c6-903f-c27b9103ef37",
                "paths": [
                    "testpathhhh"
                ],
                "type": "custom"
            },
            {
                "category": "other",
                "id": "91fff008-3609-46f3-9fc7-44713635b775",
                "name": "ce697cb7-06da-4e02-bcde-21f73b81d5ee",
                "paths": [
                    "changed\\path"
                ],
                "type": "custom"
            }
        ]
    }
}

Human Readable Output

Listed Exploit Mitigations

|id|name|type|category|paths|
|—|—|—|—|—|
| ff9d87d0-c944-4ca5-9f76-c5efd1f89ded | 3bf6f110-48d8-4114-95e3-a286ac50d722 | custom | other | newnewnewnewnew |
| 06aefe81-7f83-4768-9cec-59d86d7ee133 | Firefox | detected | browsers | $programfiles\Mozilla Firefox\firefox.exe |
| b07c6cd2-ee1b-4cf4-8bd2-d3be05e461cf | Google Chrome | detected | browsers | $programfiles\Google\Chrome\Application\chrome.exe |
| df7c2b63-dda4-4dc4-a12d-471cad799dbd | Internet Explorer | detected | browsers | $programfiles\Internet Explorer\iexplore.exe |
| f5d5ba2d-d905-4e7b-b3b7-abb0f30f38b3 | Java(TM) Platform SE binary | detected | java | $programfiles\java\jre1.8.0_271\bin\java.exe,
$programfiles\java\jre1.8.0_271\bin\javaw.exe |
| 9ddf4b33-9f65-4422-898e-d5b5b450e8d8 | Java(TM) Web Launcher | detected | java | $programfiles\java\jre1.8.0_271\bin\jp2launcher.exe |
| b44f50e0-0332-444a-bdb0-cfec43fc2def | Java(TM) Web Start Launcher | detected | java | $programfiles\java\jre1.8.0_271\bin\javaws.exe |
| a49af552-55e1-4dcd-a909-2310bcb8016f | KeePass | detected | other | $programfiles\KeePass Password Safe 2\KeePass.exe |
| 4178130a-0d4e-435d-b4bb-db594810a43a | Microsoft Edge | detected | browsers | $programfiles\Microsoft\Edge\Application\msedge.exe,
$windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe |
| ecbcd6a5-73d5-4060-b49f-b9de2e0587fc | Microsoft Excel | detected | office | $programfiles\Microsoft Office\Root\Office16\EXCEL.EXE |
| 7907eaf2-b4f0-40e3-9dd8-f7e452ffc7cf | Microsoft Outlook | detected | office | $programfiles\Microsoft Office\root\Office16\OUTLOOK.EXE |
| 6cadbe94-8e1c-4648-aa9e-b0b39e1cb1fb | Microsoft PowerPoint | detected | office | $programfiles\Microsoft Office\Root\Office16\POWERPNT.EXE |
| 417fd1be-fafa-4e3b-9a9b-589f7f20b72c | Microsoft Word | detected | office | $programfiles\Microsoft Office\Root\Office16\WINWORD.EXE |
| 68026667-ca17-473d-b797-ccebe2d9da87 | MicrosoftEdgeCP.exe | detected | browsers | $windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdgeCP.exe |
| 01e26718-ddf3-4aad-b465-d7279b755c32 | OpenJDK Platform binary | detected | java | $programfiles\JetBrains\PyCharm Community Edition 2020.1.2\jbr\bin\java.exe |
| 9e378d93-4b62-4976-9a7c-5fdbbafa0b79 | Pick an app | detected | office | $system32\OpenWith.exe |
| a0b96b54-6895-408c-ac68-f84ca81c248a | Plugin Container for Firefox | detected | plugins | $programfiles\Mozilla Firefox\plugin-container.exe |
| 3ac3fd9b-5b30-4e19-a9a4-303f553a4500 | Skype for Business | detected | other | $programfiles\Microsoft Office\Root\Office16\lync.exe |
| dbedc673-218a-4814-99f0-33642a65b1fd | Windows Media Player | detected | media | $programfiles\Windows Media Player\wmplayer.exe |
| fd4f1dc8-4b4a-429e-ac27-bd757352f52c | Windows Wordpad Application | detected | office | $programfiles\Windows NT\Accessories\WORDPAD.EXE |
| 563f4022-0a28-47f8-9bb6-7774aa7794e3 | b2477368-4e58-4868-af90-554f948f4077 | custom | other | wooba |
| b19800cf-a98a-43dc-8efc-6de1f2a7321e | cde78059-3164-46c6-903f-c27b9103ef37 | custom | other | testpathhhh |
| 91fff008-3609-46f3-9fc7-44713635b775 | ce697cb7-06da-4e02-bcde-21f73b81d5ee | custom | other | changed\path |
Current page: 1.
Results on this page: 23.
Maximum number of results allowed in a page: 100.

sophos-central-exploit-mitigation-get


Get exploit mitigation settings for a single application.

Base Command

sophos-central-exploit-mitigation-get

Input

Argument Name Description Required
mitigation_id The Exploit Mitigation application ID. Required

Context Output

Path Type Description
SophosCentral.ExploitMitigation.category String The Exploit Mitigation category ID.
SophosCentral.ExploitMitigation.name String The name given to this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.id String The ID of this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.paths String Paths included in this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.type String Whether the application was detected by the system or created by the user.

Command Example

!sophos-central-exploit-mitigation-get mitigation_id=ff9d87d0-c944-4ca5-9f76-c5efd1f89ded

Context Example

{
    "SophosCentral": {
        "ExploitMitigation": {
            "category": "other",
            "id": "ff9d87d0-c944-4ca5-9f76-c5efd1f89ded",
            "name": "3bf6f110-48d8-4114-95e3-a286ac50d722",
            "paths": [
                "newnewnewnewnew"
            ],
            "type": "custom"
        }
    }
}

Human Readable Output

Found Exploit Mitigation

id name type category paths
ff9d87d0-c944-4ca5-9f76-c5efd1f89ded 3bf6f110-48d8-4114-95e3-a286ac50d722 custom other newnewnewnewnew

sophos-central-exploit-mitigation-add


Exclude a set of file paths from exploit mitigation.

Base Command

sophos-central-exploit-mitigation-add

Input

Argument Name Description Required
path An absolute path to an application file to exclude. You may use HitmanPro.Alert expansion variables (e.g., $desktop, $programfiles). Required

Context Output

Path Type Description
SophosCentral.ExploitMitigation.category String The Exploit Mitigation category ID.
SophosCentral.ExploitMitigation.name String The name given to this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.id String The ID of this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.paths String Paths included in this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.type String Whether the application was detected by the system or created by the user.

Command Example

!sophos-central-exploit-mitigation-add path=testestesteset

Context Example

{
    "SophosCentral": {
        "ExploitMitigation": {
            "category": "other",
            "id": "755ec991-c04f-498f-ab8e-20ef1a187b52",
            "name": "d082226b-0c17-4959-a3ed-a6957f39c9bc",
            "paths": [
                "testestesteset"
            ],
            "type": "custom"
        }
    }
}

Human Readable Output

Added Exploit Mitigation

id name type category paths
755ec991-c04f-498f-ab8e-20ef1a187b52 d082226b-0c17-4959-a3ed-a6957f39c9bc custom other testestesteset

sophos-central-exploit-mitigation-update


Update exploit mitigation settings for an application.

Base Command

sophos-central-exploit-mitigation-update

Input

Argument Name Description Required
mitigation_id The Exploit Mitigation application ID. Required
path An absolute path to an application file to exclude. You may use HitmanPro.Alert expansion variables (e.g., $desktop, $programfiles). Required

Context Output

Path Type Description
SophosCentral.ExploitMitigation.category String The Exploit Mitigation category ID.
SophosCentral.ExploitMitigation.name String The name given to this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.id String The ID of this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.paths String Paths included in this Exploit Mitigation Application.
SophosCentral.ExploitMitigation.type String Whether the application was detected by the system or created by the user.

Command Example

!sophos-central-exploit-mitigation-update mitigation_id=ff9d87d0-c944-4ca5-9f76-c5efd1f89ded path=changed

Context Example

{
    "SophosCentral": {
        "ExploitMitigation": {
            "category": "other",
            "id": "ff9d87d0-c944-4ca5-9f76-c5efd1f89ded",
            "name": "3bf6f110-48d8-4114-95e3-a286ac50d722",
            "paths": [
                "changed"
            ],
            "type": "custom"
        }
    }
}

Human Readable Output

Updated Exploit Mitigation

id name type category paths
ff9d87d0-c944-4ca5-9f76-c5efd1f89ded 3bf6f110-48d8-4114-95e3-a286ac50d722 custom other changed

sophos-central-exploit-mitigation-delete


Delete a custom (user-defined) exploit mitigation application by ID.

Base Command

sophos-central-exploit-mitigation-delete

Input

Argument Name Description Required
mitigation_id The Exploit Mitigation application ID. Required

Context Output

Path Type Description
SophosCentral.DeletedExploitMitigation.deletedMitigationId String The ID of the deleted mitigation.

Command Example

!sophos-central-exploit-mitigation-delete mitigation_id=ff9d87d0-c944-4ca5-9f76-c5efd1f89ded

Context Example

{
    "SophosCentral": {
        "DeletedExploitMitigation": {
            "deletedMitigationId": "ff9d87d0-c944-4ca5-9f76-c5efd1f89ded"
        }
    }
}

Human Readable Output

Success deleting exploit mitigation: ff9d87d0-c944-4ca5-9f76-c5efd1f89ded

sophos-central-detected-exploit-list


List all detected exploits.

Base Command

sophos-central-detected-exploit-list

Input

Argument Name Description Required
page_size The maximum size of the page requested. Default is “50”. Maximum is “100”. Optional
page The page number to fetch. Default is “1”. Optional
thumbprint_not_in Filter out detected exploits with these thumbprints. Optional

Context Output

Path Type Description
SophosCentral.DetectedExploit.count Number The number of times the same exploit has been detected, potentially across multiple endpoints.
SophosCentral.DetectedExploit.description String The English description of the exploit detected event.
SophosCentral.DetectedExploit.id String The ID of this Exploit Mitigation Application.
SophosCentral.DetectedExploit.firstSeenAt Date When the exploit was first seen.
SophosCentral.DetectedExploit.lastSeenAt Date When the exploit was last seen.
SophosCentral.DetectedExploit.lastEndpointHostname String The endpoint hostname.
SophosCentral.DetectedExploit.lastEndpointId String The unique endpoint ID.
SophosCentral.DetectedExploit.lastUserName String Person’s name.
SophosCentral.DetectedExploit.lastUserId String The unique ID for the user.
SophosCentral.DetectedExploit.thumbprint String Matches [0-9a-zA-Z]{64}.

Command Example


#### Context Example

```json
{
    "SophosCentral": {
        "DetectedExploit": null
    }
}

Human Readable Output

Listed Detected Exploits

No entries.
Current page: 1.
Results on this page: 0.
Maximum number of results allowed in a page: 100.

sophos-central-detected-exploit-get


Get a single detected exploit.

Base Command

sophos-central-detected-exploit-get

Input

Argument Name Description Required
detected_exploit_id The ID of a previously detected exploit. Required

Context Output

Path Type Description
SophosCentral.DetectedExploit.count Number The number of times the same exploit has been detected, potentially across multiple endpoints.
SophosCentral.DetectedExploit.description String The English description of the exploit detected event.
SophosCentral.DetectedExploit.id String The ID of this Exploit Mitigation application.
SophosCentral.DetectedExploit.firstSeenAt Date When the exploit was first seen.
SophosCentral.DetectedExploit.lastSeenAt Date When the exploit was last seen.
SophosCentral.DetectedExploit.lastEndpointHostname String The endpoint hostname.
SophosCentral.DetectedExploit.lastEndpointId String The unique endpoint ID.
SophosCentral.DetectedExploit.lastUserName String Person’s name.
SophosCentral.DetectedExploit.lastUserId String The unique ID for the user.
SophosCentral.DetectedExploit.thumbprint String Matches [0-9a-zA-Z]{64}.

Command Example


#### Human Readable Output

### sophos-central-isolate-endpoint

***
Isolate one or more endpoints.

#### Base Command

`sophos-central-isolate-endpoint`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| endpoint_id | ID(s) of the endpoint(s) to be isolated. | Required |
| comment | Comment indicating why the endpoint(s) should be isolated. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| SophosCentral.EndpointIsolation.items.id | String | The unique endpoint ID. |
| SophosCentral.EndpointIsolation.items.isolation.enabled | Boolean | Isolation status. |
| SophosCentral.EndpointIsolation.items.isolation.lastEnabledAt | String | When isolation was last enabled for the endpoint. |
| SophosCentral.EndpointIsolation.items.isolation.lastEnabledBy.id | String | Principal Email or clientId by whom isolation was enabled. |
| SophosCentral.EndpointIsolation.items.isolation.lastDisabledAt | String | When isolation was last disabled for the endpoint. |
| SophosCentral.EndpointIsolation.items.isolation.lastDisabledBy.id | String | Principal Email or clientId by whom isolation was disabled. |
| SophosCentral.EndpointIsolation.items.isolation.comment | String | Reason endpoint should be isolated or not. |

#### Command Example

```!sophos-central-isolate-endpoint endpoint_id=25de27bc-b07a-4728-b7b2-a021365xxxxx```

#### Context Example

```json
{
    "items": [
        {
            "id": "25de27bc-b07a-4728-b7b2-a021365xxxxx",
            "isolation": {
                "enabled": true,
                "lastEnabledAt": "2021-08-13 09.07.03 GMT",
                "lastEnabledBy": {
                    "id": "e71332ab-c447-45ff-b356-b8b5f39xxxxx"
                },
                "lastDisabledAt": "2021-08-13 09.54.02 GMT",
                "lastDisabledBy": {
                    "id": "e71332ab-c447-45ff-b356-b8b5f39xxxxx"
                },
                "comment": "testing"
            }
        }
    ]
}

Human Readable Output

Endpoint(s) isolated successfully.

sophos-central-deisolate-endpoint


De-isolate one or more endpoints.

Base Command

sophos-central-deisolate-endpoint

Input

Argument Name Description Required
endpoint_id ID(s) of the endpoint(s) to be de-isolated. Required
comment Comment indicating why the endpoint(s) should be de-isolated. Optional

Context Output

Path Type Description
SophosCentral.EndpointIsolation.items.id String The unique endpoint ID.
SophosCentral.EndpointIsolation.items.isolation.enabled Boolean Isolation status.
SophosCentral.EndpointIsolation.items.isolation.lastEnabledAt String When isolation was last enabled for the endpoint.
SophosCentral.EndpointIsolation.items.isolation.lastEnabledBy.id String Principal Email or clientId by whom isolation was enabled.
SophosCentral.EndpointIsolation.items.isolation.lastDisabledAt String When isolation was last disabled for the endpoint.
SophosCentral.EndpointIsolation.items.isolation.lastDisabledBy.id String Principal Email or clientId by whom isolation was disabled.
SophosCentral.EndpointIsolation.items.isolation.comment String Reason endpoint should be isolated or not.

Command Example

!sophos-central-deisolate-endpoint endpoint_id=25de27bc-b07a-4728-b7b2-a021365xxxxx

Context Example

{
    "items": [
        {
            "id": "25de27bc-b07a-4728-b7b2-a021365xxxxx",
            "isolation": {
                "enabled": false,
                "lastEnabledAt": "2021-08-13 09.07.03 GMT",
                "lastEnabledBy": {
                    "id": "e71332ab-c447-45ff-b356-b8b5f39xxxxx"
                },
                "lastDisabledAt": "2021-08-13 09.54.02 GMT",
                "lastDisabledBy": {
                    "id": "e71332ab-c447-45ff-b356-b8b5f39xxxxx"
                },
                "comment": "testing"
            }
        }
    ]
}

Human Readable Output

Endpoint(s) de-isolated successfully.

sophos-central-usergroups-users-add


Add multiple users to the specified group.

Base Command

sophos-central-usergroups-users-add

Input

Argument Name Description Required
groupId Unique UUID of Group. Required
userIds Comma-separated list of User UUIDs. Maximum 1000 unique User IDs are allowed (You can retrieve the userIds from the sophos-central-users-list). Required

Context Output

Path Type Description
SophosCentral.UserGroups.id String The Group ID.
SophosCentral.UserGroups.addedUsers.id String User ID.
SophosCentral.UserGroups.addedUsers.name String User’s full name.

Command example

!sophos-central-usergroups-users-add groupId="733cce06-5ad0-487b-9547-03af02b5722e" userIds="09c515b2-009e-4e78-a83f-a5423e6def9a, f9029e98-311a-4c19-9908-15bafff9f39f, 86e0ae0f-77ef-423a-bbbf-d95e49edd468"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "addedUsers": [
                {
                    "id": "f9029e98-311a-4c19-9908-15bafff9f39f",
                    "name": "Domain\\User"
                },
                {
                    "id": "09c515b2-009e-4e78-a83f-a5423e6def9a",
                    "name": "GREEN\\testUser"
                },
                {
                    "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                    "name": "Administrator"
                }
            ],
            "id": "733cce06-5ad0-487b-9547-03af02b5722e"
        }
    }
}

Human Readable Output

User(s) added to the specified group.

sophos-central-usergroups-user-delete


Remove a specific User from the group.

Base Command

sophos-central-usergroups-user-delete

Input

Argument Name Description Required
groupId Unique UUID of Group (You can retrieve the group ID from the sophos-central-usergroups-list). Required
userId Unique UUID of User (You can retrieve the user ID from the sophos-central-users-list). Required

Context Output

Path Type Description
SophosCentral.UserGroups.id String The Group ID.
SophosCentral.UserGroups.users.removedUser String The User ID.

Command example

!sophos-central-usergroups-user-delete groupId="733cce06-5ad0-487b-9547-03af02b5722e" userId="86e0ae0f-77ef-423a-bbbf-d95e49edd468"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
            "removedUser": "86e0ae0f-77ef-423a-bbbf-d95e49edd468"
        }
    }
}

Human Readable Output

User removed from group.

sophos-central-usergroups-membership-get


List all users in a specific group.

Base Command

sophos-central-usergroups-membership-get

Input

Argument Name Description Required
groupId Unique Group UUID (You can retrieve the group ID from the sophos-central-usergroups-list). Required
search Search for items that match the given terms. Optional
searchFields Search only within the specified comma-separated field values. The following values are allowed: name, firstName, lastName, email, exchangeLogin When not specified, the default behavior is to search the full names of users, only. Optional
domain List the items that match the given domain. Optional
sourceType Types of sources of directory information. The following values are allowed: custom, activeDirectory, azureActiveDirectory. Possible values are: custom, activeDirectory, azureActiveDirectory. Optional
page The page number to fetch. Default is “1”. Default is 1. Optional
pageSize Size of the page requested. Default is “50”. Maximum is “100”. Default is 50. Optional

Context Output

Path Type Description
SophosCentral.UserGroups.users.id String User ID.
SophosCentral.UserGroups.users.name String User’s name.
SophosCentral.UserGroups.users.firstName String User’s first name or given name.
SophosCentral.UserGroups.users.lastName String User’s last name or surname.
SophosCentral.UserGroups.users.emailAddress String User’s email address.
SophosCentral.UserGroups.users.groups.total number Total number of groups.
SophosCentral.UserGroups.users.groups.itemsCount number Item count.
SophosCentral.UserGroups.users.groups.items.id String Group ID.
SophosCentral.UserGroups.users.groups.items.name String Group name.
SophosCentral.UserGroups.users.groups.items.displayName String Group display name.
SophosCentral.UserGroups.users.groups.tenant.id String Tenant ID.
SophosCentral.UserGroups.users.groups.source.type String Types of sources of directory information.

Command example

!sophos-central-usergroups-membership-get groupId="6ed5e258-b427-4fa0-a9cf-568d130796c3"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "id": "6ed5e258-b427-4fa0-a9cf-568d130796c3",
            "users": [
                {
                    "createdAt": "2022-03-28T05:09:51.524Z",
                    "email": "ruqdxvd1g7@lightning.example.com",
                    "firstName": "Administrator",
                    "groups": {
                        "items": [
                            {
                                "displayName": "GroupNameTestReadMe",
                                "id": "03d1fcb2-246e-4307-b570-82dcf9083686",
                                "name": "GroupNameTestReadMe"
                            },
                            {
                                "displayName": "Group 2-Updated",
                                "id": "6ed5e258-b427-4fa0-a9cf-568d130796c3",
                                "name": "Group 2-Updated"
                            },
                            {
                                "displayName": "Group1",
                                "id": "552f6e04-559e-4225-b6a4-870155de8979",
                                "name": "Group1"
                            }
                        ],
                        "itemsCount": 3,
                        "total": 3
                    },
                    "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                    "lastName": "",
                    "name": "Administrator",
                    "source": {
                        "type": "custom"
                    },
                    "tenant": {
                        "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                    },
                    "updatedAt": "2022-03-28T12:43:26.994Z"
                },
                {
                    "createdAt": "2022-06-15T06:14:14.832Z",
                    "groups": {
                        "items": [
                            {
                                "displayName": "Group 2-Updated",
                                "id": "6ed5e258-b427-4fa0-a9cf-568d130796c3",
                                "name": "Group 2-Updated"
                            },
                            {
                                "displayName": "TestGroupName-2",
                                "id": "28fd524c-e7ae-476e-87c6-0f0a2ac47592",
                                "name": "TestGroupName-2"
                            },
                            {
                                "displayName": "Group&123",
                                "id": "17d33950-4980-4dfc-83c9-d0b8dce0deaa",
                                "name": "Group&123"
                            }
                        ],
                        "itemsCount": 3,
                        "total": 3
                    },
                    "id": "c1552a7b-efe9-4a45-8168-72489e44a3f3",
                    "name": "Lightning-8483qawudl\\Lightning",
                    "source": {
                        "type": "custom"
                    },
                    "tenant": {
                        "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                    }
                },
                {
                    "createdAt": "2022-06-15T09:52:37.921Z",
                    "groups": {
                        "items": [
                            {
                                "displayName": "Group 2-Updated",
                                "id": "6ed5e258-b427-4fa0-a9cf-568d130796c3",
                                "name": "Group 2-Updated"
                            }
                        ],
                        "itemsCount": 1,
                        "total": 1
                    },
                    "id": "69d3d421-f4cc-4a24-b093-8b2e5c6d20a4",
                    "name": "Lightning-gm4vu3jxek\\Lightning",
                    "source": {
                        "type": "custom"
                    },
                    "tenant": {
                        "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                    }
                },
                {
                    "createdAt": "2022-07-07T06:18:55.746Z",
                    "groups": {
                        "items": [
                            {
                                "displayName": "Group 2-Updated",
                                "id": "6ed5e258-b427-4fa0-a9cf-568d130796c3",
                                "name": "Group 2-Updated"
                            }
                        ],
                        "itemsCount": 1,
                        "total": 1
                    },
                    "id": "9f59b08a-2cfd-476a-af9e-f1c039284c09",
                    "name": "Lightning-nlr7f2n6zd\\Lightning",
                    "source": {
                        "type": "custom"
                    },
                    "tenant": {
                        "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                    }
                }
            ]
        }
    }
}

Human Readable Output

Total Records: 4

Page: 1/1

Listed 4 User(s) in Usergroup:

id name email
86e0ae0f-77ef-423a-bbbf-d95e49edd468 Administrator ruqdxvd1g7@lightning.example.com
c1552a7b-efe9-4a45-8168-72489e44a3f3 Lightning-8483qawudl\Lightning  
69d3d421-f4cc-4a24-b093-8b2e5c6d20a4 Lightning-gm4vu3jxek\Lightning  
9f59b08a-2cfd-476a-af9e-f1c039284c09 Lightning-nlr7f2n6zd\Lightning  

sophos-central-usergroups-get


Returns the details of the GroupID specified.

Base Command

sophos-central-usergroups-get

Input

Argument Name Description Required
groupId Unique ID of the group whose details to be retrieved (You can retrieve the group ID from the sophos-central-usergroups-list). Required

Context Output

Path Type Description
SophosCentral.UserGroups.id String Group ID.
SophosCentral.UserGroups.name String Group name.
SophosCentral.UserGroups.displayName String Group display name.
SophosCentral.UserGroups.description String Group description.
SophosCentral.UserGroups.groups.total Number Count of total groups.
SophosCentral.UserGroups.groups.itemsCount Number Count of items.
SophosCentral.UserGroups.source.type String Types of sources of directory information. All users and groups created using this API have the source type custom. All users and groups synced from Active Directory or Entra ID have the source type activeDirectory or azureActiveDirectory. The following values are allowed: custom, activeDirectory, azureActiveDirectory
SophosCentral.UserGroups.usersTotal Number Total count of users.
SophosCentral.UserGroups.usersItemsCount Number Count of items.
SophosCentral.UserGroups.users.id String User ID.
SophosCentral.UserGroups.users.name String User Name.
SophosCentral.UserGroups.tenant.id String Tenant ID.
SophosCentral.UserGroups.createdAt Date When the group was created.
SophosCentral.UserGroups.updatedAt Date When the group was last updated.

Command example

!sophos-central-usergroups-get groupId="733cce06-5ad0-487b-9547-03af02b5722e"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "createdAt": "2022-10-06T06:19:13.462Z",
            "description": "NewDescriptionReadMe",
            "displayName": "NewGroupNameReadMe",
            "groups": {
                "items": [],
                "itemsCount": 0,
                "total": 0
            },
            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
            "name": "NewGroupNameReadMe",
            "source": {
                "type": "custom"
            },
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "updatedAt": "2022-10-06T06:42:24.713Z",
            "users": [
                {
                    "id": "f9029e98-311a-4c19-9908-15bafff9f39f",
                    "name": "Domain\\User"
                },
                {
                    "id": "09c515b2-009e-4e78-a83f-a5423e6def9a",
                    "name": "GREEN\\testUser"
                },
                {
                    "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                    "name": "Administrator"
                },
                {
                    "id": "1e6754d7-08a5-46e5-a6c1-006a96d4eb48",
                    "name": "Group 04/10/22"
                }
            ],
            "usersItemsCount": 4,
            "usersTotal": 4
        }
    }
}

Human Readable Output

Found User Groups

id name description sourceType
733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe NewDescriptionReadMe custom

sophos-central-usergroups-create


Creates a new “custom” (Centrally Managed) Group

Base Command

sophos-central-usergroups-create

Input

Argument Name Description Required
groupName Provide a unique name of the group to create a usergroup in a directory. Required
description Description of the user group. Optional
userIds Comma-separated list of User UUIDs. Maximum 1000 unique User IDs are allowed (You can retrieve the userIds from the sophos-central-users-list). Optional

Context Output

Path Type Description
SophosCentral.UserGroups.id String Group ID.
SophosCentral.UserGroups.name String Group name.
SophosCentral.UserGroups.displayName String Group display name.
SophosCentral.UserGroups.description String Group description.
SophosCentral.UserGroups.groups.total Number Total count of groups.
SophosCentral.UserGroups.groups.itemsCount Number Count of items.
SophosCentral.UserGroups.source.type String Types of sources of directory information. All users and groups created using this API have the source type custom. All users and groups synced from Active Directory or Entra ID have the source type activeDirectory or azureActiveDirectory. The following values are allowed: custom, activeDirectory, azureActiveDirectory
SophosCentral.UserGroups.usersTotal Number Total count of users.
SophosCentral.UserGroups.usersItemsCount Number Count of items.
SophosCentral.UserGroups.users.id String User ID.
SophosCentral.UserGroups.users.name String User Name.
SophosCentral.UserGroups.tenant.id String Tenant ID.
SophosCentral.UserGroups.createdAt Date When the group was created.
SophosCentral.UserGroups.updatedAt Date When the group was last updated.

Command example

!sophos-central-usergroups-create groupName=GroupNameTestReadMe groupDescription=GroupDescriptionReadMe userIds="86e0ae0f-77ef-423a-bbbf-d95e49edd468"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "createdAt": "2022-10-06T06:42:22.023Z",
            "id": "03d1fcb2-246e-4307-b570-82dcf9083686",
            "name": "GroupNameTestReadMe",
            "source": {
                "type": "custom"
            },
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "updatedAt": "2022-10-06T06:42:22.023Z",
            "users": [
                {
                    "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                    "name": "Administrator"
                }
            ],
            "usersItemsCount": 1,
            "usersTotal": 1
        }
    }
}

Human Readable Output

Successfully created a user group with ID: 03d1fcb2-246e-4307-b570-82dcf9083686.

sophos-central-usergroups-update


Allows for the editing of the group name and description for a usergroup.

Base Command

sophos-central-usergroups-update

Input

Argument Name Description Required
groupId Unique ID of the group whose details to be updated (You can retrieve the group ID from the sophos-central-usergroups-list). Required
groupName Group Name. Required
description Group Description. Optional

Context Output

Path Type Description
SophosCentral.UserGroups.id String Group ID.
SophosCentral.UserGroups.name String Group name.
SophosCentral.UserGroups.displayName String Group display name.
SophosCentral.UserGroups.description String Group description.
SophosCentral.UserGroups.groups.total Number Total count of groups.
SophosCentral.UserGroups.groups.itemsCount Number Count of items.
SophosCentral.UserGroups.source.type String Types of sources of directory information. All users and groups created using this API have the source type custom. All users and groups synced from Active Directory or Entra ID have the source type activeDirectory or azureActiveDirectory. The following values are allowed: custom, activeDirectory, azureActiveDirectory
SophosCentral.UserGroups.usersTotal Number Total count of users.
SophosCentral.UserGroups.usersItemsCount Number Count of items.
SophosCentral.UserGroups.users.id String User ID.
SophosCentral.UserGroups.users.name String User Name.
SophosCentral.UserGroups.tenant.id String Tenant ID.
SophosCentral.UserGroups.createdAt Date When the group was created.
SophosCentral.UserGroups.updatedAt Date When the group was last updated.

Command example

!sophos-central-usergroups-update groupId="733cce06-5ad0-487b-9547-03af02b5722e" groupName=NewGroupNameReadMe description=NewDescriptionReadMe

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "createdAt": "2022-10-06T06:19:13.462Z",
            "description": "NewDescriptionReadMe",
            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
            "name": "NewGroupNameReadMe",
            "source": {
                "type": "custom"
            },
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "updatedAt": "2022-10-06T06:42:24.713Z",
            "users": [
                {
                    "id": "f9029e98-311a-4c19-9908-15bafff9f39f",
                    "name": "Domain\\User"
                },
                {
                    "id": "09c515b2-009e-4e78-a83f-a5423e6def9a",
                    "name": "GREEN\\testUser"
                },
                {
                    "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                    "name": "Administrator"
                },
                {
                    "id": "1e6754d7-08a5-46e5-a6c1-006a96d4eb48",
                    "name": "Group 04/10/22"
                }
            ],
            "usersItemsCount": 4,
            "usersTotal": 4
        }
    }
}

Human Readable Output

Successfully updated the user group with ID: 733cce06-5ad0-487b-9547-03af02b5722e.

sophos-central-usergroups-delete


Deletes the specified group.

Base Command

sophos-central-usergroups-delete

Input

Argument Name Description Required
groupId Unique id of the usergroup to be deleted. Users in the usergroup should be removed first in order to delete the usergroup (You can retrieve the group ID from the sophos-central-usergroups-list). Required

Context Output

Path Type Description
SophosCentral.DeletedUserGroups.deletedUserGroupId String Deleted Group ID.

Command example

!sophos-central-usergroups-delete groupId="0210d539-66ab-46ac-afa2-eb8928856340"

Context Example

{
    "SophosCentral": {
        "UserGroups": {
            "deletedUserGroupId": "0210d539-66ab-46ac-afa2-eb8928856340"
        }
    }
}

Human Readable Output

Successfully deleted the user group with ID: 0210d539-66ab-46ac-afa2-eb8928856340.

sophos-central-usergroups-list


Returns a list of all user groups that match the search criteria (optional).

Base Command

sophos-central-usergroups-list

Input

Argument Name Description Required
groupsIds Comma separated list of group UUIDs. Optional
search Search for items that match the given terms. Optional
searchFields Search only within the allowed comma-separated field values. When not specified, the default behavior is to search group by names only. The following are Group fields values allowed to be searched:- name,description. Optional
domain List the items that match the given domain. Optional
sourceType Types of sources of directory information. All users and groups created using this API have the source type custom. All users and groups synced from Active Directory or Entra ID have the source type activeDirectory or azureActiveDirectory. The following values are allowed:- custom, activeDirectory, azureActiveDirectory. Possible values are: custom, activeDirectory, azureActiveDirectory. Optional
userId Search groups associated with the given user ID. Optional
page The page number to fetch. Default is “1”. Default is 1. Optional
pageSize Size of the page requested. Default is “50”. Maximum is “100”. Default is 50. Optional

Context Output

Path Type Description
SophosCentral.UserGroups.id String Group ID.
SophosCentral.UserGroups.name String Group name.
SophosCentral.UserGroups.displayName String Group display name.
SophosCentral.UserGroups.description String Group description.
SophosCentral.UserGroups.groups.total Number Total Count of groups.
SophosCentral.UserGroups.groups.itemsCount Number Count of items.
SophosCentral.UserGroups.source.type String Types of sources of directory information. All users and groups created using this API have the source type custom. All users and groups synced from Active Directory or Entra ID have the source type activeDirectory or azureActiveDirectory. The following values are allowed: custom, activeDirectory, azureActiveDirectory
SophosCentral.UserGroups.usersTotal Number Total count of users.
SophosCentral.UserGroups.usersItemsCount Number Count of items.
SophosCentral.UserGroups.users.id String User ID.
SophosCentral.UserGroups.users.name String User Name.
SophosCentral.UserGroups.tenant.id String Tenant ID.
SophosCentral.UserGroups.createdAt Date When the group was created.
SophosCentral.UserGroups.updatedAt Date When the group was last updated.

Command example

!sophos-central-usergroups-list groupsIds="733cce06-5ad0-487b-9547-03af02b5722e, 03d1fcb2-246e-4307-b570-82dcf9083686" search=GroupName searchFields=name,description sourceType=custom userId="86e0ae0f-77ef-423a-bbbf-d95e49edd468" page=1 pageSize=10

Context Example

{
    "SophosCentral": {
        "UserGroups": [
            {
                "createdAt": "2022-10-06T06:42:22.023Z",
                "displayName": "GroupNameTestReadMe",
                "groups": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "03d1fcb2-246e-4307-b570-82dcf9083686",
                "name": "GroupNameTestReadMe",
                "source": {
                    "type": "custom"
                },
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "updatedAt": "2022-10-06T06:42:22.023Z",
                "users": [
                    {
                        "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                        "name": "Administrator"
                    }
                ],
                "usersItemsCount": 1,
                "usersTotal": 1
            },
            {
                "createdAt": "2022-10-06T06:19:13.462Z",
                "description": "NewDescriptionReadMe",
                "displayName": "NewGroupNameReadMe",
                "groups": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                "name": "NewGroupNameReadMe",
                "source": {
                    "type": "custom"
                },
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "updatedAt": "2022-10-06T06:42:24.713Z",
                "users": [
                    {
                        "id": "f9029e98-311a-4c19-9908-15bafff9f39f",
                        "name": "Domain\\User"
                    },
                    {
                        "id": "09c515b2-009e-4e78-a83f-a5423e6def9a",
                        "name": "GREEN\\testUser"
                    },
                    {
                        "id": "86e0ae0f-77ef-423a-bbbf-d95e49edd468",
                        "name": "Administrator"
                    },
                    {
                        "id": "1e6754d7-08a5-46e5-a6c1-006a96d4eb48",
                        "name": "Group 04/10/22"
                    }
                ],
                "usersItemsCount": 4,
                "usersTotal": 4
            }
        ]
    }
}

Human Readable Output

Total Records: 2

Page: 1/1

Listed 2 User Groups:

id name description sourceType
03d1fcb2-246e-4307-b570-82dcf9083686 GroupNameTestReadMe   custom
733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe NewDescriptionReadMe custom

sophos-central-group-membership-get


Get endpoints in a group.

Base Command

sophos-central-group-membership-get

Input

Argument Name Description Required
groupId UUID of Endpoint group ID.(You can retrieve endpoint group-id from sophos-central-group-list command). Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.id String Group ID.
SophosCentral.EndpointGroups.type String Endpoint group types.
SophosCentral.EndpointGroups.tenant.id String Tenant ID.
SophosCentral.EndpointGroups.hostname String Hostname of the endpoint.
SophosCentral.EndpointGroups.os.isServer Boolean Whether the OS is a server OS.
SophosCentral.EndpointGroups.os.platform String OS platform type.
SophosCentral.EndpointGroups.os.name String OS name as reported by the endpoint.
SophosCentral.EndpointGroups.os.majorVersion Number OS major version.
SophosCentral.EndpointGroups.os.minorVersion Number OS minor version.
SophosCentral.EndpointGroups.os.build Number OS build.
SophosCentral.EndpointGroups.ipv4Addresses String List of IPv4 addresses.
SophosCentral.EndpointGroups.ipv6Addresses String List of IPv6 addresses.
SophosCentral.EndpointGroups.macAddresses String List of MAC addresses.
SophosCentral.EndpointGroups.group.name String Endpoint group name.
SophosCentral.EndpointGroups.group.id String Unique ID for endpoint group.
SophosCentral.EndpointGroups.associatedPerson.name String Person’s name.
SophosCentral.EndpointGroups.associatedPerson.viaLogin String Person’s login on the endpoint.
SophosCentral.EndpointGroups.associatedPerson.id String Unique ID for endpoint group.
SophosCentral.EndpointGroups.tamperProtectionEnabled Boolean Whether Tamper Protection is turned on.
SophosCentral.EndpointGroups.lastSeenAt Date Date and time (UTC) when the endpoint last communicated with Sophos Central.

Command example

!sophos-central-group-membership-get groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": [
            {
                "assignedProducts": [],
                "associatedPerson": {
                    "id": "4af78a04-659d-4b68-8ab4-5e1c1bfd7672",
                    "name": "Lightning-efxqeo9t2w\\Lightning",
                    "viaLogin": "Lightning-efxqeo9t2w\\Lightning"
                },
                "group": {
                    "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
                    "name": "Name-readme2-update"
                },
                "hostname": "Lightning-uz1lwmqwqk",
                "id": "1abcf612-d426-457b-8088-10d921112f1b",
                "ipv4Addresses": [
                    "8.8.8.8"
                ],
                "ipv6Addresses": [
                    "fe80::ad60:91b0:95fb:2c22"
                ],
                "lastSeenAt": "2022-07-07T06:35:20.897Z",
                "macAddresses": [
                    "00:50:56:83:08:E2"
                ],
                "os": {
                    "build": 19044,
                    "isServer": false,
                    "majorVersion": 10,
                    "minorVersion": 0,
                    "name": "Windows 10 Enterprise",
                    "platform": "windows"
                },
                "tamperProtectionEnabled": false,
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer"
            },
            {
                "assignedProducts": [],
                "associatedPerson": {
                    "id": "120ca229-fa0d-4aa7-9dec-206b6099e974",
                    "name": "Lightning-pa0tcy4opl\\Lightning",
                    "viaLogin": "Lightning-pa0tcy4opl\\Lightning"
                },
                "group": {
                    "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
                    "name": "Name-readme2-update"
                },
                "hostname": "Lightning-r8s9l77e5g",
                "id": "3413a306-5227-40f1-8b86-53195d927566",
                "ipv4Addresses": [
                    "8.8.8.8"
                ],
                "ipv6Addresses": [
                    "fe80::ad60:91b0:95fb:2c22"
                ],
                "lastSeenAt": "2022-07-07T06:11:57.505Z",
                "macAddresses": [
                    "00:50:56:83:08:E2"
                ],
                "os": {
                    "build": 19044,
                    "isServer": false,
                    "majorVersion": 10,
                    "minorVersion": 0,
                    "name": "Windows 10 Enterprise",
                    "platform": "windows"
                },
                "tamperProtectionEnabled": false,
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer"
            }
        ]
    }
}

Human Readable Output

Fetched 2 Endpoint(s) Successfully

id type hostname
1abcf612-d426-457b-8088-10d921112f1b computer Lightning-uz1lwmqwqk
3413a306-5227-40f1-8b86-53195d927566 computer Lightning-r8s9l77e5g

sophos-central-group-create


Create a new endpoint group.

Base Command

sophos-central-group-create

Input

Argument Name Description Required
name Group name. Required
description Group description. Optional
type Group type. The following values are allowed: computer, server. Possible values are: server, computer. Required
endpointIds Comma-separated list of endpoint IDs. (You can retrieve endpoint IDs from sophos-central-endpoint-list command). Optional

Context Output

Path Type Description
SophosCentral.EndpointGroups.id String Group ID.
SophosCentral.EndpointGroups.name String Group name.
SophosCentral.EndpointGroups.description String Group description.
SophosCentral.EndpointGroups.type String Endpoint group types.
SophosCentral.EndpointGroups.endpoints.total Number Total number of endpoints in this group.
SophosCentral.EndpointGroups.endpoints.itemsCount Number Total number of items in the list.
SophosCentral.EndpointGroups.tenant.id String Tenant ID.
SophosCentral.EndpointGroups.createdAt Date When the group was created.

Command example

!sophos-central-group-create name="Name-readme2" description=description type=computer endpointIds="3413a306-5227-40f1-8b86-53195d927566,1abcf612-d426-457b-8088-10d921112f1b"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "createdAt": "2022-10-06T09:38:16.651Z",
            "description": "description",
            "endpoints": {
                "items": [
                    {
                        "hostname": "Lightning-uz1lwmqwqk",
                        "id": "1abcf612-d426-457b-8088-10d921112f1b"
                    },
                    {
                        "hostname": "Lightning-r8s9l77e5g",
                        "id": "3413a306-5227-40f1-8b86-53195d927566"
                    }
                ],
                "itemsCount": 2,
                "total": 2
            },
            "id": "3ba49c2c-2c05-4e39-8ff4-ed0488fe0a3d",
            "name": "Name-readme2",
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "type": "computer"
        }
    }
}

Human Readable Output

EndpointGroup Created Successfully

id name type
3ba49c2c-2c05-4e39-8ff4-ed0488fe0a3d Name-readme2 computer

sophos-central-group-update


Update an endpoint group.

Base Command

sophos-central-group-update

Input

Argument Name Description Required
name Group name. Optional
description Group description. Optional
groupId UUID of Endpoint group ID. Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.id String Group ID.
SophosCentral.EndpointGroups.name String Group name.
SophosCentral.EndpointGroups.description String Group description.
SophosCentral.EndpointGroups.type String Endpoint group types.
SophosCentral.EndpointGroups.endpoints.total Number Total number of endpoints in this group.
SophosCentral.EndpointGroups.endpoints.itemsCount Number Total number of items in the list.
SophosCentral.EndpointGroups.tenant.id String Tenant ID.
SophosCentral.EndpointGroups.createdAt Date When the group was created.
SophosCentral.EndpointGroups.updatedAt Date When the group was updated.

Command example

!sophos-central-group-update name="Name-readme2-update" groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "createdAt": "2022-10-06T09:16:51.382Z",
            "description": "description",
            "endpoints": {
                "items": [],
                "itemsCount": 0,
                "total": 0
            },
            "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
            "name": "Name-readme2-update",
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "type": "computer",
            "updatedAt": "2022-10-06T09:38:19.776Z"
        }
    }
}

Human Readable Output

EndpointGroup Updated Successfully

id name description
f1ff9020-f101-42c7-a5eb-06e9ef35e7af Name-readme2-update description

sophos-central-group-get


Get an endpoint group by ID.

Base Command

sophos-central-group-get

Input

Argument Name Description Required
groupId UUID of Endpoint group ID. Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.id String Group ID.
SophosCentral.EndpointGroups.name String Group name.
SophosCentral.EndpointGroups.description String Group description.
SophosCentral.EndpointGroups.type String Endpoint group types.
SophosCentral.EndpointGroups.endpoints.total Number Total number of endpoints in this group.
SophosCentral.EndpointGroups.endpoints.itemsCount Number Total number of items in the list.
SophosCentral.EndpointGroups.tenant.id String Tenant ID.
SophosCentral.EndpointGroups.createdAt Date When the group was created.
SophosCentral.EndpointGroups.updatedAt Date When the group was updated.

Command example

!sophos-central-group-get groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "createdAt": "2022-10-06T09:16:51.382Z",
            "description": "description",
            "endpoints": {
                "items": [],
                "itemsCount": 0,
                "total": 0
            },
            "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
            "name": "Name-readme2-update",
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "type": "computer",
            "updatedAt": "2022-10-06T09:38:19.776Z"
        }
    }
}

Human Readable Output

Fetched EndpointGroup Successfully

description name
description Name-readme2-update

sophos-central-group-endpoints-add


Add endpoints in a group.

Base Command

sophos-central-group-endpoints-add

Input

Argument Name Description Required
groupId UUID of Endpoint group ID.(You can retrieve endpoint group-id from sophos-central-group-list command). Required
endpointIds Comma-separated list of endpoint IDs. (You can retrieve endpoint IDs from sophos-central-endpoint-list command). Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.endpoints.id String Unique endpoint ID.
SophosCentral.EndpointGroups.endpoints.hostname String Endpoint hostname.
SophosCentral.EndpointGroups.id String Unique group ID.

Command example

!sophos-central-group-endpoints-add groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af" ids="3413a306-5227-40f1-8b86-53195d927566,1abcf612-d426-457b-8088-10d921112f1b"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "endpoints": [
                {
                    "hostname": "Lightning-r8s9l77e5g",
                    "id": "3413a306-5227-40f1-8b86-53195d927566"
                },
                {
                    "hostname": "Lightning-uz1lwmqwqk",
                    "id": "1abcf612-d426-457b-8088-10d921112f1b"
                }
            ],
            "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af"
        }
    }
}

Human Readable Output

2 Endpoint(s) Added Successfully

id hostname
3413a306-5227-40f1-8b86-53195d927566 Lightning-r8s9l77e5g
1abcf612-d426-457b-8088-10d921112f1b Lightning-uz1lwmqwqk

sophos-central-group-endpoint-remove


Remove endpoint from a group.

Base Command

sophos-central-group-endpoint-remove

Input

Argument Name Description Required
groupId UUID of Endpoint group ID.(You can retrieve endpoint group-id from sophos-central-group-list command). Required
endpointId Comma-separated list of endpoint IDs. (You can retrieve endpoint IDs from sophos-central-endpoint-list command). Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.removedEndpoint Boolean EndpointId of removed endpoint.
SophosCentral.EndpointGroups.id String Group Id.

Command example

!sophos-central-group-endpoint-remove groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af" endpointId="3413a306-5227-40f1-8b86-53195d927566"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
            "removedEndpoint": "3413a306-5227-40f1-8b86-53195d927566"
        }
    }
}

Human Readable Output

Endpoint removed successfully

sophos-central-group-endpoints-remove


Remove endpoints from a group.

Base Command

sophos-central-group-endpoints-remove

Input

Argument Name Description Required
groupId UUID of Endpoint group ID.(You can retrieve endpoint group-id from sophos-central-group-list command). Required
endpointIds Comma-separated list of endpoint IDs. (You can retrieve endpoint IDs from sophos-central-endpoint-list command). Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.endpoints.id String Unique endpoint ID.
SophosCentral.EndpointGroups.endpoints.hostname String Endpoint hostname.
SophosCentral.EndpointGroups.id String Unique group ID.
SophosCentral.EndpointGroups.removedEndpoints String List of removed EndpointIds from the group.

Command example

!sophos-central-group-endpoints-remove groupId="f1ff9020-f101-42c7-a5eb-06e9ef35e7af" ids="3413a306-5227-40f1-8b86-53195d927566,1abcf612-d426-457b-8088-10d921112f1b"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "endpoints": [
                {
                    "hostname": "Lightning-uz1lwmqwqk",
                    "id": "1abcf612-d426-457b-8088-10d921112f1b"
                }
            ],
            "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
            "removedEndpoints": "3413a306-5227-40f1-8b86-53195d927566,1abcf612-d426-457b-8088-10d921112f1b"
        }
    }
}

Human Readable Output

1 EndPoint(s) Removed Successfully

id hostname
1abcf612-d426-457b-8088-10d921112f1b Lightning-uz1lwmqwqk

sophos-central-group-list


List endpoint groups.

Base Command

sophos-central-group-list

Input

Argument Name Description Required
page_size The maximum size of the page requested. Default is “50”. Maximum is “1000”. Default is 50. Optional
page Page number to return. Default is “1”. Default is 1. Optional

Context Output

Path Type Description
SophosCentral.EndpointGroups.id String Group ID.
SophosCentral.EndpointGroups.name String Group name.
SophosCentral.EndpointGroups.type String Endpoint group types.
SophosCentral.EndpointGroups.endpoints.total Number Total number of endpoints in this group.
SophosCentral.EndpointGroups.endpoints.itemsCount Number Total number of items in the list.
SophosCentral.EndpointGroups.tenant.id String Tenant ID.
SophosCentral.EndpointGroups.createdAt Date When the group was created.
SophosCentral.EndpointGroups.description String Group description.

Command example

!sophos-central-group-list page_size=10

Context Example

{
    "SophosCentral": {
        "EndpointGroups": [
            {
                "createdAt": "2022-10-06T09:06:16.825Z",
                "description": "description",
                "endpoints": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "b8c0428e-a422-4db6-a72f-5af4844ed418",
                "name": "Name-readme",
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer"
            },
            {
                "createdAt": "2022-10-06T09:37:33.566Z",
                "description": "description",
                "endpoints": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "b3dec702-5d56-4cb9-8961-b0dba3194c94",
                "name": "Name-readme-temp",
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer"
            },
            {
                "createdAt": "2022-10-06T09:38:16.651Z",
                "description": "description",
                "endpoints": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "3ba49c2c-2c05-4e39-8ff4-ed0488fe0a3d",
                "name": "Name-readme2",
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer",
                "updatedAt": "2022-10-06T09:38:27.895Z"
            },
            {
                "createdAt": "2022-10-06T09:16:51.382Z",
                "description": "description",
                "endpoints": {
                    "items": [],
                    "itemsCount": 0,
                    "total": 0
                },
                "id": "f1ff9020-f101-42c7-a5eb-06e9ef35e7af",
                "name": "Name-readme2-update",
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "type": "computer",
                "updatedAt": "2022-10-06T09:38:32.519Z"
            }
        ]
    }
}

Human Readable Output

Found 4 records

Page : 1/1

Listed 4 EndpointGroups:

id name type count
b8c0428e-a422-4db6-a72f-5af4844ed418 Name-readme computer 0
b3dec702-5d56-4cb9-8961-b0dba3194c94 Name-readme-temp computer 0
3ba49c2c-2c05-4e39-8ff4-ed0488fe0a3d Name-readme2 computer 0
f1ff9020-f101-42c7-a5eb-06e9ef35e7af Name-readme2-update computer 0

sophos-central-group-delete


Delete an endpoint group by ID.

Base Command

sophos-central-group-delete

Input

Argument Name Description Required
groupId UUID of Endpoint group ID.(You can retrieve endpoint group-id from sophos-central-group-list command). Required

Context Output

Path Type Description
SophosCentral.EndpointGroups.deleted Boolean Endpoint group deleted.
SophosCentral.EndpointGroups.id String Group Id.

Command example

!sophos-central-group-delete groupId="b3dec702-5d56-4cb9-8961-b0dba3194c94"

Context Example

{
    "SophosCentral": {
        "EndpointGroups": {
            "deleted": true,
            "id": "b3dec702-5d56-4cb9-8961-b0dba3194c94"
        }
    }
}

Human Readable Output

EndpointGroup Deleted Successfully

sophos-central-users-list


List users for the given tenant.

Base Command

sophos-central-users-list

Input

Argument Name Description Required
pageSize The maximum number of items to return. Default is “50”. Maximum is “100”. Default is 50. Optional
page Page number to return. Default is “1”. Default is 1. Optional
search Search for items that match the given terms. Optional
searchFields Search only within the specified comma-seperated field values. The following values are allowed: name, firstName, lastName, email, exchangeLogin When not specified, the default behavior is to search the full names of users, only. Optional
sourceType Types of sources of directory information. The following values are allowed: custom, activeDirectory, azureActiveDirectory. Possible values are: custom, activeDirectory, azureActiveDirectory. Optional
groupId Search for users in a group that has this ID (You can get the group ID from sophos-central-usergroups-list command). Optional
domain List the items that match the given domain. Optional

Context Output

Path Type Description
SophosCentral.Users.id String User ID.
SophosCentral.Users.name String User’s name.
SophosCentral.Users.firstName String User’s first name or given name.
SophosCentral.Users.lastName String User’s last name or surname.
SophosCentral.Users.email String User’s email address.
SophosCentral.Users.groups.total Number Total users
SophosCentral.Users.groups.itemsCount Number Total number of groups in which user is exists.
SophosCentral.Users.groups.items.id string Group ID.
SophosCentral.Users.groups.items.name string Group name.
SophosCentral.Users.groups.items.displayName string Group display name.
SophosCentral.Users.tenant.id String Tenant ID.
SophosCentral.Users.source.type String SourceType of the user.
SophosCentral.Users.createdAt Date When the user was created.

Command example

!sophos-central-users-list searchFields="firstname, lastname, email" search="playbook" pageSize=5

Context Example

{
    "SophosCentral": {
        "Users": [
            {
                "createdAt": "2022-10-10T12:30:57.876Z",
                "email": "updatedemail.forplaybook@playbook.com",
                "exchangeLogin": "",
                "firstName": "updatedPlaybook",
                "groups": {
                    "items": [
                        {
                            "displayName": "NewGroupNameReadMe",
                            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                            "name": "NewGroupNameReadMe"
                        }
                    ],
                    "itemsCount": 1,
                    "total": 1
                },
                "id": "4c994c63-c252-4ac9-8840-bcccb095d5a2",
                "lastName": "updatedTest",
                "name": "playbook test",
                "source": {
                    "type": "custom"
                },
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "updatedAt": "2022-10-10T12:41:24.568Z"
            },
            {
                "createdAt": "2022-10-10T12:31:46.606Z",
                "email": "email.forplaybook1@playbook.com",
                "exchangeLogin": "",
                "firstName": "playbook",
                "groups": {
                    "items": [
                        {
                            "displayName": "NewGroupNameReadMe",
                            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                            "name": "NewGroupNameReadMe"
                        }
                    ],
                    "itemsCount": 1,
                    "total": 1
                },
                "id": "111a4a5c-4c9e-449e-88fb-19a2ce5752c6",
                "lastName": "test",
                "name": "playbook test",
                "source": {
                    "type": "custom"
                },
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "updatedAt": "2022-10-10T12:31:46.609Z"
            },
            {
                "createdAt": "2022-10-10T12:48:23.980Z",
                "email": "email.forplaybook2@playbook.com",
                "exchangeLogin": "",
                "firstName": "playbook",
                "groups": {
                    "items": [
                        {
                            "displayName": "NewGroupNameReadMe",
                            "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                            "name": "NewGroupNameReadMe"
                        }
                    ],
                    "itemsCount": 1,
                    "total": 1
                },
                "id": "f6032b13-f001-4bae-adf2-a0fb6f344fbd",
                "lastName": "test",
                "name": "playbook test",
                "source": {
                    "type": "custom"
                },
                "tenant": {
                    "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
                },
                "updatedAt": "2022-10-10T12:48:23.982Z"
            }
        ]
    }
}

Human Readable Output

Total Records: 3

Page: 1/1

Listed 3 User(s):

id firstName lastName email groupIds groupNames
4c994c63-c252-4ac9-8840-bcccb095d5a2 updatedPlaybook updatedTest updatedemail.forplaybook@playbook.com 733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe
111a4a5c-4c9e-449e-88fb-19a2ce5752c6 playbook test email.forplaybook1@playbook.com 733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe
f6032b13-f001-4bae-adf2-a0fb6f344fbd playbook test email.forplaybook2@playbook.com 733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe

sophos-central-users-get


List user with userId for the given tenant.

Base Command

sophos-central-users-get

Input

Argument Name Description Required
userId Unique User UUID (You can get the user ID from sophos-central-users-list command). Required

Context Output

Path Type Description
SophosCentral.Users.id String User ID.
SophosCentral.Users.name String User’s name.
SophosCentral.Users.firstName String User’s first name or given name.
SophosCentral.Users.lastName String User’s last name or surname.
SophosCentral.Users.email String User’s email address.
SophosCentral.Users.groups.total Number Total users.
SophosCentral.Users.groups.itemsCount Number Total number of groups in which user is exists.
SophosCentral.Users.groups.items.id string Group ID.
SophosCentral.Users.groups.items.name string Group name.
SophosCentral.Users.groups.items.displayName string Group display name.
SophosCentral.Users.tenant.id String Tenant ID.
SophosCentral.Users.source.type String SourceType of the user.
SophosCentral.Users.createdAt Date When the user was created.
SophosCentral.Users.updatedAt Date When the user was updated.

Command example

!sophos-central-users-get userId=4c994c63-c252-4ac9-8840-bcccb095d5a2

Context Example

{
    "SophosCentral": {
        "Users": {
            "email": "updatedemail.forplaybook@playbook.com",
            "exchangeLogin": "",
            "firstName": "updatedPlaybook",
            "groupIds": [
                "733cce06-5ad0-487b-9547-03af02b5722e"
            ],
            "groupNames": [
                "NewGroupNameReadMe"
            ],
            "id": "4c994c63-c252-4ac9-8840-bcccb095d5a2",
            "lastName": "updatedTest"
        }
    }
}

Human Readable Output

Found User

id firstName lastName email exchangeLogin groupIds groupNames
4c994c63-c252-4ac9-8840-bcccb095d5a2 updatedPlaybook updatedTest updatedemail.forplaybook@playbook.com   733cce06-5ad0-487b-9547-03af02b5722e NewGroupNameReadMe

sophos-central-users-add


Add a new user.

Base Command

sophos-central-users-add

Input

Argument Name Description Required
firstName First Name of the user. This must not include a space. Maximum length should be 250 characters. Required
lastName Last Name of the user. This must not include a space. Maximum length should be 250 characters. Required
email Email Address of the user. Required
exchangeLogin Exchange Login for the user. Optional
groupIds Comma-separated list of GroupIds to be enrolled in (You can get the list of user IDs from sophos-central-usergroups-list command). Optional

Context Output

Path Type Description
SophosCentral.Users.id String User ID.
SophosCentral.Users.name String User’s name.
SophosCentral.Users.firstName String User’s first name or given name.
SophosCentral.Users.lastName String User’s last name or surname.
SophosCentral.Users.email String User’s email address.
SophosCentral.Users.groups.total Number Total users.
SophosCentral.Users.groups.itemsCount Number Total number of groups in which user is exists.
SophosCentral.Users.groups.items.id string Group ID.
SophosCentral.Users.groups.items.name string Group name.
SophosCentral.Users.groups.items.displayName string Group display name.
SophosCentral.Users.tenant.id String Tenant ID.
SophosCentral.Users.source.type String SourceType of the user.
SophosCentral.Users.createdAt Date When the user was created.
SophosCentral.Users.updatedAt Date When the user was updated.

Command example

!sophos-central-users-add firstName=playbook lastName=test email=email.forplaybook2@playbook.com groupIds=733cce06-5ad0-487b-9547-03af02b5722e

Context Example

{
    "SophosCentral": {
        "Users": {
            "createdAt": "2022-10-10T12:48:23.980Z",
            "email": "email.forplaybook2@playbook.com",
            "exchangeLogin": "",
            "firstName": "playbook",
            "groups": {
                "items": [
                    {
                        "displayName": "NewGroupNameReadMe",
                        "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                        "name": "NewGroupNameReadMe"
                    }
                ],
                "itemsCount": 1,
                "total": 1
            },
            "id": "f6032b13-f001-4bae-adf2-a0fb6f344fbd",
            "lastName": "test",
            "name": "playbook test",
            "source": {
                "type": "custom"
            },
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "updatedAt": "2022-10-10T12:48:23.982Z"
        }
    }
}

Human Readable Output

A new User was added to the Directory.

sophos-central-users-update


Update a user.

Base Command

sophos-central-users-update

Input

Argument Name Description Required
userId Unique User UUID (You can get the user ID from sophos-central-users-list command). Required
name User’s fullname. Optional
firstName First Name of the user. This must not include a space. Maximum length should be 250 characters. Optional
lastName Last Name of the user. This must not include a space. Maximum length should be 250 characters. Optional
email Email Address of the user. Optional
exchangeLogin Exchange Login for the user. Optional

Context Output

Path Type Description
SophosCentral.Users.id String User ID.
SophosCentral.Users.name String User’s name.
SophosCentral.Users.firstName String User’s first name or given name.
SophosCentral.Users.lastName String User’s last name or surname.
SophosCentral.Users.email String User’s email address.
SophosCentral.Users.groups.total Number Total users.
SophosCentral.Users.groups.itemsCount Number Total number of groups in which user is exists.
SophosCentral.Users.groups.items.id string Group ID.
SophosCentral.Users.groups.items.name string Group name.
SophosCentral.Users.groups.items.displayName string Group display name.
SophosCentral.Users.tenant.id String Tenant ID.
SophosCentral.Users.source.type String SourceType of the user.
SophosCentral.Users.createdAt Date When the user was created.
SophosCentral.Users.updatedAt Date When the user was updated.

Command example

!sophos-central-users-update userId=4c994c63-c252-4ac9-8840-bcccb095d5a2 firstName="updatedPlaybook" lastName="updatedTest" email="updatedemail.forplaybook@playbook.com"

Context Example

{
    "SophosCentral": {
        "Users": {
            "createdAt": "2022-10-10T12:30:57.876Z",
            "email": "updatedemail.forplaybook@playbook.com",
            "exchangeLogin": "",
            "firstName": "updatedPlaybook",
            "groups": {
                "items": [
                    {
                        "displayName": "NewGroupNameReadMe",
                        "id": "733cce06-5ad0-487b-9547-03af02b5722e",
                        "name": "NewGroupNameReadMe"
                    }
                ],
                "itemsCount": 1,
                "total": 1
            },
            "id": "4c994c63-c252-4ac9-8840-bcccb095d5a2",
            "lastName": "updatedTest",
            "name": "playbook test",
            "source": {
                "type": "custom"
            },
            "tenant": {
                "id": "7fc4a6ac-0aa1-4c35-8d6d-9c4a0c28ec80"
            },
            "updatedAt": "2022-10-10T12:41:24.568Z"
        }
    }
}

Human Readable Output

User updated.

sophos-central-users-delete


Delete a user.

Base Command

sophos-central-users-delete

Input

Argument Name Description Required
userId Unique User UUID (You can get user ID from sophos-central-users-list command). Required

Context Output

Path Type Description
SophosCentral.DeletedUsers.deletedUserId String Deleted User’s Id.

Command example

!sophos-central-users-delete userId=9d79e670-3846-45b7-a119-12ca1ee46933

Context Example

{
    "SophosCentral": {
        "DeletedUsers": {
            "deletedUserId": "9d79e670-3846-45b7-a119-12ca1ee46933"
        }
    }
}

Human Readable Output

User deleted.

sophos-central-endpoint-policy-search


Get all endpoint policy.

Base Command

sophos-central-endpoint-policy-search

Input

Argument Name Description Required
page_size The maximum size of the page requested. Default is “50”. Maximum is “200”. Default is 50. Optional
page Page number to return. Default is “1”. Default is 1. Optional
policy_type Fetch the policies based on policy_type value. Possible values are: “threat-protection”, “peripheral-control”, “application-control”, “data-loss-prevention”, “device-encryption”, “web-control”, “agent-updating”, “windows-firewall”, “server-threat-protection”, “server-peripheral-control”, “server-application-control”, “server-web-control”, “server-lockdown”, “server-data-loss-prevention”, “server-agent-updating”, “server-windows-firewall”, “server-file-integrity-monitoring”. Possible values are: threat-protection, peripheral-control, application-control, data-loss-prevention, device-encryption, web-control, agent-updating, windows-firewall, server-threat-protection, server-peripheral-control, server-application-control, server-web-control, server-lockdown, server-data-loss-prevention, server-agent-updating, server-windows-firewall, server-file-integrity-monitoring. Optional

Context Output

Path Type Description  
SophosCentral.PolicyAndEnumeration.id String Policy ID  
SophosCentral.PolicyAndEnumeration.feature String Feature  
SophosCentral.PolicyAndEnumeration.settings String Settings  
SophosCentral.PolicyAndEnumeration.orderPriority String Order priority  
SophosCentral.PolicyAndEnumeration.name String Name  
SophosCentral.PolicyAndEnumeration.enforced Boolean Enforced (T F)
SophosCentral.PolicyAndEnumeration.typeSingle String Type Single  
SophosCentral.PolicyAndEnumeration.typeGroup String Type Group  
SophosCentral.PolicyAndEnumeration.lastModified String Last Modified  

Command example

!sophos-central-endpoint-policy-search page_size=10 page=1

Context Example

{
    "SophosCentral": {
        "PolicyAndEnumeration": [
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "67074d6e-ce83-40c2-a7f4-8a94a1beac10",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 3)",
                "orderPriority": 9,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "b3715f16-b675-4978-927d-2e0fb206b6e9",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 3)",
                "orderPriority": 8,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "e4a9ec1e-a5e3-4072-825f-701b8e1e33fe",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 3)",
                "orderPriority": 7,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "df3bdaa7-c156-4580-baa6-30e2bf118502",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 2)",
                "orderPriority": 6,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "c4887d95-d099-4ae1-9290-1fe316a24d59",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned)",
                "orderPriority": 5,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "a18aafe1-eb86-46c0-ba2f-1f64f1e5b16e",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 2)",
                "orderPriority": 4,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "694f8591-217c-44a0-99f1-f7331bf1bf33",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "12",
                "orderPriority": 3,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "09eff4b3-14f1-4a42-a47c-c0382066d094",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned 2)",
                "orderPriority": 2,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": false,
                "feature": "agent-updating",
                "id": "875166af-1848-463a-a853-bed673cad119",
                "lastModified": "2022-10-11T06:13:07.146Z",
                "name": "Base Policy (cloned)",
                "orderPriority": 1,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            },
            {
                "enforced": true,
                "feature": "agent-updating",
                "id": "3f863d0a-4405-4c6d-a035-4215db53b087",
                "lastModified": "2022-05-07T01:16:26.767Z",
                "name": "Base Policy",
                "orderPriority": 0,
                "settings": {
                    "endpoint.agent-updating.dont-use-update-caches.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.fixed-version.mac": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.fixed-version.windows": {
                        "value": "recommended"
                    },
                    "endpoint.agent-updating.scheduled-updates.day": {
                        "unit": "day",
                        "value": 3
                    },
                    "endpoint.agent-updating.scheduled-updates.enabled": {
                        "value": false
                    },
                    "endpoint.agent-updating.scheduled-updates.time": {
                        "format": "hourMinute",
                        "value": "14:00"
                    }
                }
            }
        ]
    }
}

Human Readable Output

Total Record(s): 24

Current page: 1/3

Listed 10 Endpoint Policies

id feature settings orderPriority name enforced typeSingle typeGroup lastModified
67074d6e-ce83-40c2-a7f4-8a94a1beac10 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
9 Base Policy (cloned 3) false     2022-10-11T06:13:07.146Z
b3715f16-b675-4978-927d-2e0fb206b6e9 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
8 Base Policy (cloned 3) false     2022-10-11T06:13:07.146Z
e4a9ec1e-a5e3-4072-825f-701b8e1e33fe agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
7 Base Policy (cloned 3) false     2022-10-11T06:13:07.146Z
df3bdaa7-c156-4580-baa6-30e2bf118502 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
6 Base Policy (cloned 2) false     2022-10-11T06:13:07.146Z
c4887d95-d099-4ae1-9290-1fe316a24d59 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
5 Base Policy (cloned) false     2022-10-11T06:13:07.146Z
a18aafe1-eb86-46c0-ba2f-1f64f1e5b16e agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
4 Base Policy (cloned 2) false     2022-10-11T06:13:07.146Z
694f8591-217c-44a0-99f1-f7331bf1bf33 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
3 12 false     2022-10-11T06:13:07.146Z
09eff4b3-14f1-4a42-a47c-c0382066d094 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
2 Base Policy (cloned 2) false     2022-10-11T06:13:07.146Z
875166af-1848-463a-a853-bed673cad119 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
1 Base Policy (cloned) false     2022-10-11T06:13:07.146Z
3f863d0a-4405-4c6d-a035-4215db53b087 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
0 Base Policy true     2022-05-07T01:16:26.767Z

sophos-central-endpoint-policy-get


Get details of Policy by id.

Base Command

sophos-central-endpoint-policy-get

Input

Argument Name Description Required
policy_id The policy ID. You can find the policy_id by executing the sophos-central-endpoint-policy-search command. Required

Context Output

Path Type Description  
SophosCentral.PolicyAndEnumeration.id String Policy ID  
SophosCentral.PolicyAndEnumeration.feature String Feature  
SophosCentral.PolicyAndEnumeration.settings String Settings  
SophosCentral.PolicyAndEnumeration.orderPriority String Order priority  
SophosCentral.PolicyAndEnumeration.name String Name  
SophosCentral.PolicyAndEnumeration.enforced Boolean Enforced (T F)
SophosCentral.PolicyAndEnumeration.typeSingle String Type Single  
SophosCentral.PolicyAndEnumeration.typeGroup String Type Group  
SophosCentral.PolicyAndEnumeration.lastModified String Last Modified  

Command example

!sophos-central-endpoint-policy-get policy_id=67074d6e-ce83-40c2-a7f4-8a94a1beac10

Context Example

{
    "SophosCentral": {
        "PolicyAndEnumeration": {
            "enforced": false,
            "feature": "agent-updating",
            "id": "67074d6e-ce83-40c2-a7f4-8a94a1beac10",
            "lastModified": "2022-10-11T06:13:07.146Z",
            "name": "Base Policy (cloned 3)",
            "orderPriority": 9,
            "settings": {
                "endpoint.agent-updating.dont-use-update-caches.enabled": {
                    "value": false
                },
                "endpoint.agent-updating.fixed-version.mac": {
                    "value": "recommended"
                },
                "endpoint.agent-updating.fixed-version.windows": {
                    "value": "recommended"
                },
                "endpoint.agent-updating.scheduled-updates.day": {
                    "unit": "day",
                    "value": 3
                },
                "endpoint.agent-updating.scheduled-updates.enabled": {
                    "value": false
                },
                "endpoint.agent-updating.scheduled-updates.time": {
                    "format": "hourMinute",
                    "value": "14:00"
                }
            }
        }
    }
}

Human Readable Output

67074d6e-ce83-40c2-a7f4-8a94a1beac10 Policy Details

id feature settings orderPriority name enforced typeSingle typeGroup lastModified
67074d6e-ce83-40c2-a7f4-8a94a1beac10 agent-updating endpoint.agent-updating.dont-use-update-caches.enabled: {“value”: false}
endpoint.agent-updating.fixed-version.mac: {“value”: “recommended”}
endpoint.agent-updating.fixed-version.windows: {“value”: “recommended”}
endpoint.agent-updating.scheduled-updates.day: {“value”: 3, “unit”: “day”}
endpoint.agent-updating.scheduled-updates.enabled: {“value”: false}
endpoint.agent-updating.scheduled-updates.time: {“value”: “14:00”, “format”: “hourMinute”}
9 Base Policy (cloned 3) false     2022-10-11T06:13:07.146Z

sophos-central-endpoint-policy-reorder


Update Policy priority for non-base policies.

Base Command

sophos-central-endpoint-policy-reorder

Input

Argument Name Description Required
policy_id The policy ID. You can find the policy_id by executing the sophos-central-endpoint-policy-search command. Required
priority Update Policy Order priority for non-base policies. Required

Context Output

Path Type Description
SophosCentral.PolicyAndEnumeration.updatedPolicyId String The ID of the updated policy.

Command example

!sophos-central-endpoint-policy-reorder policy_id=67074d6e-ce83-40c2-a7f4-8a94a1beac10 priority=1

Context Example

{
    "SophosCentral": {
        "PolicyAndEnumeration": {
            "updatedPolicyId": "67074d6e-ce83-40c2-a7f4-8a94a1beac10"
        }
    }
}

Human Readable Output

Success updating endpoint policy: 67074d6e-ce83-40c2-a7f4-8a94a1beac10

sophos-central-endpoint-policy-search-delete


Delete an existing endpoint policy.

Base Command

sophos-central-endpoint-policy-search-delete

Input

Argument Name Description Required
policy_id The policy ID. You can find the policy_id by executing the sophos-central-endpoint-policy-search command. Required

Context Output

Path Type Description
SophosCentral.PolicyAndEnumeration.deletedPolicyId String The ID of the deleted policy.

Command example

!sophos-central-endpoint-policy-search-delete policy_id=67074d6e-ce83-40c2-a7f4-8a94a1beac10

Context Example

{
    "SophosCentral": {
        "PolicyAndEnumeration": {
            "deletedPolicyId": "67074d6e-ce83-40c2-a7f4-8a94a1beac10"
        }
    }
}

Human Readable Output

Success deleting endpoint policy: 67074d6e-ce83-40c2-a7f4-8a94a1beac10

sophos-central-endpoint-policy-clone


Clone an existing endpoint policy.

Base Command

sophos-central-endpoint-policy-clone

Input

Argument Name Description Required
policy_id The policy ID. You can find the policy_id by executing the sophos-central-endpoint-policy-search command. Required
name Policy name of the newly cloned policy. Optional

Context Output

Path Type Description
SophosCentral.PolicyAndEnumeration.clonedPolicyId String The ID of the cloned policy.

Command example

!sophos-central-endpoint-policy-clone policy_id=b3715f16-b675-4978-927d-2e0fb206b6e9 name=testclonenew

Context Example

{
    "SophosCentral": {
        "PolicyAndEnumeration": {
            "clonedPolicyId": "28d9b869-ba28-420f-87da-98a8e1b1656f"
        }
    }
}

Human Readable Output

Success cloning endpoint policy: 28d9b869-ba28-420f-87da-98a8e1b1656f

Configuration parameters

  • credentials — Client ID (required)
  • tenant_id — Tenant ID
  • isFetch — Fetch incidents
  • fetch_severity — Fetch Severity
  • fetch_category — Fetch Category
  • max_fetch — Fetch Limit
  • first_fetch — First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)
  • proxy — Use system proxy settings
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval

Commands (58)

  • sophos-central-alert-action

    Perform an action on the alerts.

  • sophos-central-alert-get

    Get a single alert by ID.

  • sophos-central-alert-list

    List alerts.

  • sophos-central-alert-search

    Get alerts matching request.

  • sophos-central-allowed-item-add

    Add a new allowed item.

  • sophos-central-allowed-item-delete

    Delete an existing allowed item.

  • sophos-central-allowed-item-get

    Get a single allowed item by ID.

  • sophos-central-allowed-item-list

    List all allowed items.

  • sophos-central-allowed-item-update

    Update an existing allowed item.

  • sophos-central-blocked-item-add

    Add a new blocked item.

  • sophos-central-blocked-item-delete

    Delete an existing blocked item.

  • sophos-central-blocked-item-get

    Get a single blocked item by ID.

  • sophos-central-blocked-item-list

    Get all blocked items.

  • sophos-central-deisolate-endpoint

    Initiate de-isolation request on the endpoint(s).

  • sophos-central-detected-exploit-get

    Get a single detected exploit.

  • sophos-central-detected-exploit-list

    List all detected exploits.

  • sophos-central-endpoint-list

    List all endpoints for a tenant.

  • sophos-central-endpoint-policy-clone

    Clone an existing endpoint policy.

  • sophos-central-endpoint-policy-get

    Get details of Policy by id.

  • sophos-central-endpoint-policy-reorder

    Update Policy priority for non-base policies.

  • sophos-central-endpoint-policy-search

    Get all endpoint policy.

  • sophos-central-endpoint-policy-search-delete

    Delete an existing endpoint policy.

  • sophos-central-endpoint-scan

    Scan endpoints of a tenant.

  • sophos-central-endpoint-tamper-get

    Get tamper protection information for one or more endpoints. Potentially harmful because of the password.

  • sophos-central-endpoint-tamper-update

    Update tamper protection information for one or more endpoints. Potentially harmful because of the password.

  • sophos-central-exploit-mitigation-add

    Exclude a set of file paths from exploit mitigation.

  • sophos-central-exploit-mitigation-delete

    Delete a custom (user-defined) Exploit Mitigation application by ID.

  • sophos-central-exploit-mitigation-get

    Get Exploit Mitigation settings for a single application.

  • sophos-central-exploit-mitigation-list

    List exploit mitigation settings for all protected applications.

  • sophos-central-exploit-mitigation-update

    Update Exploit Mitigation settings for an application.

  • sophos-central-group-create

    Create a new endpoint group.

  • sophos-central-group-delete

    Delete an endpoint group by ID.

  • sophos-central-group-endpoint-remove

    Remove endpoint from a group.

  • sophos-central-group-endpoints-add

    Add endpoints in a group.

  • sophos-central-group-endpoints-remove

    Remove endpoints from a group.

  • sophos-central-group-get

    Get an endpoint group by ID.

  • sophos-central-group-list

    List endpoint groups.

  • sophos-central-group-membership-get

    Get endpoints in a group.

  • sophos-central-group-update

    Update an endpoint group.

  • sophos-central-isolate-endpoint

    Initiate isolation request on the endpoint(s).

  • sophos-central-scan-exclusion-add

    Add a new scan exclusion.

  • sophos-central-scan-exclusion-delete

    Delete an existing scan exclusion.

  • sophos-central-scan-exclusion-get

    Get a single scan exclusion by ID.

  • sophos-central-scan-exclusion-list

    List all scan exclusions.

  • sophos-central-scan-exclusion-update

    Update an existing scan exclusion.

  • sophos-central-usergroups-create

    Creates a new “custom” (Centrally Managed) Group.

  • sophos-central-usergroups-delete

    Deletes the specified group.

  • sophos-central-usergroups-get

    Returns the details of the GroupID specified.

  • sophos-central-usergroups-list

    Returns a list of all user groups that match the search criteria (optional).

  • sophos-central-usergroups-membership-get

    List all users in a specific group.

  • sophos-central-usergroups-update

    Allows for the editing of the group name and description for a usergroup.

  • sophos-central-usergroups-user-delete

    Remove a specific User from the group.

  • sophos-central-usergroups-users-add

    Add multiple users to the specified group.

  • sophos-central-users-add

    Add a new user.

  • sophos-central-users-delete

    Delete a user.

  • sophos-central-users-get

    List user with userId for the given tenant.

  • sophos-central-users-list

    List users for the given tenant.

  • sophos-central-users-update

    Update a user.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401
from CommonServerUserPython import *

"""IMPORTS"""
import dateparser

"""GLOBAL VARS"""

DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
COMMON_BASE_URL = "https://api.central.sophos.com"


class Client(BaseClient):
    """Client class, communicates with Sophos Central."""

    def __init__(
        self,
        client_id,
        client_secret,
        verify,
        proxy,
        bearer_token,
        integration_context,
        tenant_id="",
    ):
        """
        Set headers, client_id and client_secret.

        Args:
            client_id (str): Sophos Central client id.
            client_secret (str): Sophos Central client secret.
            verify (bool): takes bool value.
            proxy (bool): takes boolean value.
            bearer_token (str): A JWT token.
        """
        headers, base_url = self.get_client_data(tenant_id, bearer_token)
        super().__init__(base_url=base_url, verify=verify, proxy=proxy, headers=headers)
        self.headers = headers
        self.bearer_token = bearer_token
        self.client_id = client_id
        self.client_secret = client_secret
        self.integration_context = integration_context

    @staticmethod
    def _cache_exists() -> bool:
        """
        Check if the cache exists with base URL and tenant ID.

        Returns:
            _cache_exists (bool): True, if cache has base URL and tenant ID as keys, False otherwise.
        """
        context = get_integration_context()
        return "base_url" in context and "tenant_id" in context

    @staticmethod
    def _whoami(bearer_token: str) -> dict:
        """
        Get the "whoami" API response.

        Args:
            bearer_token (str): JWT token for authentication

        Returns:
            response (dict): whoami API response
        """
        headers = {"Authorization": f"Bearer {bearer_token}"}
        try:
            response = requests.get(f"{COMMON_BASE_URL}/whoami/v1", headers=headers)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as err:
            raise DemistoException(f"An HTTP error occurred while validating the given tenant ID: {str(err)}")
        except requests.exceptions.SSLError as err:
            raise DemistoException(f"SSL Certificate Verification Failed: {str(err)}")
        except requests.exceptions.ProxyError as err:
            err_msg = (
                "Proxy Error - if the 'Use system proxy' checkbox in the integration configuration is"
                " selected, try clearing the checkbox."
            )
            raise DemistoException(err_msg, err)
        except requests.exceptions.ConnectionError as err:
            raise DemistoException(f"Connection error occurred while validating the given tenant ID: {str(err)}")
        except requests.exceptions.Timeout as err:
            raise DemistoException(f"Request timed out while validating the given tenant ID: {str(err)}")
        except requests.exceptions.RequestException as err:
            raise DemistoException(f"An error occurred while making REST API call to validate the given tenant ID: {str(err)}")
        except Exception as err:
            raise DemistoException(f"An error occurred while processing the API response: {str(err)}")

    @staticmethod
    def _get_tenant_base_url(bearer_token: str, entity_id: str, tenant_id: str, creds_type: str) -> str:
        """
        Fetch the tenant base URL.

        Args:
            bearer_token (str): JWT token for authentication
            entity_id (str): Partner or organization ID
            tenant_id (str): Tenant ID for which the base URL is to be fetched
            creds_type (str): Credential type (partner/organization)

        Returns:
            base_url (str): The base URL of given tenant in given partner/organization
        """
        url_suffix = f"{creds_type}/v1/tenants/{tenant_id}"
        headers = {
            f"X-{creds_type.title()}-ID": entity_id,
            "Authorization": f"Bearer {bearer_token}",
        }

        try:
            response = requests.get(f"{COMMON_BASE_URL}/{url_suffix}", headers=headers)

            if response.status_code == 200:
                return response.json().get("apiHost", "")
            elif response.status_code == 404:
                return ""
            response.raise_for_status()
        except requests.exceptions.HTTPError as err:
            raise DemistoException(f"An HTTP error occurred while validating the given tenant ID: {str(err)}")
        except requests.exceptions.SSLError as err:
            raise DemistoException(f"SSL Certificate Verification Failed: {str(err)}")
        except requests.exceptions.ProxyError as err:
            err_msg = (
                "Proxy Error - if the 'Use system proxy' checkbox in the integration configuration is"
                " selected, try clearing the checkbox."
            )
            raise DemistoException(err_msg, err)
        except requests.exceptions.ConnectionError as err:
            raise DemistoException(f"Connection error occurred while validating the given tenant ID: {str(err)}")
        except requests.exceptions.Timeout as err:
            raise DemistoException(f"Request timed out while validating the given tenant ID: {str(err)}")
        except requests.exceptions.RequestException as err:
            raise DemistoException(f"An error occurred while making REST API call to validate the given tenant ID: {str(err)}")
        except Exception as err:
            raise DemistoException(f"An error occurred while processing the API response: {str(err)}")
        return ""

    @staticmethod
    def _update_integration_context(new_context: dict):
        """
        Update the integration context by the new values.

        Args:
            new_context (dict): The new context values to be added to existing context.
        """
        context = get_integration_context()
        context.update(new_context)
        set_integration_context(context)

    @staticmethod
    def get_client_data(tenant_id: str, bearer_token: str) -> tuple[dict, str]:
        """
        Validate the given tenant ID.

        Args:
            tenant_id (str): Tenant ID entered by the user
            bearer_token (str): JWT token for authentication

        Returns:
            headers (dict): Headers object with tenant ID and bearer token.
            base_url (str): Tenant specific regional base URL.
        """
        headers = {"Authorization": f"Bearer {bearer_token}"}

        # compare tenant id with cache
        if Client._cache_exists():
            context = get_integration_context()
            if tenant_id == context.get("tenant_id") or context.get("is_tenant_level", False):
                # this means tenant ID hasn't changed. So use the cache
                headers.update({"X-Tenant-ID": context.get("tenant_id")})
                return headers, context.get("base_url")
            else:
                # this means tenant ID changed, update the cache.
                context.pop("base_url")
                context.pop("tenant_id")
                set_integration_context(context)
                return Client.get_client_data(tenant_id, bearer_token)
        else:
            whoami = Client._whoami(bearer_token)
            creds_type, entity_id, base_url = (
                str(whoami.get("idType")).lower(),
                whoami.get("id", ""),
                whoami.get("apiHosts", {}).get("dataRegion"),
            )
            # if tenant ID is provided even with tenant level credentials and it's different from
            # actual tenant ID, raise error without making API call to validate it.
            if tenant_id and creds_type == "tenant" and tenant_id != entity_id:
                raise DemistoException(
                    "Value provided in tenant ID field is not same as configured tenant whose credentials are entered."
                )
            if tenant_id and creds_type != "tenant":
                # validate the given tenant id for partner or organization entity and get corresponding base url
                base_url = Client._get_tenant_base_url(bearer_token, entity_id, tenant_id, creds_type)
                if base_url:
                    base_url = f"{base_url}/"
                    headers.update({"X-Tenant-ID": tenant_id})
                    # update the cache
                    Client._update_integration_context({"base_url": base_url, "tenant_id": tenant_id})
                    return headers, base_url
                raise DemistoException(
                    f"Value provided in tenant ID is not from managed tenants of "
                    f"configured {creds_type} whose credentials are entered."
                )
            else:
                # validate that the credentials are of tenant level and get the corresponding tenant id.
                if creds_type != "tenant":
                    raise DemistoException(f"Tenant ID field is mandatory to configure {creds_type} user's credential.")

                headers.update({"X-Tenant-ID": entity_id})
                if not base_url:
                    raise DemistoException("Error finding data region.")

                base_url = f"{base_url}/"
                # updatet the cache
                Client._update_integration_context(
                    {
                        "base_url": base_url,
                        "tenant_id": entity_id,
                        "is_tenant_level": True,
                    }
                )
                return headers, base_url

    @staticmethod
    def get_jwt_token_from_api(client_id: str, client_secret: str) -> dict:
        """
        Send an auth request to Sophos Central and receive an access token.

        Args:
            client_id (str): Sophos Central client id.
            client_secret (str): Sophos Central client secret.

        Returns:
            response.json (dict): API response from Sophos.
        """
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        body = {
            "grant_type": "client_credentials",
            "client_id": client_id,
            "client_secret": client_secret,
            "scope": "token",
        }
        response = requests.post(headers=headers, data=body, url="https://id.sophos.com/api/v2/oauth2/token")
        if not response.ok:
            raise DemistoException(response.text)
        return response.json()

    def convert_id_to_name(self, object_mapping_name: str, object_id: str, url_suffix: str, field_key: str) -> str:
        """
        Converts an object id to its name using API.
        Notes:
        * as a performance enhacement, will use integration context as a cache to avoid multiple API calls.
        * Follows the best-effort approach. in case of an error, it will log the error and return an empty string.
        Args:
            object_mapping_name (str): the name of the object mapping.
            object_id (str): the object ID to convert.
            url_suffix (str): the URL endpoint for getting the object info.
            field_key (str): the field key of the name in the API response.
        Returns:
            object name (str): the object name if successful, empty string otherwise.
        """
        try:
            object_mapping = self.integration_context.setdefault(object_mapping_name, {})
            if object_mapping.get(object_id):
                return object_mapping.get(object_id)

            demisto.debug(f"did not find object id in {object_mapping_name} cache, retreiving from API")
            response = self._http_request(
                method="GET",
                url_suffix=url_suffix,
                headers=self.headers,
            )
            object_mapping[object_id] = response.get(field_key, "")
            return object_mapping[object_id]
        except Exception as exc:
            demisto.debug(f"failed to convert the {object_mapping_name} id, Error: {exc}\n{traceback.format_exc()}")
            return ""

    def get_person_name(self, person_id: str) -> str:
        return self.convert_id_to_name(
            "person_mapping",
            person_id,
            f"common/v1/directory/users/{person_id}",
            "name",
        )

    def get_managed_agent_name(self, managed_agent_id: str) -> str:
        return self.convert_id_to_name(
            "managed_agent_mapping",
            managed_agent_id,
            f"endpoint/v1/endpoints/{managed_agent_id}",
            "hostname",
        )

    def list_alert(self, limit: Optional[int]) -> dict:
        """
        List all alerts connected to a tenant.

        Args:
            limit (int): Max number of alerts to return.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements({"pageSize": limit})
        url_suffix = "common/v1/alerts"
        return self._http_request(method="GET", url_suffix=url_suffix, headers=self.headers, params=params)

    def get_alert(self, alert_id: str) -> dict:
        """
        Get a single alert based on ID.

        Args:
            alert_id (str): ID of the alert to get.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"common/v1/alerts/{alert_id}"
        return self._http_request(method="GET", url_suffix=url_suffix, headers=self.headers)

    def action_alert(
        self,
        alert_id: str,
        action: str,
        message: Optional[str],
    ) -> dict:
        """
        Take action against one alert.

        Args:
            alert_id (str): Alert ID to take action against
            action (str): Name of the action to take.
            message (str): Optional message for the action.

        Returns:
            response (Response): API response from Sophos.
        """
        body = remove_empty_elements({"action": action, "message": message})
        url_suffix = f"common/v1/alerts/{alert_id}/actions"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def search_alert(
        self,
        start: Optional[str],
        end: Optional[str],
        product: Optional[List[str]],
        category: Optional[List[str]],
        group_key: Optional[str],
        severity: Optional[List[str]],
        ids: Optional[List[str]],
        limit: Optional[int],
    ) -> dict:
        """
        Search alerts based on parameters.

        Args:
            start (str): Find alerts that were raised on or after this time - Use ISO time format.
            end (str): Find alerts that were raised on or before this time - Use ISO time format.
            product (str): Alerts for a product.
            category (str): Alert category.
            group_key (str): Alerts for a specific severity level.
            severity (str): Alerts for a specific severity level.
            ids (list(str)): List of IDs.
            limit (int): Max number of alerts to return.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {
            "from": start,
            "to": end,
            "product": product,
            "category": category,
            "groupKey": group_key,
            "severity": severity,
            "ids": ids,
            "pageSize": limit,
        }
        body = remove_empty_elements(body)
        url_suffix = "common/v1/alerts/search"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def list_endpoint(
        self,
        health_status: Optional[List[str]],
        endpoint_type: Optional[List[str]],
        tamper_protection_enabled: Optional[bool],
        lockdown_status: Optional[List[str]],
        last_seen_before: Optional[str],
        last_seen_after: Optional[str],
        ids: Optional[List[str]],
        view: Optional[str],
        limit: Optional[int],
        ip_addresses: Optional[List[str]],
        hostname_contains: Optional[str],
    ) -> dict:
        """
        List all endpoints for a tenant.

        Args:
            health_status (list(str)): Endpoints that have any of the specified health status.
            endpoint_type (list(str)): Endpoints that have any of the specified endpoint type.
            tamper_protection_enabled (bool): Tamper protection status.
            lockdown_status (list(str)): Endpoints that have any of the specified lockdown status.
            last_seen_before (str): Last seen before date and time (UTC) or duration exclusive.
            last_seen_after (str): Last seen after date and time (UTC) or duration inclusive.
            ids (list(str)): List of IDs.
            view (str): Type of view to be returned in the response.
            limit (int): Max number of endpoints to return.
            ip_addresses (list(str)): Find endpoints by IP addresses.
            hostname_contains (str): Find endpoints where the hostname contains the given string.
                Only the first 10 characters of the given string are matched.

        Returns:
            response (Response): API response from Sophos.
        """
        params = {
            "healthStatus": health_status,
            "type": endpoint_type,
            "tamperProtectionEnabled": tamper_protection_enabled,
            "lockdownStatus": lockdown_status,
            "lastSeenBefore": last_seen_before,
            "lastSeenAfter": last_seen_after,
            "ids": ids,
            "view": view,
            "pageSize": limit,
            "ipAddresses": ip_addresses,
            "hostnameContains": hostname_contains,
        }
        params = remove_empty_elements(params)
        url_suffix = "endpoint/v1/endpoints"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def scan_endpoint(self, endpoint_id: str) -> dict:
        """
        Initiate a scan on an endpoint.

        Args:
            endpoint_id (str): ID of the endpoint to scan.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/endpoints/{endpoint_id}/scans"
        return self._http_request(method="POST", headers=self.headers, json_data={}, url_suffix=url_suffix)

    def get_tamper(self, endpoint_id: str) -> dict:
        """
        Get tamper protection of an endpoint.

        Args:
            endpoint_id (str): ID of the endpoint to get protection of.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/endpoints/{endpoint_id}/tamper-protection"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def update_tamper(self, endpoint_id: str, enabled: bool) -> dict:
        """
        Get tamper protection of an endpoin.

        Args:
            endpoint_id (str): ID of the endpoint to update protection of.
            enabled(bool): Should the protection be updated to enabled or disabled.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"enabled": enabled}
        url_suffix = f"endpoint/v1/endpoints/{endpoint_id}/tamper-protection"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def list_allowed_item(
        self,
        page_size: Optional[int],
        page: Optional[int],
    ) -> dict:
        """
        List all allowed items for a tenant.

        Args:
            page_size (int): Max number of results per page.
            page (int): Page number to return.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements({"pageSize": page_size, "page": page})
        url_suffix = "endpoint/v1/settings/allowed-items"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_allowed_item(self, allowed_item_id: str) -> dict:
        """
        Get a single allowed item.

        Args:
            allowed_item_id (str): Allowed item ID.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/allowed-items/{allowed_item_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def add_allowed_item(
        self,
        item_type: str,
        comment: str,
        certificate_signer: Optional[str],
        file_name: Optional[str],
        path: Optional[str],
        sha256: Optional[str],
        origin_endpoint_id: Optional[str],
    ) -> dict:
        """
        Add a new allowed item.

        Args:
            comment (str): Comment indicating why the item should be allowed.
            certificate_signer (str): Certificate signer.
            file_name (str): File name to allow.
            path (str): Path of file to allow.
            sha256 (str) SHA256 value for the file.
            item_type (str): type of the item.
            origin_endpoint_id (str): Endpoint ID where the item was last seen.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {
            "comment": comment,
            "originEndpointId": origin_endpoint_id,
            "type": item_type,
            "properties": {
                "fileName": file_name,
                "path": path,
                "sha256": sha256,
                "certificateSigner": certificate_signer,
            },
        }
        body = remove_empty_elements(body)
        url_suffix = "endpoint/v1/settings/allowed-items"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def update_allowed_item(self, allowed_item_id: str, comment: str) -> dict:
        """
        Update an existing allowed item.

        Args:
            allowed_item_id (str): ID of the allowed item to update.
            comment (str): Comment indicating why the item should be allowed.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"comment": comment}
        url_suffix = f"endpoint/v1/settings/allowed-items/{allowed_item_id}"
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def delete_allowed_item(self, allowed_item_id: str) -> dict:
        """
        Delete an existing allowed item.

        Args:
            allowed_item_id (str): ID of the allowed item to update.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/allowed-items/{allowed_item_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def list_blocked_item(
        self,
        page_size: Optional[int],
        page: Optional[int],
    ) -> dict:
        """
        List all blocked items for a tenant.

        Args:
            page_size (int): Max number of results per page.
            page (int): Page number to return.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements({"pageSize": page_size, "page": page})
        url_suffix = "endpoint/v1/settings/blocked-items"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_blocked_item(self, allowed_item_id: str) -> dict:
        """
        Get a single blocked item.

        Args:
            allowed_item_id (str): Allowed item ID.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/blocked-items/{allowed_item_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def add_blocked_item(
        self,
        item_type: str,
        comment: str,
        certificate_signer: Optional[str],
        file_name: Optional[str],
        path: Optional[str],
        sha256: Optional[str],
        origin_endpoint_id: Optional[str],
    ) -> dict:
        """
        Add a new blocked item.

        Args:
            comment (str): Comment indicating why the item should be allowed.
            certificate_signer (str): Certificate signer.
            file_name (str): File name to allow.
            path (str): Path of file to allow.
            sha256 (str) SHA256 value for the file.
            item_type (str): type of the item.
            origin_endpoint_id (str): Endpoint ID where the item was last seen.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {
            "comment": comment,
            "originEndpointId": origin_endpoint_id,
            "type": item_type,
            "properties": {
                "fileName": file_name,
                "path": path,
                "sha256": sha256,
                "certificateSigner": certificate_signer,
            },
        }
        body = remove_empty_elements(body)
        url_suffix = "endpoint/v1/settings/blocked-items"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def delete_blocked_item(self, allowed_item_id: str) -> dict:
        """
        Delete an existing blocked item.

        Args:
            allowed_item_id (str): ID of the allowed item to update.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/blocked-items/{allowed_item_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def list_scan_exclusion(
        self,
        exclusion_type: Optional[str],
        page_size: Optional[int],
        page: Optional[int],
    ) -> dict:
        """
        List all scan exclusions.

        Args:
            exclusion_type (str): Type of scanning exclusions to list.
            page_size (int): Size of the page requested.
            page (int): Number of page to return.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements({"type": exclusion_type, "pageSize": page_size, "page": page})
        url_suffix = "endpoint/v1/settings/exclusions/scanning"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_scan_exclusion(self, exclusion_id: str) -> dict:
        """
        Get a single scan exclusion.

        Args:
            exclusion_id (str): ID of the scan exclusion.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/exclusions/scanning/{exclusion_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def add_scan_exclusion(
        self,
        comment: Optional[str],
        scan_mode: Optional[str],
        exclusion_type: str,
        value: str,
    ) -> dict:
        """
        Add a new scan exclusion.

        Args:
            comment (str): Comment indicating why the exclusion was created.
            scan_mode (str): Scan mode to exclude.
            exclusion_type (str): Type of the scanning exclusion.
            value (str): Exclusion value.

        Returns:
            response (Response): API response from Sophos.
        """
        body = remove_empty_elements(
            {
                "comment": comment,
                "scanMode": scan_mode,
                "type": exclusion_type,
                "value": value,
            }
        )
        url_suffix = "endpoint/v1/settings/exclusions/scanning"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def update_scan_exclusion(
        self,
        comment: Optional[str],
        scan_mode: Optional[str],
        exclusion_id: str,
        value: Optional[str],
    ) -> dict:
        """
        Update an existing scan exclusion.

        Args:
            comment (str): Comment indicating why the exclusion was created.
            scan_mode (str): Scan mode to exclude.
            exclusion_id (str): ID of the exclusion to update.
            value (str): Exclusion value.

        Returns:
            response (Response): API response from Sophos.
        """
        body = remove_empty_elements({"comment": comment, "scanMode": scan_mode, "value": value})
        url_suffix = f"endpoint/v1/settings/exclusions/scanning/{exclusion_id}"
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def delete_scan_exclusion(self, exclusion_id: str) -> dict:
        """
        Delete an existing scan exclusion.

        Args:
            exclusion_id (str): ID of the exclusion to delete.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/exclusions/scanning/{exclusion_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def list_exploit_mitigation(
        self,
        mitigation_type: Optional[str],
        page_size: Optional[int],
        page: Optional[int],
        modified: Optional[bool],
    ) -> dict:
        """
        List all exploit mitigations.

        Args:
            mitigation_type (str): Exploit mitigation type.
            page_size (int): Size of the page requested.
            page (int): Number of page to return.
            modified (bool): Whether or not the exploit mitigation was customized.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements(
            {
                "page": page,
                "pageSize": page_size,
                "type": mitigation_type,
                "modified": modified,
            }
        )
        url_suffix = "endpoint/v1/settings/exploit-mitigation/applications"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_exploit_mitigation(self, mitigation_id: str) -> dict:
        """
        Get a single exploit mitigation.

        Args:
            mitigation_id (str): Exploit mitigation type.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/exploit-mitigation/applications/{mitigation_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def add_exploit_mitigation(self, path: str) -> dict:
        """
        Add a new exploit mitigation.

        Args:
            path (str): An absolute path to exclude.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"paths": [path]}
        url_suffix = "endpoint/v1/settings/exploit-mitigation/applications"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def update_exploit_mitigation(self, mitigation_id: str, path: Optional[str]) -> dict:
        """
        Update an existing exploit mitigation.

        Args:
            mitigation_id (str): ID of the mitigation to update.
            path (str): An absolute path to exclude.

        Returns:
            response (Response): API response from Sophos.
        """
        body = remove_empty_elements({"paths": [path]})
        url_suffix = f"endpoint/v1/settings/exploit-mitigation/applications/{mitigation_id}"
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def delete_exploit_mitigation(self, mitigation_id: str) -> dict:
        """
        Update an existing exploit mitigation.

        Args:
            mitigation_id (str): ID of the mitigation to update.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/exploit-mitigation/applications/{mitigation_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def list_detected_exploit(
        self,
        page_size: Optional[int],
        page: Optional[int],
        thumbprint_not_in: Optional[str],
    ) -> dict:
        """
        List all detected exploits.

        Args:
            page_size (int): Size of the page requested.
            page (int): Number of page to return.
            thumbprint_not_in (str): Filter out detected exploits with these thumbprints.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = "endpoint/v1/settings/exploit-mitigation/detected-exploits"
        params = {
            "pageSize": page_size,
            "page": page,
            "thumbprintNotIn": thumbprint_not_in,
        }
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_detected_exploit(self, detected_exploit_id: str) -> dict:
        """
        Get a single detected exploit.

        Args:
            detected_exploit_id (str): ID of the exploit to return.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/settings/exploit-mitigation/detected-exploits/{detected_exploit_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def isolate_endpoint(self, endpoint_id: List[str], comment: Optional[str]) -> dict:
        """
        Initiate isolation request on the given endpoint(s).

        Args:
            endpoint_id: Endpoint ID(s) to be isolated.
            comment: Reason for isolation.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"enabled": True, "ids": endpoint_id, "comment": comment}
        return self._http_request(
            method="POST",
            headers=self.headers,
            url_suffix="endpoint/v1/endpoints/isolation",
            json_data=body,
        )

    def deisolate_endpoint(self, endpoint_id: List[str], comment: Optional[str]) -> dict:
        """
        Initiate de-isolation request on the given endpoint(s).

        Args:
            endpoint_id: Endpoint ID(s) to be de-isolated.
            comment: Reason for de-isolation.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"enabled": False, "ids": endpoint_id, "comment": comment}
        return self._http_request(
            method="POST",
            headers=self.headers,
            url_suffix="endpoint/v1/endpoints/isolation",
            json_data=body,
        )

    def get_endpoints_group(self, group_id: str) -> dict:
        """
        Get endpoints in a group

        Args:
            group_id (str): Endpoint group ID.

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"/endpoint/v1/endpoint-groups/{group_id}/endpoints"

        return self._http_request(method="GET", url_suffix=url_suffix, headers=self.headers)

    def add_endpoints_group(self, group_id: str, ids: List[str]) -> dict:
        """
        Add endpoints to the group.

        Args:
            group_id (str): Endpoint group ID.
            ids(list(str)): Endpoints in the group.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"ids": ids}

        body = remove_empty_elements(body)
        url_suffix = f"/endpoint/v1/endpoint-groups/{group_id}/endpoints"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def remove_endpoints(self, group_id: str, ids: str) -> dict:
        """
        Remove endpoints from endpoint group.

        Args:
            ids(str): Endpoints in the group.
            group_id (str): Endpoint group ID.

        Returns:
            response (Response): API response from Sophos.
        """

        params = {"ids": ids}

        params = remove_empty_elements(params)

        url_suffix = f"/endpoint/v1/endpoint-groups/{group_id}/endpoints"

        return self._http_request(method="DELETE", params=params, headers=self.headers, url_suffix=url_suffix)

    def remove_endpoint(self, group_id: str, endpoint_id: str) -> dict:
        """
        Remove endpoint from endpoint group.

        Args:
            endpoint_id(str): Endpoints in the group.
            group_id (str): Endpoint group ID.

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"/endpoint/v1/endpoint-groups/{group_id}/endpoints/{endpoint_id}"

        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def get_endpoint_policies(self, policy_type: Optional[str], page_size: Optional[int], page: Optional[int]) -> dict:
        """
        Get all endpoint policy.

        Args:
            policy_type (Optional[str]): Policy Type.
            page_size (Optional[int]): Size of the page requested.
            page (Optional[int]): Number of page to return.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = "endpoint/v1/policies"
        params = remove_empty_elements({"pageSize": page_size, "page": page, "pageTotal": True, "policyType": policy_type})
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_endpoint_policy(self, policy_id: str) -> dict:
        """
        Get details of Policy by ID.

        Args:
            policy_id (str): ID of the endpoint policy.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/policies/{policy_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def delete_endpoint_policy(self, policy_id: str) -> dict:
        """
        Delete an existing endpoint policy.

        Args:
            policy_id (str): ID of the endpoint policy to delete.

        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/policies/{policy_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def clone_endpoint_policy(self, policy_id: str, name: Optional[str]) -> dict:
        """
        Clone an existing endpoint policy.

        Args:
            policy_id (str): ID of the endpoint policy to clone.
            name (Optional[str]): Name of the endpoint policy to clone.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/policies/{policy_id}/clone"
        body = {"name": name} if name else {}
        return self._http_request(
            method="POST",
            headers=self.headers,
            url_suffix=url_suffix,
            json_data=body,
        )

    def update_endpoint_policy(self, policy_id: str, priority: str) -> dict:
        """
        Update order priority an endpoint policy.

        Args:
            policy_id (str): ID of the endpoint policy to update.
            priority (str): priority of the endpoint policy to update.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"endpoint/v1/policies/{policy_id}"
        body = {"priority": priority}
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            url_suffix=url_suffix,
            json_data=body,
        )

    def list_usergroups(
        self,
        group_ids: Optional[str],
        search: Optional[str],
        search_fields: Optional[str],
        domain: Optional[str],
        source_type: Optional[str],
        user_id: Optional[str],
        page: Optional[int],
        page_size: Optional[int],
    ) -> dict:
        """
        List all usergroups.

        Args:
            group_ids (str) : List of item IDs to match.
            search (str): Search for items that match the given terms.
            search_fields (str): Search only within the specified fields.
                The following values are allowed :- name, description.
            domain (str): List the items that match the given domain.
            source_type (str): Types of sources of directory information.
                The following values are allowed:- custom, activeDirectory, azureActiveDirectory.
            user_id (str): Search groups associated with the given user ID.
            page (int): Index of page to retrieve.
            page_size (int): Max usergroups in a page.

        Returns:
            response (Response): API response from Sophos.
        """
        params = {
            "ids": group_ids,
            "search": search,
            "searchFields": search_fields,
            "domain": domain,
            "sourceType": source_type,
            "userId": user_id,
            "page": page,
            "pageSize": page_size,
            "pageTotal": True,
        }
        params = remove_empty_elements(params)

        return self._http_request(
            method="GET",
            headers=self.headers,
            params=params,
            url_suffix="common/v1/directory/user-groups",
        )

    def get_usergroup(self, group_id: str) -> dict:
        """
        Get a single usergroup based on ID.

        Args:
            group_id (str): ID of the usergroup to get.

        Returns:
            response (Response): API response from Sophos.
        """
        return self._http_request(method="GET", headers=self.headers, url_suffix=f"common/v1/directory/user-groups/{group_id}")

    def create_usergroup(self, group_name: str, description: Optional[str], user_ids: List[str]) -> dict:
        """Create a usergroup

        Args:
            group_name (str): Group name.
            description (str): Group description.
            userIds (str): Users in the group.
        """
        body = {"name": group_name, "description": description, "userIds": user_ids}
        return self._http_request(
            method="POST",
            headers=self.headers,
            url_suffix="common/v1/directory/user-groups",
            json_data=body,
        )

    def update_usergroup(self, group_id: str, group_name: str, description: Optional[str]) -> dict:
        """Update a specific usergroup based on ID.

        Args:
            group_id (str): Group ID.
            group_name (str): Group name.
            description (str): Group description.
        """
        body = {"name": group_name, "description": description}
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            url_suffix=f"common/v1/directory/user-groups/{group_id}",
            json_data=body,
        )

    def delete_usergroup(self, group_id: str) -> dict:
        """Delete a usergroup with given ID.

        Args:
            group_id (str): Group ID.
        """
        return self._http_request(
            method="DELETE",
            headers=self.headers,
            url_suffix=f"common/v1/directory/user-groups/{group_id}",
        )

    def get_users_in_usergroup(
        self,
        group_id: str,
        search: Optional[str],
        search_field: Optional[str],
        domain: Optional[str],
        source_type: Optional[str],
        page: int,
        page_size: int,
    ) -> dict:
        """
        Add multiple users to the specified group.

        Args:
            group_id (str): Group ID.
            search (str): Search for items that match the given terms.
            search_field(str): Search only within the specified fields.
            domain(str): List the items that match the given domain.
            source_type(str): Types of sources of directory information.
            page (int): Index of page to retrieve.
            page_size (int): Max users in a page.
        Returns:
            response (Response): API response from Sophos.
        """
        params = {
            "searchFields": search_field,
            "search": search,
            "domain": domain,
            "sourceType": source_type,
            "page": page,
            "pageSize": page_size,
            "pageTotal": True,
        }

        url_suffix = f"common/v1/directory/user-groups/{group_id}/users"
        return self._http_request(method="GET", url_suffix=url_suffix, headers=self.headers, params=remove_empty_elements(params))

    def add_users_to_usergroup(self, group_id: str, ids: List[str]) -> dict:
        """
        Add multiple users to the specified group.

        Args:
            group_id (str): Group ID.
            ids (list): List of User ID.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"common/v1/directory/user-groups/{group_id}/users"
        return self._http_request(method="POST", url_suffix=url_suffix, headers=self.headers, json_data={"ids": ids})

    def delete_user_from_usergroup(self, group_id: str, user_id: str) -> dict:
        """
        Delete a user from the specified group.

        Args:
            group_id (str): Group ID.
            user_id (str): User ID.
        Returns:
            response (Response): API response from Sophos.
        """
        url_suffix = f"common/v1/directory/user-groups/{group_id}/users/{user_id}"
        return self._http_request(method="DELETE", url_suffix=url_suffix, headers=self.headers)

    def list_users(
        self,
        search: Optional[str],
        search_fields: Optional[str],
        group_id: Optional[str],
        domain: Optional[str],
        source_type: Optional[str],
        page_size: Optional[int],
        page: Optional[int],
    ) -> dict:
        """
        List all users.

        Args:
            search (str): Search for items that match the given terms.
            search_fields (str): Search only within the specified fields.
                The following values are allowed :- name, description.
            group_id (str) : Group Id associated with a user.
            domain (str): List the items that match the given domain.
            source_type (str): Types of sources of directory information.
                The following values are allowed:- custom, activeDirectory, azureActiveDirectory.
            page_size (int) : The size of the page being returned.
            page (int) : The one indexed page number being returned.

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements(
            {
                "search": search,
                "searchFields": search_fields,
                "sourceType": source_type,
                "groupId": group_id,
                "domain": domain,
                "pageSize": page_size,
                "page": page,
                "pageTotal": True,
            }
        )
        url_suffix = "common/v1/directory/users"
        return self._http_request(method="GET", headers=self.headers, params=params, url_suffix=url_suffix)

    def get_user(self, user_id: str) -> dict:
        """
        Get a single user based on id.

        Args:
            user_id (str) : The User's id.

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"common/v1/directory/users/{user_id}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def add_user(
        self,
        first_name: str,
        last_name: str,
        email: str,
        role: Optional[str],
        exchange_login: Optional[str],
        group_ids: Optional[list],
    ) -> dict:
        """
        Add a new user.

        Args:
            first_name (str) : First name of the user.
            last_name (str) : Last name of the user.
            email (str) : The User's email.
            role (str) : Role type of the user
            exchange_login (str) : User's Exchange login.
            group_ids (str) : Group Ids the user is currently enrolled in.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {
            "name": f"{first_name} {last_name}",
            "firstName": first_name,
            "lastName": last_name,
            "email": email,
            "role": role,
            "exchangeLogin": exchange_login,
            "groupIds": group_ids,
        }

        body = remove_empty_elements(body)
        url_suffix = "common/v1/directory/users"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def update_user(
        self,
        user_id: str,
        name: Optional[str],
        first_name: Optional[str],
        last_name: Optional[str],
        email: Optional[str],
        role: Optional[str],
        exchange_login: Optional[str],
    ) -> dict:
        """
        Update an existing user.

        Args:
            user_id (str) : The User's id.
            name(str) : User's full name.
            first_name (str) : First name of the user.
            last_name (str) : Last name of the user.
            email (str) : The User's email.
            role (str) : Role type of the user
            exchange_login (str) : User's Exchange login.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {
            "name": name,
            "firstName": first_name,
            "lastName": last_name,
            "email": email,
            "role": role,
            "exchangeLogin": exchange_login,
        }

        url_suffix = f"common/v1/directory/users/{user_id}"
        return self._http_request(
            method="PATCH",
            headers=self.headers,
            json_data=remove_empty_elements(body),
            url_suffix=url_suffix,
        )

    def delete_user(
        self,
        user_id: str,
    ) -> dict:
        """
        Delete an existing user.

        Args:

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"common/v1/directory/users/{user_id}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)

    def get_endpoint_group(self, limit: Optional[int], page: Optional[int]) -> dict:
        """
        List all endpoint group connected to a tenant

        Returns:
            response (Response): API response from Sophos.
        """
        params = remove_empty_elements({"pageSize": limit, "pageTotal": True, "page": page})
        url_suffix = "endpoint/v1/endpoint-groups"
        return self._http_request(method="GET", url_suffix=url_suffix, headers=self.headers, params=params)

    def create_group(self, description: Optional[str], type: str, name: str, endpointIds: Optional[List[str]]) -> dict:
        """
        List all endpoint group connected to a tenant.

        Args:
            endpointIds(list(str)): Endpoints in the group.:
            description (str): Group description.
            name (str): Group name.
            type (str): Endpoint group types server/computer.

        Returns:
            response (Response): API response from Sophos.
        """
        body = {"description": description, "type": type, "name": name.strip(), "endpointIds": endpointIds}

        body = remove_empty_elements(body)
        url_suffix = "/endpoint/v1/endpoint-groups"
        return self._http_request(
            method="POST",
            headers=self.headers,
            json_data=body,
            url_suffix=url_suffix,
        )

    def update_group(self, groupId: str, name: Optional[str], description: Optional[str]) -> dict:
        """
        List all endpoint group connected to a tenant.

        Args:
            groupId (str): Endpoint group ID.
            name (str): New group name.
            description (str) : New group description.

        Returns:
            response (Response): API response from Sophos.
        """

        body = {"description": description, "name": name}

        body = remove_empty_elements(body)
        url_suffix = f"/endpoint/v1/endpoint-groups/{groupId}"
        return self._http_request(method="PATCH", headers=self.headers, json_data=body, url_suffix=url_suffix)

    def fetch_group(self, groupId: str) -> dict:
        """
        List all endpoint group connected to a tenant.

        Args:
            groupId (str): Endpoint group ID.

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"/endpoint/v1/endpoint-groups/{groupId}"
        return self._http_request(method="GET", headers=self.headers, url_suffix=url_suffix)

    def delete_group(self, groupId: str) -> dict:
        """
        Delete endpoint group connected to a tenant.

        Args:
            groupId (str): Endpoint group ID.

        Returns:
            response (Response): API response from Sophos.
        """

        url_suffix = f"/endpoint/v1/endpoint-groups/{groupId}"
        return self._http_request(method="DELETE", headers=self.headers, url_suffix=url_suffix)


def flip_chars(id_to_flip: str) -> str:
    """
    Reverse every couple of adjacent digits in the ID.
    can be used to construct Sophos URLs.
    For example:
        badc-fehgji-xwzy -> abcd-efghij-wxyz
    Args:
        id_to_flip (str): A UID
    Returns:
        id (str): A UID with the every two digits flipped.
    """
    return "-".join("".join(pair[::-1] for pair in re.split(r"(.{2})", uid_part)) for uid_part in id_to_flip.split("-"))


def create_alert_output(client: Client, item: dict, table_headers: List[str]) -> dict[str, Optional[Any]]:
    """
    Create the complete output dictionary for an alert.

    Args:
        item (dict): A source dictionary from the API response.
        table_headers (list(str)): The table headers to be used when creating initial data.

    Returns:
        object_data (dict(str)): The output dictionary.
    """
    alert_data = {field: item.get(field) for field in table_headers + ["groupKey", "product"]}
    managed_agent = item.get("managedAgent")
    if managed_agent:
        managed_agent_id = managed_agent.get("id", "")
        alert_data["managedAgentId"] = managed_agent_id
        alert_data["managedAgentIdMorphed"] = flip_chars(managed_agent_id)
        alert_data["managedAgentName"] = client.get_managed_agent_name(managed_agent_id)
        alert_data["managedAgentType"] = managed_agent.get("type")
    tenant = item.get("tenant")
    if tenant:
        alert_data["tenantId"] = tenant.get("id")
        alert_data["tenantIdMorphed"] = flip_chars(tenant.get("id", ""))
        alert_data["tenantName"] = tenant.get("name")
    person = item.get("person")
    if person:
        person_id = person.get("id", "")
        alert_data["person"] = person_id
        alert_data["personIdMorphed"] = flip_chars(person_id)
        alert_data["personName"] = client.get_person_name(person_id)

    return alert_data


def sophos_central_alert_list_command(client: Client, args: dict[str, str]) -> CommandResults:
    """
    List all alerts.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.list_alert(min(int(args.get("limit", "")), 100))
    items = results.get("items")
    table_headers = [
        "id",
        "description",
        "severity",
        "raisedAt",
        "allowedActions",
        "managedAgentId",
        "managedAgentName",
        "personName",
        "category",
        "type",
    ]
    outputs = []
    if items:
        for item in items:
            outputs.append(create_alert_output(client, item, table_headers))

    readable_output = tableToMarkdown(
        name=f"Listed {len(outputs)} Alerts:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.Alert",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_alert_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a specific alert by ID.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    alert_id = args.get("alert_id", "")
    try:
        result = client.get_alert(alert_id)
        table_headers = [
            "id",
            "description",
            "severity",
            "raisedAt",
            "allowedActions",
            "managedAgentId",
            "managedAgentName",
            "personName",
            "category",
            "type",
        ]
        object_data = create_alert_output(client, result, table_headers)
        readable_output = tableToMarkdown(name="Found Alert:", t=object_data, headers=table_headers, removeNull=True)
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.Alert",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to find the following alert: {alert_id}")


def sophos_central_alert_action_command(client: Client, args: dict) -> CommandResults:
    """
    Take an action against a specific alert or alerts.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    outputs = []
    table_headers = [
        "id",
        "action",
        "completedAt",
        "alertId",
        "result",
        "requestedAt",
        "startedAt",
        "status",
    ]
    alert_ids = argToList(args.get("alert_id"))
    failed_alerts = []
    results = []
    for alert_id in alert_ids:
        try:
            result = client.action_alert(
                alert_id,
                args.get("action", ""),
                args.get("message", ""),
            )
            results.append(result)
            object_data = {field: result.get(field) for field in table_headers}
            outputs.append(object_data)
        except DemistoException:
            failed_alerts.append(alert_id)
    readable_output = tableToMarkdown(name="Alerts Acted Against:", t=outputs, headers=table_headers, removeNull=True)
    if failed_alerts:
        readable_output += f'\nAlerts not acted against: {",".join(failed_alerts)}'
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.AlertAction",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_alert_search_command(client: Client, args: dict) -> CommandResults:
    """
    Search for alerts based on query parameters.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    start_date = args.get("start")
    end_date = args.get("end")
    date_range = args.get("date_range")
    if date_range:
        start_date, end_date = parse_date_range(date_range=date_range)
        start_date = start_date.isoformat(timespec="milliseconds")
        end_date = end_date.isoformat(timespec="milliseconds")

    results = client.search_alert(
        start_date,
        end_date,
        argToList(args.get("product")),
        argToList(args.get("category")),
        args.get("group_key"),
        argToList(args.get("severity")),
        argToList(args.get("ids")),
        min(int(args.get("limit", "")), 100),
    )

    items = results.get("items")
    table_headers = [
        "id",
        "description",
        "severity",
        "raisedAt",
        "allowedActions",
        "managedAgentId",
        "managedAgentName",
        "personName",
        "category",
        "type",
    ]
    outputs = []
    if items:
        for item in items:
            outputs.append(create_alert_output(client, item, table_headers))

    readable_output = tableToMarkdown(
        name=f"Found {len(outputs)} Alerts:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.Alert",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all endpoints.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.list_endpoint(
        argToList(args.get("health_status")),
        argToList(args.get("endpoint_type")),
        args.get("tamper_protection_enabled") == "true" if args.get("tamper_protection_enabled") else None,
        argToList(args.get("lockdown_status")),
        args.get("last_seen_before"),
        args.get("last_seen_after"),
        args.get("ids"),
        args.get("view"),
        min(int(args.get("limit", "")), 100),
        argToList(args.get("ip_addresses")),
        args.get("hostname_contains"),
    )
    full_match_ip = argToBoolean(args.get("full_match_ip", "false"))
    full_match_hostname = argToBoolean(args.get("full_match_hostname", "false"))
    items = results.get("items")
    table_headers = [
        "id",
        "hostname",
        "ipv4Addresses",
        "ipv6Addresses",
        "macAddresses",
        "type",
        "online",
        "tamperProtectionEnabled",
    ]
    outputs = []
    if items:
        for item in items:
            object_data = {field: item.get(field) for field in table_headers}
            # The Sophos API does partial string matching, which can be unwanted for IP addresses.
            if full_match_ip:
                query_ips = argToList(args.get("ip_addresses"))
                ips = []
                if (data := object_data.get("ipv4Addresses", [])) is not None:
                    ips.extend(data)
                if (data := object_data.get("ipv6Addresses", [])) is not None:
                    ips.extend(data)
                matching_ips = [ip for ip in query_ips if ip in ips]
                if not matching_ips:
                    continue

            # The Sophos API does partial string matching, which can be unwanted for hostnames.
            if full_match_hostname and (
                object_data.get("hostname") is None or object_data.get("hostname") != args.get("hostname_contains")
            ):
                continue

            assigned_products = item.get("assignedProducts")
            if assigned_products:
                object_data["assignedProductCodes"] = [
                    product.get("code") for product in assigned_products if product.get("code")
                ]
            associated_person = item.get("associatedPerson")
            if associated_person:
                object_data["associatedPersonId"] = associated_person.get("id")
                object_data["associatedPersonName"] = associated_person.get("name")
                object_data["associatedPersonViaLogin"] = associated_person.get("viaLogin")
            group = item.get("group")
            if group:
                object_data["groupId"] = group.get("id")
                object_data["groupName"] = group.get("name")
            endpoint_os = item.get("os")
            if endpoint_os:
                object_data["osBuild"] = endpoint_os.get("build")
                object_data["osIsServer"] = endpoint_os.get("isServer")
                object_data["osName"] = endpoint_os.get("name")
                object_data["osPlatform"] = endpoint_os.get("platform")
            health = item.get("health")
            if health:
                object_data["health"] = health.get("overall")
            outputs.append(object_data)
    readable_output = tableToMarkdown(
        name=f"Listed {len(outputs)} Endpoints:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.Endpoint",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_scan_command(client: Client, args: dict) -> CommandResults:
    """
    Initiate a scan on an endpoint.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    table_headers = ["id", "status", "requestedAt"]
    failed_endpoints = []
    outputs = []
    results = []
    for endpoint in argToList(args.get("endpoint_id")):
        try:
            result = client.scan_endpoint(endpoint)
            if result:
                results.append(result)
                object_data = {field: result.get(field) for field in table_headers}
                outputs.append(object_data)
        except DemistoException:
            failed_endpoints.append(endpoint)
    readable_output = tableToMarkdown(name="Scanning Endpoints:", t=outputs, headers=table_headers, removeNull=True)
    if failed_endpoints:
        readable_output += f'\nEndpoints not scanned: {",".join(failed_endpoints)}'
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.EndpointScan",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_tamper_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get tamper protection info on one or more endpoints.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    table_headers = ["endpointId", "enabled", "password"]
    failed_endpoints = []
    outputs = []
    results = []
    for endpoint in argToList(args.get("endpoint_id")):
        try:
            result = client.get_tamper(endpoint)
            if result:
                object_data = {
                    "enabled": result.get("enabled"),
                    "endpointId": endpoint,
                    "password": result.get("password"),
                }
                if not argToBoolean(args.get("get_password")):
                    object_data["password"] = None
                    result["password"] = result["previousPasswords"] = None
                results.append(result)
                outputs.append(object_data)
        except DemistoException:
            failed_endpoints.append(endpoint)
    readable_output = tableToMarkdown(
        name="Listed Endpoints Tamper Protection:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    if failed_endpoints:
        readable_output += f'\nEndpoints not found: {",".join(failed_endpoints)}'
    return CommandResults(
        outputs_key_field="endpointId",
        outputs_prefix="SophosCentral.EndpointTamper",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_tamper_update_command(client: Client, args: dict) -> CommandResults:
    """
    Update tamper protection info on one or more endpoints.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    table_headers = ["endpointId", "enabled", "password"]
    failed_endpoints = []
    outputs = []
    results = []
    for endpoint in argToList(args.get("endpoint_id")):
        try:
            result = client.update_tamper(endpoint, args.get("enabled") == "true")
            if result:
                object_data = {
                    "enabled": result.get("enabled"),
                    "endpointId": endpoint,
                    "password": result.get("password"),
                }
                if not argToBoolean(args.get("get_password")):
                    object_data["password"] = None
                    result["password"] = result["previousPasswords"] = None
                results.append(result)
                outputs.append(object_data)
        except DemistoException:
            failed_endpoints.append(endpoint)
    readable_output = tableToMarkdown(
        name="Updated Endpoints Tamper Protection:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    if failed_endpoints:
        readable_output += f'\nEndpoints not found: {",".join(failed_endpoints)}'
    return CommandResults(
        outputs_key_field="endpointId",
        outputs_prefix="SophosCentral.EndpointTamper",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def create_item_output(item: dict) -> dict:
    """
    Create the complete output dictionary for an allowed / blocked item.

    Args:
        item (dict(str)): A source dictionary from the API response.

    Returns:
        item_data (dict(str)): The output dictionary.
    """
    data_fields = ["id", "comment", "type", "updatedAt", "createdAt"]
    item_data = {field: item.get(field) for field in data_fields}
    properties = item.get("properties")
    if properties:
        item_data["fileName"] = properties.get("fileName")
        item_data["path"] = properties.get("path")
        item_data["sha256"] = properties.get("sha256")
        item_data["certificateSigner"] = properties.get("certificateSigner")

    created_by = item.get("createdBy")
    if created_by:
        item_data["createdById"] = created_by.get("id")
        item_data["createdByName"] = created_by.get("name")

    origin_endpoint = item.get("originEndpoint")
    if origin_endpoint:
        item_data["originEndpointId"] = origin_endpoint.get("endpointId")

    origin_person = item.get("originPerson")
    if origin_person:
        item_data["originPersonId"] = origin_person.get("id")
        item_data["originPersonName"] = origin_person.get("name")

    return item_data


def validate_item_fields(args: dict[str, str]):
    """
    Validate parameters exist before they are sent to the API.

    Args:
        args (dict): XSOAR arguments for the command.

    Raises:
        DemistoException: If a required field is missing.
    """
    item_types = ["path", "certificateSigner", "sha256"]
    for item_type in item_types:
        if args.get("item_type") == item_type and not args.get(camel_case_to_underscore(item_type)):
            raise DemistoException(f"{item_type} item requires a value in the {camel_case_to_underscore(item_type)} argument.")


def sophos_central_allowed_item_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all allowed items for a tenant.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.list_allowed_item(min(int(args.get("page_size", "")), 100), args.get("page"))
    items = results.get("items")
    table_headers = [
        "id",
        "comment",
        "fileName",
        "sha256",
        "path",
        "certificateSigner",
        "createdAt",
        "createdByName",
        "type",
        "updatedAt",
    ]
    outputs = []
    if items:
        for item in items:
            outputs.append(create_item_output(item))
    readable_output = f'### Current page: {int(args.get("page", ""))}\n'
    readable_output += tableToMarkdown(
        name=f"Listed {len(outputs)} Allowed Items:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.AllowedItem",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_allowed_item_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single allowed item for a tenant.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    allowed_item_id = args.get("allowed_item_id", "")
    try:
        result = client.get_allowed_item(allowed_item_id)
        table_headers = [
            "id",
            "comment",
            "fileName",
            "sha256",
            "path",
            "certificateSigner",
            "createdAt",
            "createdByName",
            "type",
            "updatedAt",
        ]
        object_data = {}
        if result:
            object_data = create_item_output(result)

        readable_output = tableToMarkdown(
            name="Found Allowed Item:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.AllowedItem",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to find item: {allowed_item_id}")


def sophos_central_allowed_item_add_command(client: Client, args: dict) -> CommandResults:
    """
    Add a new allowed item.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    validate_item_fields(args)
    result = client.add_allowed_item(
        args.get("item_type", ""),
        args.get("comment", ""),
        args.get("certificate_signer"),
        args.get("file_name"),
        args.get("path"),
        args.get("sha256"),
        args.get("origin_endpoint_id"),
    )
    table_headers = [
        "id",
        "comment",
        "fileName",
        "sha256",
        "path",
        "certificateSigner",
        "createdAt",
        "createdByName",
        "type",
        "updatedAt",
    ]
    object_data = {}
    if result:
        object_data = create_item_output(result)

    readable_output = tableToMarkdown(
        name="Added Allowed Item:",
        t=object_data,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.AllowedItem",
        raw_response=result,
        outputs=object_data,
        readable_output=readable_output,
    )


def sophos_central_allowed_item_update_command(client: Client, args: dict) -> CommandResults:
    """
    Update an existing allowed item.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    allowed_item_id = args.get("allowed_item_id", "")
    try:
        result = client.update_allowed_item(allowed_item_id, args.get("comment", ""))
        table_headers = [
            "id",
            "comment",
            "fileName",
            "sha256",
            "path",
            "certificateSigner",
            "createdAt",
            "createdByName",
            "type",
            "updatedAt",
        ]
        object_data = {}
        if result:
            object_data = create_item_output(result)

        readable_output = tableToMarkdown(
            name="Updated Allowed Item:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.AllowedItem",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to update item: {allowed_item_id}")


def sophos_central_allowed_item_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing allowed item.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.delete_allowed_item(args.get("allowed_item_id", ""))
    readable_output = f'Success deleting allowed item: {args.get("allowed_item_id", "")}'
    outputs = {"deletedItemId": args.get("allowed_item_id", "")}
    if not result or not result.get("deleted"):
        readable_output = f'Failed deleting allowed item: {args.get("allowed_item_id", "")}'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.DeletedAllowedItem",
    )


def sophos_central_blocked_item_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all blocked items for a tenant.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.list_blocked_item(
        min(int(args.get("page_size", "")), 100),
        args.get("page"),
    )
    items = results.get("items")
    table_headers = [
        "id",
        "comment",
        "fileName",
        "sha256",
        "path",
        "certificateSigner",
        "createdAt",
        "createdByName",
        "type",
        "updatedAt",
    ]
    outputs = []
    if items:
        for item in items:
            outputs.append(create_item_output(item))

    readable_output = f'### Current page: {int(args.get("page", ""))}\n'
    readable_output += tableToMarkdown(
        name=f"Listed {len(outputs)} Blocked Items:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.BlockedItem",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_blocked_item_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single blocked item for a tenant.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    blocked_item_id = args.get("blocked_item_id", "")
    try:
        result = client.get_blocked_item(blocked_item_id)
        table_headers = [
            "id",
            "comment",
            "fileName",
            "sha256",
            "path",
            "certificateSigner",
            "createdAt",
            "createdByName",
            "type",
            "updatedAt",
        ]
        object_data = {}
        if result:
            object_data = create_item_output(result)

        readable_output = tableToMarkdown(
            name="Found Blocked Item:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.BlockedItem",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to find item: {blocked_item_id}")


def sophos_central_blocked_item_add_command(client: Client, args: dict) -> CommandResults:
    """
    Add a new blocked item.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    validate_item_fields(args)
    result = client.add_blocked_item(
        args.get("item_type", ""),
        args.get("comment", ""),
        args.get("certificate_signer"),
        args.get("file_name"),
        args.get("path"),
        args.get("sha256"),
        args.get("origin_endpoint_id"),
    )
    table_headers = [
        "id",
        "comment",
        "fileName",
        "sha256",
        "path",
        "certificateSigner",
        "createdAt",
        "createdByName",
        "type",
        "updatedAt",
    ]
    object_data = {}
    if result:
        object_data = create_item_output(result)

    readable_output = tableToMarkdown(
        name="Added Blocked Item:",
        t=object_data,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.BlockedItem",
        raw_response=result,
        outputs=object_data,
        readable_output=readable_output,
    )


def sophos_central_blocked_item_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing blocked item.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.delete_blocked_item(args.get("blocked_item_id", ""))
    readable_output = f'Success deleting blocked item: {args.get("blocked_item_id", "")}'
    outputs = {"deletedItemId": args.get("blocked_item_id", "")}
    if not result or not result.get("deleted"):
        readable_output = f'Failed deleting blocked item: {args.get("blocked_item_id", "")}'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.DeletedBlockedItem",
    )


def sophos_central_scan_exclusion_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all scan exclusions.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    results = client.list_scan_exclusion(
        args.get("exclusion_type"),
        min(int(args.get("page_size", "")), 100),
        args.get("page"),
    )
    items = results.get("items")
    table_headers = ["id", "value", "type", "description", "comment", "scanMode"]
    outputs = []
    if items:
        for item in items:
            current_object_data = {field: item.get(field) for field in table_headers}
            outputs.append(current_object_data)

    readable_output = f'### Current page: {int(args.get("page", ""))}\n'
    readable_output += tableToMarkdown(
        name=f"Listed {len(outputs)} Scan Exclusions:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.ScanExclusion",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_scan_exclusion_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    exclusion_id = args.get("exclusion_id", "")
    try:
        result = client.get_scan_exclusion(exclusion_id)
        table_headers = ["id", "value", "type", "description", "comment", "scanMode"]
        object_data = {}
        if result:
            object_data = {field: result.get(field) for field in table_headers}

        readable_output = tableToMarkdown(
            name="Found Scan Exclusion:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.ScanExclusion",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(f"Unable to find exclusion: {exclusion_id}")


def sophos_central_scan_exclusion_add_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    result = client.add_scan_exclusion(
        args.get("comment"),
        args.get("scan_mode"),
        args.get("exclusion_type", ""),
        args.get("value", ""),
    )
    table_headers = ["id", "value", "type", "description", "comment", "scanMode"]
    object_data = {}
    if result:
        object_data = {field: result.get(field) for field in table_headers}

    readable_output = tableToMarkdown(
        name="Added Scan Exclusion:",
        t=object_data,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.ScanExclusion",
        raw_response=result,
        outputs=object_data,
        readable_output=readable_output,
    )


def sophos_central_scan_exclusion_update_command(client: Client, args: dict) -> CommandResults:
    """
    Update an existing. scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    exclusion_id = args.get("exclusion_id", "")
    try:
        result = client.update_scan_exclusion(
            args.get("comment"),
            args.get("scan_mode"),
            exclusion_id,
            args.get("value", ""),
        )
        table_headers = ["id", "value", "type", "description", "comment", "scanMode"]
        object_data = {}
        if result:
            object_data = {field: result.get(field) for field in table_headers}

        readable_output = tableToMarkdown(
            name="Updated Scan Exclusion:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.ScanExclusion",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(f"Unable to update exclusion: {exclusion_id}")


def sophos_central_scan_exclusion_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.delete_scan_exclusion(args.get("exclusion_id", ""))
    readable_output = f'Success deleting scan exclusion: {args.get("exclusion_id", "")}'
    outputs = {"deletedExclusionId": args.get("exclusion_id", "")}
    if not result or not result.get("deleted"):
        readable_output = f'Failed deleting scan exclusion: {args.get("exclusion_id", "")}'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.DeletedScanExclusion",
    )


def sophos_central_exploit_mitigation_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all exploit mitigations.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    results = client.list_exploit_mitigation(
        args.get("mitigation_type"),
        min(int(args.get("page_size", "")), 100),
        args.get("page"),
        args.get("modified"),
    )
    items = results.get("items")
    table_headers = ["id", "name", "type", "category", "paths"]
    outputs = []
    if items:
        for item in items:
            current_object_data = {field: item.get(field) for field in table_headers}
            outputs.append(current_object_data)
    readable_output = f'### Current page: {int(args.get("page", ""))}\n'
    readable_output += tableToMarkdown(
        name=f"Listed {len(outputs)} Exploit Mitigations:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.ExploitMitigation",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_exploit_mitigation_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    mitigation_id = args.get("mitigation_id", "")
    try:
        result = client.get_exploit_mitigation(mitigation_id)
        table_headers = ["id", "name", "type", "category", "paths"]
        object_data = {}
        if result:
            object_data = {field: result.get(field) for field in table_headers}

        readable_output = tableToMarkdown(
            name="Found Exploit Mitigation:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.ExploitMitigation",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(f"Unable to find mitigation: {mitigation_id}")


def sophos_central_exploit_mitigation_add_command(client: Client, args: dict) -> CommandResults:
    """
    Add a new scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    result = client.add_exploit_mitigation(args.get("path", ""))
    table_headers = ["id", "name", "type", "category", "paths"]
    object_data = {}
    if result:
        object_data = {field: result.get(field) for field in table_headers}

    readable_output = tableToMarkdown(
        name="Added Exploit Mitigation:",
        t=object_data,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.ExploitMitigation",
        raw_response=result,
        outputs=object_data,
        readable_output=readable_output,
    )


def sophos_central_exploit_mitigation_update_command(client: Client, args: dict) -> CommandResults:
    """
    Add a new scan exclusion.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    mitigation_id = args.get("mitigation_id", "")
    try:
        result = client.update_exploit_mitigation(mitigation_id, args.get("path"))
        table_headers = ["id", "name", "type", "category", "paths"]
        object_data = {}
        if result:
            object_data = {field: result.get(field) for field in table_headers}

        readable_output = tableToMarkdown(
            name="Updated Exploit Mitigation:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.ExploitMitigation",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(f"Unable to update mitigation: {mitigation_id}")


def sophos_central_exploit_mitigation_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing exploit mitigation.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.delete_exploit_mitigation(args.get("mitigation_id", ""))
    readable_output = f'Success deleting exploit mitigation: {args.get("mitigation_id", "")}'
    outputs = {"deletedMitigationId": args.get("mitigation_id", "")}
    if not result or not result.get("deleted"):
        readable_output = f'Failed deleting exploit mitigation: {args.get("mitigation_id", "")}'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.DeletedExploitMitigation",
    )


def create_detected_exploit_output(item: dict) -> dict:
    """
    Create the complete output dictionary for a detected exploit.

    Args:
        item (dict(str)): A source dictionary from the API response.

    Returns:
        object_data (dict(str)): The output dictionary.
    """
    data_fields = [
        "id",
        "thumbprint",
        "count",
        "description",
        "firstSeenAt",
        "lastSeenAt",
    ]
    outputs = {field: item.get(field) for field in data_fields}

    last_user = item.get("lastUser")
    if last_user:
        outputs["lastUserName"] = last_user.get("name")
        outputs["lastUserId"] = last_user.get("id")

    last_endpoint = item.get("lastEndpoint")
    if last_endpoint:
        outputs["lastEndpointHostname"] = last_endpoint.get("hostname")
        outputs["lastEndpointId"] = last_endpoint.get("id")

    return outputs


def sophos_central_detected_exploit_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all detected exploits.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.list_detected_exploit(
        min(int(args.get("page_size", "")), 100),
        args.get("page"),
        args.get("thumbprint_not_in"),
    )
    items = results.get("items")
    table_headers = [
        "id",
        "description",
        "thumbprint",
        "count",
        "firstSeenAt",
        "lastSeenAt",
    ]
    outputs = []
    if items:
        for item in items:
            current_object_data = create_detected_exploit_output(item)
            outputs.append(current_object_data)
    readable_output = f'### Current page: {int(args.get("page", ""))}\n'
    readable_output += tableToMarkdown(
        name=f"Listed {len(outputs)} Detected Exploits:",
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.DetectedExploit",
        raw_response=results,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_detected_exploit_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a single detected exploit.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    detected_exploit_id = args.get("detected_exploit_id", "")
    try:
        result = client.get_detected_exploit(detected_exploit_id)
        table_headers = [
            "id",
            "description",
            "thumbprint",
            "count",
            "firstSeenAt",
            "lastSeenAt",
        ]
        object_data = {}
        if result:
            object_data = create_detected_exploit_output(result)

        readable_output = tableToMarkdown(
            name="Found Detected Exploit:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.DetectedExploit",
            raw_response=result,
            outputs=object_data,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(f"Unable to find exploit: {detected_exploit_id}")


def sophos_central_isolate_endpoint_command(client: Client, args: dict) -> CommandResults:
    """
    Initiate isolation request on the given endpoint(s).

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.isolate_endpoint(argToList(args.get("endpoint_id")), args.get("comment", ""))
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.EndpointIsolation",
        readable_output="Endpoint(s) isolated successfully.",
        outputs=result,
        raw_response=result,
    )


def sophos_central_deisolate_endpoint_command(client: Client, args: dict) -> CommandResults:
    """
    Initiate de-isolation request on the given endpoint(s).

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.deisolate_endpoint(argToList(args.get("endpoint_id")), args.get("comment", ""))
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.EndpointIsolation",
        readable_output="Endpoint(s) de-isolated successfully.",
        outputs=result,
        raw_response=result,
    )


def fetch_incidents(
    client: Client,
    last_run: dict[str, int],
    first_fetch_time: str,
    fetch_severity: Optional[List[str]],
    fetch_category: Optional[List[str]],
    max_fetch: Optional[int],
) -> tuple[dict[str, int], List[dict]]:
    """
    Fetch incidents (alerts) each minute (by default).

    Args:
        client (Client): Sophos Central Client.
        last_run (dict): Dict with last_fetch object,
                                  saving the last fetch time(in millisecond timestamp).
        first_fetch_time (dict): Dict with first fetch time in str (ex: 3 days ago).
        fetch_severity (list(str)): Severity to fetch.
        fetch_category (list(str)): Category(s) to fetch.
        max_fetch (int): Max number of alerts to fetch.
    Returns:
        Tuple of next_run (millisecond timestamp) and the incidents list
    """
    demisto.debug(f"Fetching incidents with last_run: {last_run}")
    last_fetch_timestamp = last_run.get("last_fetch", None)

    if last_fetch_timestamp:
        demisto.debug(f"Last fetch time: {last_fetch_timestamp}")
        last_fetch_date = datetime.fromtimestamp(last_fetch_timestamp / 1000)
        last_fetch = last_fetch_date
    else:
        demisto.debug(f"First fetch time: {first_fetch_time}")
        first_fetch_time_date = dateparser.parse(first_fetch_time)
        assert first_fetch_time_date is not None, f"could not parse {first_fetch_time}"
        first_fetch_date = first_fetch_time_date.replace(tzinfo=None)
        last_fetch = first_fetch_date
    incidents = []
    next_run = last_fetch
    alerts = client.search_alert(
        last_fetch.isoformat(timespec="milliseconds"),
        None,
        None,
        fetch_category,
        None,
        fetch_severity,
        None,
        max_fetch,
    )
    data_fields = [
        "id",
        "description",
        "severity",
        "raisedAt",
        "allowedActions",
        "managedAgentId",
        "category",
        "type",
    ]
    for alert in alerts.get("items", []):
        alert = create_alert_output(client, alert, data_fields)
        alert_created_time = alert.get("raisedAt")
        alert_id = alert.get("id")
        incident = {
            "name": f"Sophos Central Alert {alert_id}",
            "occurred": alert_created_time,
            "rawJSON": json.dumps(alert),
        }
        incidents.append(incident)
    if incidents:
        demisto.debug(f"Found {len(incidents)} incidents.")
        last_incident_time = incidents[-1].get("occurred", "")
        next_run = datetime.strptime(last_incident_time, DATE_FORMAT)
    next_run += timedelta(milliseconds=1)
    next_run_timestamp = int(datetime.timestamp(next_run) * 1000)
    demisto.debug(f"Next run: {next_run_timestamp}")
    return {"last_fetch": next_run_timestamp}, incidents


def sophos_central_group_list(client: Client, args: dict) -> CommandResults:
    """
    List all endpoint groups in the directory.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments
    Returns:
        CommandResults: outputs,readable outputs and raw response for XSOAR.
    """
    page_size = arg_to_number(args.get("page_size"))
    number_of_page = arg_to_number(args.get("page"))

    if page_size is not None:
        if page_size < 0:
            raise ValueError("page_size must be a positive number.")

        if page_size > 1000:
            raise ValueError("page_size must be equal or less than 1000.")

    if number_of_page is not None and number_of_page < 0:
        raise ValueError("page must be a positive number.")

    try:
        results = client.get_endpoint_group(page_size, number_of_page)
        items = results.get("items", [])
        pages = results.get("pages", {})
        records = (pages.get("items", 0),)
        current = (pages.get("current", 0),)
        total = pages.get("total", 0)

        if number_of_page > total:
            return CommandResults(readable_output="Page Not Found.")

        table_headers = ["id", "name", "type"]

        outputs = []

        if items:
            for item in items:
                group_data = {field: item.get(field) for field in table_headers}
                group_data["count"] = item.get("endpoints", {}).get("itemsCount", 0)
                outputs.append(group_data)

        table_headers.append("count")
        name = f"Found {records} records \n Page : {current}/{total} \n Listed {len(outputs)} EndpointGroups:"

        readable_output = tableToMarkdown(
            name=name,
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=results,
            outputs=items,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to fetch the group list.")


def sophos_central_group_create(client: Client, args: dict) -> CommandResults:
    """
    Create a new endpoint group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    try:
        results = client.create_group(
            args.get("description"), args.get("type", ""), args.get("name", ""), argToList(args.get("endpointIds", []))
        )

        table_headers = ["id", "name", "type"]

        outputs = {key: results.get(key) for key in table_headers}

        readable_output = tableToMarkdown(
            name="EndpointGroup Created Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=results,
            outputs=results,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to create the group.")


def sophos_central_group_update(client: Client, args: dict):
    """
    Update an endpoint group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    group_id = args.get("groupId", "")
    try:
        results = client.update_group(group_id, args.get("name", "").strip(), args.get("description"))

        table_headers = ["id", "name", "description"]

        outputs = {key: results.get(key) for key in table_headers}

        readable_output = tableToMarkdown(
            name="EndpointGroup Updated Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=results,
            outputs=results,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to update the following group: {group_id}.")


def sophos_central_group_get(client: Client, args: dict):
    """
    Fetch an endpoint group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    group_id = args.get("groupId", "")
    try:
        results = client.fetch_group(group_id)

        table_headers = ["type", "name"]

        outputs = {key: results.get(key) for key in table_headers}

        readable_output = tableToMarkdown(
            name="Fetched EndpointGroup Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=results,
            outputs=results,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to find the following group: {group_id}.")


def sophos_central_group_delete(client: Client, args: dict):
    """
    Delete an endpoint group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    results = client.delete_group(args.get("groupId", ""))

    if results.get("deleted"):
        results["id"] = args.get("groupId")

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            outputs=results,
            readable_output="EndpointGroup Deleted Successfully.",
        )
    else:
        raise DemistoException("EndpointGroup Deletion Failed, Please Enter valid groupId.")


def create_policy_output(item: dict) -> dict[str, Optional[Any]]:
    """
    Create the complete output dictionary for an endpoint policy.

    Args:
        item (dict): A source dictionary from the API response.
        table_headers (list(str)): The table headers to be used when creating initial data.

    Returns:
        object_data (dict(str)): The output dictionary.
    """

    policy_data = {
        "id": item.get("id"),
        "feature": item.get("type"),
        "settings": item.get("settings", {}),
        "orderPriority": item.get("priority"),
        "name": item.get("name"),
        "enforced": item.get("enabled"),
        "lastModified": item.get("updatedAt"),
    }

    if item.get("appliesTo", {}).get("users") and item.get("appliesTo", {}).get("userGroups"):
        policy_data["typeSingle"] = item.get("appliesTo", {}).get("users")
        policy_data["typeGroup"] = item.get("appliesTo", {}).get("userGroups")

    if item.get("appliesTo", {}).get("endpoints") and item.get("appliesTo", {}).get("endpointGroups"):
        policy_data["typeSingle"] = item.get("appliesTo", {}).get("endpoints")
        policy_data["typeGroup"] = item.get("appliesTo", {}).get("endpointGroups")

    return policy_data


def sophos_central_group_membership_get(client: Client, args: dict):
    """
    Get endpoints in a group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """

    group_id = args.get("groupId", "")

    try:
        result = client.get_endpoints_group(group_id)
        items = result.get("items", [])

        outputs = []

        table_headers = ["id", "type", "hostname"]

        if items:
            for item in items:
                group_data = {field: item.get(field) for field in table_headers}
                outputs.append(group_data)

        readable_output = tableToMarkdown(
            name=f"Fetched {len(outputs)} Endpoint(s) Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=result,
            outputs=items,
            readable_output=readable_output,
        )

    except DemistoException:
        return CommandResults(readable_output=f"Unable to find the following endpoint of group: {group_id}.")


def sophos_central_group_endpoints_add(client: Client, args: dict):
    """
    Add endpoints to group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """

    group_id = args.get("groupId", "")

    try:
        result = client.add_endpoints_group(group_id, argToList(args.get("endpointIds")))
        items = result.get("addedEndpoints", [])

        outputs = []

        table_headers = ["id", "hostname"]

        if items:
            for item in items:
                group_data = {field: item.get(field) for field in table_headers}
                outputs.append(group_data)

        endpoints = {"endpoints": outputs, "id": group_id}

        readable_output = tableToMarkdown(
            name=f"{len(outputs)} Endpoint(s) Added Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=result,
            outputs=endpoints,
            readable_output=readable_output,
        )

    except DemistoException:
        return CommandResults(readable_output=f"Unable to add the endpoint to the following group: {group_id}.")


def sophos_central_group_endpoints_remove(client: Client, args: dict):
    """
    Remove endpoints to group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """

    group_id = args.get("groupId", "")

    try:
        result = client.remove_endpoints(group_id, args.get("endpointIds", ""))
        items = result.get("removedEndpoints", [])

        endpoints = {"endpoints": items, "id": group_id, "removedEndpoints": args.get("endpointIds", "")}

        outputs = []

        table_headers = ["id", "hostname"]

        if items:
            for item in items:
                group_data = {field: item.get(field) for field in table_headers}
                outputs.append(group_data)
        readable_output = tableToMarkdown(
            name=f"{len(outputs)} EndPoint(s) Removed Successfully.",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.EndpointGroups",
            raw_response=result,
            outputs=endpoints,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to remove endpoint(s) from the following group: {group_id}.")


def sophos_central_group_endpoint_remove(client: Client, args: dict):
    """

    Remove single endpoint from group.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """

    group_id = args.get("groupId", "")

    try:
        result = client.remove_endpoint(group_id, args.get("endpointId", ""))

        if result.get("removed"):
            readable_output = "Endpoint removed successfully."

            endpoints = {"id": group_id, "removedEndpoint": args.get("endpointId", "")}

            return CommandResults(
                outputs_key_field="id",
                outputs_prefix="SophosCentral.EndpointGroups",
                raw_response=result,
                outputs=endpoints,
                readable_output=readable_output,
            )
        else:
            return CommandResults(readable_output="Endpoint Deletion failed, Please Enter valid endpointId.")
    except DemistoException:
        return CommandResults(readable_output=f"Unable to remove endpoint from the following group: {group_id}.")


def sophos_central_endpoint_policy_search_command(client: Client, args: dict) -> CommandResults:
    """
    Get all configured policies.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    page_size = arg_to_number(args.get("page_size", 50))
    number_of_page = arg_to_number(args.get("page", 1))

    if page_size is not None:
        if page_size < 0:
            raise ValueError("page_size must be a positive number")

        if page_size > 200:
            raise ValueError("page_size must be equal or less than 200")

    if number_of_page is not None and number_of_page < 0:
        raise ValueError("page must be a positive number")

    result = client.get_endpoint_policies(args.get("policy_type", ""), page_size, number_of_page)

    items = result.get("items", [])
    pages = result.get("pages", {})
    table_headers = ["id", "feature", "settings", "orderPriority", "name", "enforced", "typeSingle", "typeGroup", "lastModified"]
    outputs = []
    if items:
        for item in items:
            outputs.append(create_policy_output(item))

    total_pages = pages.get("total", 1)
    if number_of_page > total_pages:
        return CommandResults(
            readable_output="Page Not Found.",
        )
    readable_output = tableToMarkdown(
        name=(
            f"Total Record(s): {pages.get('items', '')} \n"
            f"### Current page: {number_of_page}/{total_pages}\n"
            f"### Listed {len(outputs)} Endpoint Policies:"
        ),
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.PolicyAndEnumeration",
        raw_response=result,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_policy_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get details of Policy by ID.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.get_endpoint_policy(args.get("policy_id", ""))
    table_headers = ["id", "feature", "settings", "orderPriority", "name", "enforced", "typeSingle", "typeGroup", "lastModified"]
    outputs = create_policy_output(result)
    readable_output = tableToMarkdown(
        name=f'{args.get("policy_id", "")} Policy Details:',
        t=outputs,
        headers=table_headers,
        removeNull=True,
    )
    return CommandResults(
        outputs_key_field="id",
        outputs_prefix="SophosCentral.PolicyAndEnumeration",
        raw_response=result,
        outputs=outputs,
        readable_output=readable_output,
    )


def sophos_central_endpoint_policy_search_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing policy.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.delete_endpoint_policy(args.get("policy_id", ""))
    readable_output = f'Success deleting endpoint policy: {args.get("policy_id", "")}'
    outputs = {"deletedPolicyId": args.get("policy_id", "")}
    if not (result and result.get("deleted")):
        readable_output = f'Failed deleting endpoint policy: {args.get("policy_id", "")}.'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.PolicyAndEnumeration",
    )


def sophos_central_endpoint_policy_clone_command(client: Client, args: dict) -> CommandResults:
    """
    Clone an existing policy.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.clone_endpoint_policy(args.get("policy_id", ""), args.get("name", ""))
    readable_output = f'Success cloning endpoint policy: {result.get("id", "")}.'
    outputs = {"clonedPolicyId": result.get("id", "")}
    if not (result and result.get("id")):
        readable_output = f'Failed cloning endpoint policy: {args.get("policy_id", "")}.'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.PolicyAndEnumeration",
    )


def sophos_central_endpoint_policy_reorder_command(client: Client, args: dict) -> CommandResults:
    """
    Update Priority in existing policy.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    result = client.update_endpoint_policy(args.get("policy_id", ""), args.get("priority", ""))
    readable_output = f'Success updating endpoint policy: {result.get("id", "")}.'
    outputs = {"updatedPolicyId": result.get("id", "")}
    if not result or not result.get("id"):
        readable_output = f'Failed updating endpoint policy: {args.get("policy_id", "")}.'
        outputs = {}
    return CommandResults(
        raw_response=result,
        readable_output=readable_output,
        outputs=outputs,
        outputs_prefix="SophosCentral.PolicyAndEnumeration",
    )


def create_usergroup_output(item: dict, table_headers: List[str]) -> dict:
    """
    Create the complete output dictionary for an usergroup.

    Args:
        item (dict): A source dictionary from the API response.
        table_headers (list(str)): The table headers to be used when creating initial data.

    Returns:
        usergroup_data (dict(str)): The output dictionary.
    """
    usergroup_data = {field: item.get(field) for field in table_headers}
    source = item.get("source")
    if source:
        usergroup_data["sourceType"] = source.get("type")

    return usergroup_data


def sophos_central_usergroups_get_command(client: Client, args: dict) -> CommandResults:
    """
    Get a specific usergroups by ID.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    try:
        result = client.get_usergroup(args.get("groupId", ""))
        result.update(
            {
                "usersItemsCount": result.get("users", {}).get("itemsCount"),
                "usersTotal": result.get("users", {}).get("total"),
                "users": result.get("users", {}).get("items", []),
            }
        )
        table_headers = ["id", "name", "description", "sourceType"]

        object_data = create_usergroup_output(item=result, table_headers=table_headers)
        readable_output = tableToMarkdown(
            name="Found User Groups:",
            t=object_data,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.UserGroups",
            readable_output=readable_output,
            outputs=result,
            raw_response=result,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to fetch user group.")


def sophos_central_usergroups_create_command(client: Client, args: dict) -> CommandResults:
    """
    Create a usergroup.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    try:
        result = client.create_usergroup(args.get("groupName", ""), args.get("description"), argToList(args.get("userIds")))
        result.update(
            {
                "usersItemsCount": result.get("users", {}).get("itemsCount"),
                "usersTotal": result.get("users", {}).get("total"),
                "users": result.get("users", {}).get("items", []),
            }
        )
        return CommandResults(
            outputs_key_field="id",
            outputs=result,
            outputs_prefix="SophosCentral.UserGroups",
            readable_output=f"Successfully created a user group with ID: {result.get('id')}.",
            raw_response=result,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to create user group.")


def sophos_central_usergroups_list_command(client: Client, args: dict) -> CommandResults:
    """
    Returns a list of all user groups that match the search criteria (optional).

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    allowed_search_fields = ["name", "description"]
    search_fields = argToList(args.get("searchFields"))
    for field in search_fields:
        if field not in allowed_search_fields:
            raise DemistoException(
                "Invalid value for searchFields provided. Allowed values are " + ", ".join(allowed_search_fields) + "."
            )
    try:
        page = arg_to_number(args.get("page", "1"))
        page_size = arg_to_number(args.get("pageSize", "50"))

        if page is None or page < 1:
            raise ValueError("page should be a positive number.")

        if page_size is None or page_size < 1 or page_size > 100:
            raise ValueError("pageSize must be between 1 and 100.")

        results = client.list_usergroups(
            args.get("groupsIds"),
            args.get("search"),
            args.get("searchFields"),
            args.get("domain"),
            args.get("sourceType"),
            args.get("userId"),
            page,
            page_size,
        )

        current_page = results.get("pages", {}).get("current", 1)
        total_pages = results.get("pages", {}).get("total", 1)

        if current_page > total_pages:
            return CommandResults(readable_output="No page found.")

        items = results.get("items", [])
        for item in items:
            item.update(
                {
                    "usersItemsCount": item.get("users", {}).get("itemsCount"),
                    "usersTotal": item.get("users", {}).get("total"),
                    "users": item.get("users", {}).get("items", []),
                }
            )
        table_headers = ["id", "name", "description", "sourceType"]

        outputs = []
        for item in items:
            outputs.append(create_usergroup_output(item=item, table_headers=table_headers))

        readable_output = tableToMarkdown(
            name=(
                f"Total Records: {results.get('pages', {}).get('items', '')}\n"
                f"Page: {current_page}/{total_pages}\n"
                f"Listed {len(outputs)} User Groups:"
            ),
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.UserGroups",
            readable_output=readable_output,
            outputs=items,
            raw_response=results,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to list user groups.")


def sophos_central_usergroups_update_command(client: Client, args: dict) -> CommandResults:
    """
    Update a usergroup.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    try:
        result = client.update_usergroup(args.get("groupId", ""), args.get("groupName", ""), args.get("description"))
        result.update(
            {
                "usersItemsCount": result.get("users", {}).get("itemsCount"),
                "usersTotal": result.get("users", {}).get("total"),
                "users": result.get("users", {}).get("items", []),
            }
        )
        return CommandResults(
            outputs_key_field="id",
            outputs=result,
            outputs_prefix="SophosCentral.UserGroups",
            readable_output=f"Successfully updated the user group with ID: {result.get('id')}.",
            raw_response=result,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to update usergroup with ID: {args.get('groupId')}.")


def sophos_central_usergroups_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete a usergroup.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    try:
        result = client.delete_usergroup(args.get("groupId", ""))
        output = {}
        if result.get("deleted"):
            output["deletedUserGroupId"] = args.get("groupId", "")

        return CommandResults(
            outputs=output,
            outputs_prefix="SophosCentral.DeletedUserGroups",
            readable_output=f"Successfully deleted the user group with ID: {args.get('groupId')}.",
            raw_response=result,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to delete usergroup with ID: {args.get('groupId')}.")


def sophos_central_usergroups_membership_get(client: Client, args: dict) -> CommandResults:
    """
    List all users in a specific group.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments.
    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    group_id = args.get("groupId", "")
    search = args.get("search")
    search_field = args.get("searchFields")
    domain = args.get("domain")
    source_type = args.get("sourceType")
    page = arg_to_number(args.get("page", "1"))
    page_size = arg_to_number(args.get("pageSize", "50"))

    if page is None or page < 1:
        raise ValueError("page should be a positive number.")

    if page_size is None or page_size < 1 or page_size > 100:
        raise ValueError("pageSize must be between 1 and 100.")

    allowed_search_fields = ["name", "firstName", "lastName", "email", "exchangeLogin"]
    search_fields = argToList(search_field)
    for field in search_fields:
        if field not in allowed_search_fields:
            raise DemistoException(
                "Invalid value for searchFields provided. Allowed values are " + ", ".join(allowed_search_fields) + "."
            )

    try:
        result = client.get_users_in_usergroup(group_id, search, search_field, domain, source_type, page, page_size)
        items = result.get("items", [])
        current_page = result.get("pages", {}).get("current", 1)
        total_pages = result.get("pages", {}).get("total", 1)

        if current_page > total_pages:
            return CommandResults(readable_output="No page found.")

        table_headers = ["id", "name", "email"]
        users = []
        output = {}
        for item in items:
            current_object_data = {field: item.get(field) for field in table_headers}
            users.append(current_object_data)
        output["id"] = group_id
        output["users"] = items

        readable_output = tableToMarkdown(
            name=(
                f"Total Records: {result.get('pages', {}).get('items', '')}\n"
                f"Page: {current_page}/{total_pages}\n"
                f"Listed {len(users)} User(s) in Usergroup:"
            ),
            t=users,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.UserGroups",
            raw_response=result,
            outputs=output,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to get users for the following group: {group_id}.")


def sophos_central_usergroups_users_add(client: Client, args: dict) -> CommandResults:
    """
    Add multiple users to the specified group.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments.
    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    group_id = args.get("groupId", "")
    ids = argToList(args.get("userIds", ""))
    try:
        result = client.add_users_to_usergroup(group_id, ids)
        result["id"] = group_id
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.UserGroups",
            raw_response=result,
            outputs=result,
            readable_output="User(s) added to the specified group.",
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to add user to the following group: {group_id}.")


def sophos_central_usergroups_user_delete(client: Client, args: dict) -> CommandResults:
    """
    Delete a user from the specified group.

    Args:
        client (Client):  Sophos Central API client.
        args (dict): All command arguments.
    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.
    """
    group_id = args.get("groupId", "")
    user_id = args.get("userId", "")
    try:
        result = client.delete_user_from_usergroup(group_id, user_id)
        result["id"] = user_id
        output = {"id": group_id, "removedUser": user_id}

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.UserGroups",
            raw_response=result,
            outputs=output,
            readable_output="User removed from group.",
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to remove user({user_id}) from the following group: {group_id}.")


def sophos_central_users_list_command(client: Client, args: dict) -> CommandResults:
    """
    List all users for a tenant who meets command arguments.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    allowed_search_fields = ["name", "firstName", "lastName", "email", "exchangeLogin"]
    search_fields = argToList(args.get("searchFields"))
    for field in search_fields:
        if field not in allowed_search_fields:
            raise DemistoException(
                "Invalid value for searchFields provided. Allowed values are " + ", ".join(allowed_search_fields) + "."
            )
    try:
        page = arg_to_number(args.get("page", "1"))
        page_size = arg_to_number(args.get("pageSize", "50"))

        if page is None or page < 1:
            raise ValueError("page should be a positive number.")

        if page_size is None or page_size < 1 or page_size > 100:
            raise ValueError("pageSize should be between 1 and 100.")

        results = client.list_users(
            args.get("search"),
            args.get("searchFields"),
            args.get("groupId"),
            args.get("domain"),
            args.get("sourceType"),
            page_size,
            page,
        )

        current_page = results.get("pages", {}).get("current", 1)
        total_pages = results.get("pages", {}).get("total", 1)

        if current_page > total_pages:
            return CommandResults(readable_output="No page found.")

        items = results.get("items")
        table_headers = ["id", "firstName", "lastName", "email", "exchangeLogin", "groupIds", "groupNames"]
        outputs = []
        if items:
            for item in items:
                current_object_data = {
                    field: item.get(field) for field in table_headers if field not in ["groupIds", "groupNames"]
                }
                groupIds = []
                groupNames = []
                for group_item in item.get("groups").get("items"):
                    groupIds.append(group_item.get("id"))
                    groupNames.append(group_item.get("name"))
                current_object_data["groupIds"] = groupIds
                current_object_data["groupNames"] = groupNames
                outputs.append(current_object_data)

        readable_output = tableToMarkdown(
            name=(
                f"Total Records: {results.get('pages', {}).get('items', '')}\n"
                f"Page: {current_page}/{total_pages}\n"
                f"Listed {len(outputs)} User(s):"
            ),
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.Users",
            raw_response=results,
            outputs=items,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to list users.")


def sophos_central_users_get_command(client: Client, args: dict) -> CommandResults:
    """
    List user of a tenant with userId.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    user_id = args.get("userId", "")
    try:
        item = client.get_user(user_id)
        table_headers = ["id", "firstName", "lastName", "email", "exchangeLogin", "groupIds", "groupNames"]
        outputs = []
        if item:
            current_object_data = {field: item.get(field) for field in table_headers if field not in ["groupIds", "groupNames"]}
            groupIds = []
            groupNames = []
            for group_item in item.get("groups", {}).get("items", []):
                groupIds.append(group_item.get("id", ""))
                groupNames.append(group_item.get("name", ""))
            current_object_data["groupIds"] = groupIds
            current_object_data["groupNames"] = groupNames
            outputs.append(current_object_data)
        readable_output = tableToMarkdown(
            name="Found User:",
            t=outputs,
            headers=table_headers,
            removeNull=True,
        )
        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.Users",
            raw_response=item,
            outputs=outputs,
            readable_output=readable_output,
        )
    except DemistoException:
        return CommandResults(readable_output=f"Unable to find the following user with userId:{user_id}.")


def sophos_central_users_add_command(client: Client, args: dict) -> CommandResults:
    """
    Add user for a tenant.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    try:
        result = client.add_user(
            args.get("firstName", ""),
            args.get("lastName", ""),
            args.get("email", ""),
            args.get("role", ""),
            args.get("exchangeLogin", ""),
            argToList(args.get("groupIds", "")),
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.Users",
            readable_output="A new User was added to the Directory.",
            outputs=result,
            raw_response=result,
        )
    except DemistoException:
        return CommandResults(readable_output="Unable to add user.")


def sophos_central_users_update_command(client: Client, args: dict) -> CommandResults:
    """
    Update an existing user.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    try:
        result = client.update_user(
            args.get("userId", ""),
            args.get("name"),
            args.get("firstName"),
            args.get("lastName"),
            args.get("email"),
            args.get("role"),
            args.get("exchangeLogin"),
        )

        return CommandResults(
            outputs_key_field="id",
            outputs_prefix="SophosCentral.Users",
            readable_output="User updated.",
            outputs=result,
            raw_response=result,
        )

    except DemistoException:
        return CommandResults(readable_output="Unable to update the user.")


def sophos_central_users_delete_command(client: Client, args: dict) -> CommandResults:
    """
    Delete an existing user.

    Args:
        client (Client): Sophos Central API client.
        args (dict): All command arguments

    Returns:
        CommandResults: outputs, readable outputs and raw response for XSOAR.

    """
    try:
        result = client.delete_user(args.get("userId", ""))
        output = {"deletedUserId": args.get("userId", "")}
        return CommandResults(
            outputs_prefix="SophosCentral.DeletedUsers",
            readable_output="User deleted.",
            outputs=output,
            raw_response=result,
        )

    except DemistoException:
        return CommandResults(readable_output="Unable to delete the user.")


def test_module(client: Client) -> str:
    """
    Test the validity of the connection and the.

    Args:
        client (Client): Sophos Central client

    Returns:
        'ok' if test passed, anything else will fail the test.
    """
    try:
        client.list_alert(1)
        return "ok"
    except DemistoException as exception:
        if "Name does not resolve" in str(exception):
            return "Wrong API server region found."
        raise DemistoException(exception)


def retrieve_jwt_token(client_id: str, client_secret: str, integration_context: dict) -> str:
    """
    Get the JWT token from the integration context or create a new one.

    Args:
        client_id (str): Sophos Central client ID.
        client_secret (str): Sophoes Central client secret.
        integration_context (dict): Integration context from Demisto.

    Returns:
        bearer_token (str): JWT token for required commands.
    """
    bearer_token = integration_context.get("bearer_token", "")
    valid_until = integration_context.get("valid_until", "")
    time_now = int(time.time())
    if bearer_token and valid_until and time_now < int(valid_until):
        return bearer_token
    bearer_token_dict = Client.get_jwt_token_from_api(client_id, client_secret)
    if bearer_token_dict:
        bearer_token = str(bearer_token_dict.get("access_token", ""))
    Client._update_integration_context({"bearer_token": bearer_token, "valid_until": time_now + 600})
    return bearer_token


def creds_changed(context: dict, client_id: str) -> bool:
    """
    Check whether the credentials were changed by the user.

    Args:
        context (dict): Integration context from Demisto.
        client_id (str): Sophos Central client ID.

    Returns:
        creds_changed (bool): True if credentials were changed, False otherwise.
    """
    return context.get("client_id", "") != client_id


def invalidate_context(client_id: str) -> None:
    """
    Invalidate the Demisto integration context and set new client id.

    Args:
        client_id (str): Newly provided Sophos Central client ID.
    """
    set_integration_context({"client_id": client_id})


def main():
    """Parse and validate integration params."""
    params = demisto.params()
    sophos_id = params.get("credentials", {}).get("identifier", "")
    sophos_secret = params.get("credentials", {}).get("password", "")

    # if credentials were changed by the user, stored cache/context should be invalidated
    # and new client ID should be stored in context.
    if creds_changed(get_integration_context(), sophos_id):
        invalidate_context(sophos_id)

    fetch_severity = params.get("fetch_severity", [])
    fetch_category = params.get("fetch_category", [])
    max_fetch = int(params.get("max_fetch", "50"))
    first_fetch_time = params.get("first_fetch", "3 days").strip()
    proxy = params.get("proxy", False)
    tenant_id = params.get("tenant_id", "")
    command = demisto.command()
    demisto.info(f"Command being called is {command}")
    client: Optional[Client] = None
    commands = {
        "sophos-central-alert-list": sophos_central_alert_list_command,
        "sophos-central-alert-get": sophos_central_alert_get_command,
        "sophos-central-alert-action": sophos_central_alert_action_command,
        "sophos-central-alert-search": sophos_central_alert_search_command,
        "sophos-central-endpoint-list": sophos_central_endpoint_list_command,
        "sophos-central-endpoint-scan": sophos_central_endpoint_scan_command,
        "sophos-central-endpoint-tamper-get": sophos_central_endpoint_tamper_get_command,
        "sophos-central-endpoint-tamper-update": sophos_central_endpoint_tamper_update_command,
        "sophos-central-allowed-item-list": sophos_central_allowed_item_list_command,
        "sophos-central-allowed-item-get": sophos_central_allowed_item_get_command,
        "sophos-central-allowed-item-add": sophos_central_allowed_item_add_command,
        "sophos-central-allowed-item-update": sophos_central_allowed_item_update_command,
        "sophos-central-allowed-item-delete": sophos_central_allowed_item_delete_command,
        "sophos-central-blocked-item-list": sophos_central_blocked_item_list_command,
        "sophos-central-blocked-item-get": sophos_central_blocked_item_get_command,
        "sophos-central-blocked-item-add": sophos_central_blocked_item_add_command,
        "sophos-central-blocked-item-delete": sophos_central_blocked_item_delete_command,
        "sophos-central-scan-exclusion-list": sophos_central_scan_exclusion_list_command,
        "sophos-central-scan-exclusion-get": sophos_central_scan_exclusion_get_command,
        "sophos-central-scan-exclusion-add": sophos_central_scan_exclusion_add_command,
        "sophos-central-scan-exclusion-update": sophos_central_scan_exclusion_update_command,
        "sophos-central-scan-exclusion-delete": sophos_central_scan_exclusion_delete_command,
        "sophos-central-exploit-mitigation-list": sophos_central_exploit_mitigation_list_command,
        "sophos-central-exploit-mitigation-get": sophos_central_exploit_mitigation_get_command,
        "sophos-central-exploit-mitigation-add": sophos_central_exploit_mitigation_add_command,
        "sophos-central-exploit-mitigation-update": sophos_central_exploit_mitigation_update_command,
        "sophos-central-exploit-mitigation-delete": sophos_central_exploit_mitigation_delete_command,
        "sophos-central-detected-exploit-list": sophos_central_detected_exploit_list_command,
        "sophos-central-detected-exploit-get": sophos_central_detected_exploit_get_command,
        "sophos-central-isolate-endpoint": sophos_central_isolate_endpoint_command,
        "sophos-central-deisolate-endpoint": sophos_central_deisolate_endpoint_command,
        "sophos-central-group-list": sophos_central_group_list,
        "sophos-central-group-create": sophos_central_group_create,
        "sophos-central-group-update": sophos_central_group_update,
        "sophos-central-group-get": sophos_central_group_get,
        "sophos-central-group-delete": sophos_central_group_delete,
        "sophos-central-group-membership-get": sophos_central_group_membership_get,
        "sophos-central-group-endpoints-add": sophos_central_group_endpoints_add,
        "sophos-central-group-endpoints-remove": sophos_central_group_endpoints_remove,
        "sophos-central-group-endpoint-remove": sophos_central_group_endpoint_remove,
        "sophos-central-users-list": sophos_central_users_list_command,
        "sophos-central-users-get": sophos_central_users_get_command,
        "sophos-central-users-add": sophos_central_users_add_command,
        "sophos-central-users-update": sophos_central_users_update_command,
        "sophos-central-users-delete": sophos_central_users_delete_command,
        "sophos-central-endpoint-policy-search": sophos_central_endpoint_policy_search_command,
        "sophos-central-endpoint-policy-get": sophos_central_endpoint_policy_get_command,
        "sophos-central-endpoint-policy-search-delete": sophos_central_endpoint_policy_search_delete_command,
        "sophos-central-endpoint-policy-clone": sophos_central_endpoint_policy_clone_command,
        "sophos-central-endpoint-policy-reorder": sophos_central_endpoint_policy_reorder_command,
        "sophos-central-usergroups-list": sophos_central_usergroups_list_command,
        "sophos-central-usergroups-get": sophos_central_usergroups_get_command,
        "sophos-central-usergroups-create": sophos_central_usergroups_create_command,
        "sophos-central-usergroups-update": sophos_central_usergroups_update_command,
        "sophos-central-usergroups-delete": sophos_central_usergroups_delete_command,
        "sophos-central-usergroups-users-add": sophos_central_usergroups_users_add,
        "sophos-central-usergroups-user-delete": sophos_central_usergroups_user_delete,
        "sophos-central-usergroups-membership-get": sophos_central_usergroups_membership_get,
    }
    try:
        bearer_token = retrieve_jwt_token(sophos_id, sophos_secret, get_integration_context())
        client = Client(
            bearer_token=bearer_token,
            verify=True,
            client_id=sophos_id,
            client_secret=sophos_secret,
            proxy=proxy,
            integration_context=get_integration_context(),
            tenant_id=tenant_id,
        )
        if command == "test-module":
            result = test_module(client)
            return_results(result)

        elif command == "fetch-incidents":
            next_run, incidents = fetch_incidents(
                client=client,
                last_run=demisto.getLastRun(),
                first_fetch_time=first_fetch_time,
                fetch_severity=fetch_severity,
                fetch_category=fetch_category,
                max_fetch=max_fetch,
            )
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)

        elif command in commands:
            return_results(commands[command](client, demisto.args()))
        else:
            raise NotImplementedError(f'The "{command}" command was not implemented.')

    except Exception as e:
        if "Error parsing the query params or request body" in str(e):
            error_string = "Make sure the arguments are correctly formatted."
        elif "Unauthorized" in str(e):
            error_string = "Wrong credentials (ID and / or secret) given."
        elif "SSL Certificate Verification Failed" in str(e):
            error_string = (
                "SSL Certificate Verification Failed: Make sure that Sophos Central API servers have valid SSL certificate."
            )
        else:
            error_string = str(e)
        return_error(f"Failed to execute {command} command. Error: {error_string}")
    finally:
        if client:
            client._update_integration_context(client.integration_context)


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()