Custom Solution: Shortening Endpoint Central Inventory Scan Intervals via REST API

AI Preview

Is this content worth your time? Use the quick preview to decide.

Welcome to Techaptic!

In today’s guide, we show you how to perform inventory scans more frequently on ManageEngine Endpoint Central, shortening the native once-a-day interval limit.

Scheduled inventory scans in Endpoint Central are limited to running once a day, which might not be enough for dynamic environments requiring up-to-date data. In this post, we use Endpoint Central’s REST API, PowerShell, and Windows Task Scheduler to trigger full inventory scans at your desired intervals without altering the native schedule settings. We also prioritize security by utilizing the Windows DPAPI mechanism to securely encrypt the API token, tying it directly to the local machine so it is never exposed in plain text. Follow along to implement this custom solution and maintain real-time visibility over your endpoints safely.

🔗 Helpful Links
  • There are no helpful links in this one.

Video Tutorial

Used Commands


Secure API token storage script (Save-EcAuthTokenMachine.ps1)

<#
.SYNOPSIS
Techaptic - Endpoint Central Secure API Token Storage Script

.DESCRIPTION
Protects the Endpoint Central API authentication token by using
Windows DPAPI with the LocalMachine scope.

The encrypted token is stored as Base64 data, and the token file
permissions are restricted to SYSTEM and Administrators.

.NOTES
Author: Techaptic

The script must be run from an elevated PowerShell session.

Default Output:
C:\ProgramData\EPC\ec_authtoken.machine
#>

# C:\Scripts\Save-EcAuthTokenMachine.ps1
# Encrypts the token with DPAPI LocalMachine.

[CmdletBinding()]
param(
[Parameter()]
[string]$OutputPath = "$env:ProgramData\EPC\ec_authtoken.machine",

[Parameter()]
[string]$EntropyText = "EPC_TOKEN_V1_LOCALMACHINE"
)

function Ensure-Dir([string]$Path) {
$d = Split-Path -Parent $Path
if ($d -and !(Test-Path $d)) {
New-Item -ItemType Directory -Path $d -Force | Out-Null
}
}

function Get-Plain([Security.SecureString]$SecureString) {
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
try {
[Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
}
finally {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
}

Write-Host ""
Write-Host "Techaptic - Endpoint Central Secure API Token Configuration Initiated..." -ForegroundColor Cyan
Write-Host "------------------------------------------------------------------------" -ForegroundColor Cyan

Write-Host "Processing: Token directory preparation... " -NoNewline
Ensure-Dir $OutputPath
Write-Host "[SUCCESS]" -ForegroundColor Green

Write-Host "Paste Endpoint Central Authentication Token and hit Enter:" -ForegroundColor Yellow
$tokenSecure = Read-Host -AsSecureString
$plain = Get-Plain $tokenSecure

if ([string]::IsNullOrWhiteSpace($plain)) {
Write-Host "[ERROR] Token is empty. The process is cancelled." -ForegroundColor Red
throw "Token was entered empty. Process cancelled."
}

Write-Host "Processing: DPAPI LocalMachine encryption... " -NoNewline
Add-Type -AssemblyName System.Security

$bytes = [Text.Encoding]::UTF8.GetBytes($plain)
$entropy = [Text.Encoding]::UTF8.GetBytes($EntropyText)

$protected = [Security.Cryptography.ProtectedData]::Protect(
$bytes,
$entropy,
[Security.Cryptography.DataProtectionScope]::LocalMachine
)

$b64 = [Convert]::ToBase64String($protected)
Set-Content -Path $OutputPath -Value $b64 -Encoding ASCII -NoNewline
Write-Host "[SUCCESS]" -ForegroundColor Green

Write-Host "Processing: Token file ACL configuration... " -NoNewline
& icacls $OutputPath /inheritance:r | Out-Null
& icacls $OutputPath /grant:r "SYSTEM:(R)" "Administrators:(R)" | Out-Null
Write-Host "[SUCCESS] (SYSTEM and Administrators: Read)" -ForegroundColor Green

Write-Host "------------------------------------------------------------------------" -ForegroundColor Cyan
Write-Host "Process Completed. Authentication token stored securely." -ForegroundColor Green
Write-Host "Token File: $OutputPath" -ForegroundColor Green

Full inventory scan trigger script (Invoke-EcInventoryScanAll.ps1)

<#
.SYNOPSIS
Techaptic - Endpoint Central Full Inventory Scan Trigger Script

.DESCRIPTION
Triggers a full inventory scan for all computers managed by
ManageEngine Endpoint Central.

The script reads the DPAPI-protected API token created by
Save-EcAuthTokenMachine.ps1 and sends an authenticated POST
request to the Endpoint Central Scan All API.

.NOTES
Author: Techaptic

API Endpoint:
POST /api/1.4/inventory/computers/scanall

Required API Permission:
Inventory - Update

Default Token File:
C:\ProgramData\EPC\ec_authtoken.machine

Default Log File:
C:\Windows\Temp\ec_inventory_scanall.log
#>

# C:\Scripts\Invoke-EcInventoryScanAll.ps1

[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$ServerBaseUrl,

[Parameter()]
[string]$TokenFile = "$env:ProgramData\EPC\ec_authtoken.machine",

[Parameter()]
[string]$EntropyText = "EPC_TOKEN_V1_LOCALMACHINE",

[Parameter()]
[string]$LogFile = "C:\Windows\Temp\ec_inventory_scanall.log",

[Parameter()]
[ValidateRange(5,300)]
[int]$TimeoutSec = 60
)

function Ensure-Dir([string]$Path) {
$d = Split-Path -Parent $Path
if ($d -and !(Test-Path $d)) {
New-Item -ItemType Directory -Path $d -Force | Out-Null
}
}

function Write-Log([string]$Msg, [ValidateSet("INFO","WARN","ERROR")]$Level="INFO") {
Ensure-Dir $LogFile
$ts = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
Add-Content -Path $LogFile -Value "$ts | $Level | $Msg" -Encoding UTF8
}

function To-Json([object]$o) {
try {
return ($o | ConvertTo-Json -Depth 10 -Compress)
} catch {
return "<json_failed>"
}
}

function Get-AuthToken-FromLocalMachineFile([string]$Path, [string]$EntropyText) {
if (!(Test-Path $Path)) { throw "Token file not found: $Path" }

$b64 = (Get-Content -Path $Path -Raw).Trim()

if ([string]::IsNullOrWhiteSpace($b64)) { throw "Token file is empty: $Path" }

Add-Type -AssemblyName System.Security
$protected = [Convert]::FromBase64String($b64)
$entropy = [Text.Encoding]::UTF8.GetBytes($EntropyText)

$bytes = [Security.Cryptography.ProtectedData]::Unprotect(
$protected,
$entropy,
[Security.Cryptography.DataProtectionScope]::LocalMachine
)

$plain = [Text.Encoding]::UTF8.GetString($bytes)

if ([string]::IsNullOrWhiteSpace($plain)) { throw "Token decrypted but returned empty." }

return $plain
}

Write-Host ""
Write-Host "Techaptic - Endpoint Central Full Inventory Scan Initiated..." -ForegroundColor Cyan
Write-Host "------------------------------------------------------------------" -ForegroundColor Cyan

try {
Write-Host "Processing: Endpoint Central server address... " -NoNewline
$ServerBaseUrl = $ServerBaseUrl.Trim().TrimEnd("/")
Write-Host "[SUCCESS] ($ServerBaseUrl)" -ForegroundColor Green

try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
} catch {}

Write-Host "Processing: Secure authentication token retrieval... " -NoNewline
$authToken = Get-AuthToken-FromLocalMachineFile -Path $TokenFile -EntropyText $EntropyText
Write-Host "[SUCCESS]" -ForegroundColor Green

$headers = @{
"Authorization" = $authToken
"Accept" = "application/json"
"Content-Type" = "application/json"
}

$url = "$ServerBaseUrl/api/1.4/inventory/computers/scanall"

Write-Host "Processing: Inventory Scan All API request... " -NoNewline
Write-Log "START | INVENTORY scanall -> POST $url"

$resp = Invoke-RestMethod -Method POST -Uri $url -Headers $headers -TimeoutSec $TimeoutSec -ErrorAction Stop

Write-Log "RESPONSE: $(To-Json $resp)"
Write-Log "DONE | Success"
Write-Host "[SUCCESS]" -ForegroundColor Green

Write-Host "------------------------------------------------------------------" -ForegroundColor Cyan
Write-Host "Process Completed. Full inventory scan request was accepted." -ForegroundColor Green
Write-Host "API Endpoint: $url" -ForegroundColor Green
Write-Host "Log File: $LogFile" -ForegroundColor Green

exit 0
}
catch {
Write-Host "[ERROR] ($($_.Exception.Message))" -ForegroundColor Red
Write-Log ("FATAL: " + $_.Exception.Message) "ERROR"

Write-Host "------------------------------------------------------------------" -ForegroundColor Cyan
Write-Host "Process Failed. Full inventory scan could not be triggered." -ForegroundColor Red
Write-Host "Log File: $LogFile" -ForegroundColor Yellow

exit 1
}

Quiz


QUIZ-EN-Custom-Solution-Shortening-Endpoint-Central-Inventory-Scan-Intervals-via-REST-API-5
  • Question
  • Question
  • Question
  • Question
  • Question

Full Transcript

Rating

Post Rating (EN)
Scroll to Top