Sophos Central Email Quarantine API Sample Script

Disclaimer: This information is provided as-is for the benefit of the Community. Please contact Sophos Professional Services if you require assistance with your specific environment.


By using or accessing the Software below, you agree to be bound by the terms of the Sophos End User License Agreement


The sample powershell script reads all emails in the admin quarantine and fetches the URL's for each message ID.

param ([switch] $SaveCredentials)
    Description: Authentication Script for Sophos Central
    Parameters: -SaveCredentials -> will store then entered credentials locally on the PC, this is needed when
                                    running the script unattended

Write-Output "==============================================================================="
Write-Output "Sophos API - Authentication Example"
Write-Output "==============================================================================="

# Define the filename and path for the credential file
$CredentialFile = $PSScriptRoot + '\Sophos_Central_Admin_Credentials.json'

# Check if Central API Credentials have been stored, if not then prompt the user to enter the credentials
if (((Test-Path $CredentialFile) -eq $false) -or $SaveCredentials){
	# Prompt for Credentials
	$clientId = Read-Host "Please Enter your Client ID"
	$clientSecret = Read-Host "Please Enter your Client Secret" -AsSecureString 
} else { 
    # Read Credentials from JSON File
    $credentials = Get-Content $CredentialFile | ConvertFrom-Json
    $clientId = $credentials[0]
    $clientSecret = $credentials[1] | ConvertTo-SecureString

# We are making use of the PSCredentials object to store the API credentials
# The Client Secret will be encrypted for the user excuting the script
# When scheduling execution of the script remember to use the same user context

$SecureCredentials = New-Object System.Management.Automation.PSCredential -ArgumentList $clientId , $clientSecret

$TokenURI = ""

# TokenRequestBody for oAuth2
$TokenRequestBody = @{
	"grant_type" = "client_credentials";
	"client_id" = $SecureCredentials.GetNetworkCredential().Username;
	"client_secret" = $SecureCredentials.GetNetworkCredential().Password;
	"scope" = "token";
$TokenRequestHeaders = @{
	"content-type" = "application/x-www-form-urlencoded";

# Set TLS Version
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Post Request to SOPHOS for OAuth2 token
try {
    $APIAuthResult = (Invoke-RestMethod -Method Post -Uri $TokenURI -Body $TokenRequestBody -Headers $TokenRequestHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)
    if ($SaveCredentials) {
	    $clientSecret = $clientSecret | ConvertFrom-SecureString
	    ConvertTo-Json $ClientID, $ClientSecret | Out-File $CredentialFile -Force
} catch {
    # If there's an error requesting the token, say so, display the error, and break:
    Write-Output "" 
	Write-Output "AUTHENTICATION FAILED - Unable to retreive SOPHOS API Authentication Token"
    Write-Output "Please verify the credentials used!" 
    Write-Output "" 
    Write-Output "If you are working with saved credentials then you can reset them by calling"
    Write-Output "this script with the -SaveCredentials parameter"
    Write-Output "" 
    Read-Host -Prompt "Press ENTER to continue..."

# Set the Token for use later on:
$Token = $APIAuthResult.access_token

# SOPHOS Whoami URI:
$WhoamiURI = ""

# SOPHOS Whoami Headers:
$WhoamiRequestHeaders = @{
	"Content-Type" = "application/json";
	"Authorization" = "Bearer $Token";

# Post Request to SOPHOS for Whoami Details:
$APIWhoamiResult = (Invoke-RestMethod -Method Get -Uri $WhoamiURI -Headers $WhoamiRequestHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)

# Save Response details
$APIidTenant = $
$APIidType = $APIWhoamiResult.idType	
$APIdataRegion = $APIWhoamiResult.ApiHosts.dataRegion


# SOPHOS API Headers:
$APIHeaders = @{
	"Authorization" = "Bearer $Token";
	"X-Tenant-ID" = "$APIidTenant";
    "Content-Type" = "application/json";}

#Calc last 7 days for the query in UTC format
$currtime = Get-Date
$fromtime = $currtime.AddDays(-7).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFZ")
$tilltime = $currtime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFZ")
$PostBody =  '{ "beginDate": "' + $fromtime + '" , "endDate": "' + $tilltime + '" , "pageSize": 100 }'

 if($null -ne $APIdataRegion){
    # Search all Quarantine Emails within the $fromtime and $tilltime timeframe
	 $Result=(Invoke-RestMethod -Method Post -Uri $APIdataRegion"/email/v1/quarantine/messages/search" -Headers $APIHeaders -Body $PostBody -ErrorAction SilentlyContinue -ErrorVariable ScriptError)

# run through each email in Quarantine
foreach ($mailid in $Result.items ) {
    # show For and subject
    Write-Host $mailid.forRecipient " -- " $mailid.subject
    Write-Output "-URLs-----------------------------------------"
    # Build the URI to fetch the URLs for each Mail ID
    $mailURI = $APIdataRegion + "/email/v1/quarantine/messages/" + $ + "/urls?pageSize=100&page=1"
    $URLResult=(Invoke-RestMethod -Method Get -Uri $mailURI -Headers $APIHeaders -ErrorAction SilentlyContinue -ErrorVariable ScriptError)
    # Dump all URLs
    Write-Output $URLResult.items