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
#>

Clear-Host
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

# SOPHOS OAuth URL
$TokenURI = "https://id.sophos.com/api/v2/oauth2/token"

# 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..."
    Break
}

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

# SOPHOS Whoami URI:
$WhoamiURI = "https://api.central.sophos.com/whoami/v1"

# 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 = $APIWhoamiResult.id
$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/" + $mailid.id + "/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
}