Removing inactive systems¶
When users decommission devices or leave the organisation, their enrolled systems can linger in the portal indefinitely. This script uses the Enclave API to automatically remove systems that haven't connected for a configurable number of days, keeping your enrolled system list clean without manual intervention.
This is particularly useful for MSPs managing multiple customer tenants, where keeping track of individual device lifecycle events across every organisation isn't practical.
Tip
You can invoke the Enclave API from your scripting language of choice. Check out the OpenAPI specification for individual endpoint details.
Prerequisites¶
- An Enclave API key
- Your Organisation ID
- PowerShell 5.1 or later
How it works¶
The script pages through the GET /org/{orgId}/systems endpoint, including disabled systems. For each system, it checks the lastSeen timestamp - or the enrolledAt timestamp if the system has never connected. Any system that hasn't been seen within the configured threshold (90 days by default) is removed via the DELETE /org/{orgId}/systems/{systemId} endpoint.
A test mode lets you preview which systems would be removed before making any changes.
The script¶
Save the following script as a .ps1 file.
-orgId, the organisation to run queries against.-apiKey, the Enclave API key. Set theENCLAVE_API_KEYenvironment variable as an alternative.-maxInactiveDays, the maximum number of inactive days to allow before a system is removed. Defaults to 90.-test, previews which systems would be removed without making any changes.
Param(
[Parameter(Mandatory=$true)]
[string]$orgId,
[Parameter()]
[string]$apiKey = "",
[Parameter()]
[ValidateRange(1, [int]::MaxValue)]
[int]$maxInactiveDays = 90,
[Parameter()]
[switch]$test = $false
)
$ErrorActionPreference = "Stop"
if ($apiKey -eq "")
{
$apiKey = $env:ENCLAVE_API_KEY
}
if ($apiKey -eq "")
{
Write-Error "No API key provided; either specify the 'apiKey' argument, or set the ENCLAVE_API_KEY environment variable."
return;
}
# Attach our api key to each request.
$headers = @{Authorization = "Bearer $apiKey"}
$contentType = "application/json";
$uri = "https://api.enclave.io/org/$orgId/systems?per_page=50&include_disabled=true";
$currentDate = Get-Date
# Begin our loop through the pages of systems.
do {
$systems = Invoke-RestMethod -ContentType $contentType -Uri $uri -Headers $headers
foreach ($system in $systems.items) {
# Get the lastSeen field, or use the enrolement date if the system has never connected.
$lastSeenText = if ($system.lastSeen) { $system.lastSeen } else { $system.enrolledAt }
$lastSeen = Get-Date $lastSeenText;
# How long between today and the lastSeen date?
$age = $currentDate - $lastSeen;
# Anything not seen in the configured number of days will be removed.
if ($age.TotalDays -gt $maxInactiveDays)
{
"Removing $($system.hostname) ($($system.systemId)) after $([math]::Round($age.TotalDays)) days of inactivity"
if (!$test)
{
# Invoke our API to delete the system from the organisation.
Invoke-RestMethod -Uri "https://api.enclave.io/org/$orgId/systems/$($system.systemId)" -Headers $headers -Method Delete | Out-Null
}
}
}
# Get the url to the next page of systems.
$uri = $systems.links.next;
} while($uri);
Usage¶
Preview which systems would be removed (no changes are made):
.\cleanup-inactive-systems.ps1 -orgId "b87f2e1a3d9f" -apiKey $env:ENCLAVE_API_KEY -test
Remove systems inactive for more than 60 days:
.\cleanup-inactive-systems.ps1 -orgId "b87f2e1a3d9f" -apiKey $env:ENCLAVE_API_KEY -maxInactiveDays 60
Scheduling¶
To keep enrolled systems tidy automatically, run this script on a recurring schedule. Windows Task Scheduler, your RMM platform, or Azure Functions all work well. Set the ENCLAVE_API_KEY environment variable on the host so the scheduled task doesn't need the key in its command line arguments.