I could use some help with a Powershell script for the events feed.
For some work I am doing trying to track DHCP events, I have been looking at the Events Feed API and am having trouble getting code working in Powershell. I know my API key/Account ID are good because I have other scripts/tasks running daily, but I am struggling on the event feed. I would rather avoid Python because I already have other things happening in Powershell and am not very comfortable in Python. I think I have events enabled in my account correctly.
I asked ChatGPT to review my efforts and add debugging and this is my current script. It returns 0 events. you can toggle $DEBUG_MODE = $true/$false as needed
Can someone let me know if you return results with this code? thanks.
# start script -----------------------------------------------------------------------------
# ====== CONFIGURATION ======
$API_URL = "https://api.catonetworks.com/api/v1/graphql2"
$API_KEY = "YOUR_CATO_API_KEY"
$ACCOUNT_ID = "YOUR_ACCOUNT_ID"
$DEBUG_MODE = $true
$MAX_LOOPS = 3
# ===========================
$query = @"
query EventsFeed(`$accountIDs: [ID!], `$marker: String) {
eventsFeed(accountIDs: `$accountIDs, marker: `$marker) {
marker
fetchedCount
accounts {
id
records {
time
fieldsMap
}
}
}
}
"@
function Write-DebugLog {
param(
[string]$Message,
$Data = $null
)
if (-not $DEBUG_MODE) { return }
Write-Output "[DEBUG] $Message"
if ($null -ne $Data) {
try {
if ($Data -is [string]) {
Write-Output $Data
}
else {
$json = $Data | ConvertTo-Json -Depth 20
Write-Output $json
}
}
catch {
Write-Output "[DEBUG] Could not serialize debug data."
Write-Output ($Data | Out-String)
}
}
Write-Output ("=" * 80)
}
function Print-Event {
param($Record)
$timeStr = $Record.time
try {
$dt = [datetime]::Parse($Record.time)
$timeStr = $dt.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss 'UTC'")
}
catch {}
$f = $Record.fieldsMap
Write-Output "[$timeStr] $($f.event_type) / $($f.event_sub_type): $($f.message)"
Write-Output " User: $($f.user_display_name)"
Write-Output " App: $($f.application)"
Write-Output " Src: $($f.src_ip)"
Write-Output " Dst: $($f.dest_ip)"
Write-Output ("-" * 80)
}
function Fetch-Events {
$headers = @{
"x-api-key" = $API_KEY
"Content-Type" = "application/json"
}
$marker = ""
$totalEvents = 0
$loopCount = 0
while ($true) {
$loopCount++
if ($loopCount -gt $MAX_LOOPS) {
Write-Output "[INFO] Reached MAX_LOOPS limit ($MAX_LOOPS)."
break
}
$variables = @{
accountIDs = @($ACCOUNT_ID)
marker = $marker
}
$bodyObject = @{
query = $query
variables = $variables
}
$body = $bodyObject | ConvertTo-Json -Depth 20
try {
Write-DebugLog "Request URI" $API_URL
Write-DebugLog "Request headers" @{
"x-api-key" = "***REDACTED***"
"Content-Type" = "application/json"
}
Write-DebugLog "Request variables" $variables
Write-DebugLog "Request body object" $bodyObject
Write-DebugLog "Request body JSON" $body
$response = Invoke-RestMethod `
-Uri $API_URL `
-Method Post `
-Headers $headers `
-Body $body `
-TimeoutSec 30
Write-DebugLog "Parsed API response" $response
}
catch {
Write-Error "[ERROR] API request failed: $($_.Exception.Message)"
if ($_.ErrorDetails -and $_.ErrorDetails.Message) {
Write-Output "[DEBUG] ErrorDetails:"
Write-Output $_.ErrorDetails.Message
Write-Output ("=" * 80)
}
break
}
if ($response.errors) {
Write-Error "[ERROR] API returned GraphQL errors."
Write-DebugLog "GraphQL errors" $response.errors
break
}
if (-not $response.data) {
Write-Output "[DEBUG] Response has no 'data' property."
Write-DebugLog "Full parsed response" $response
break
}
$feed = $response.data.eventsFeed
if (-not $feed) {
Write-Output "[DEBUG] Response has no 'data.eventsFeed'."
Write-DebugLog "Full parsed response" $response
break
}
Write-DebugLog "eventsFeed object" $feed
$batchCount = 0
if (-not $feed.accounts) {
Write-Output "[DEBUG] eventsFeed.accounts is null or empty."
}
else {
Write-Output "[DEBUG] Number of accounts returned: $($feed.accounts.Count)"
}
foreach ($account in $feed.accounts) {
Write-Output "[DEBUG] Inspecting account id: $($account.id)"
if (-not $account.records) {
Write-Output "[DEBUG] No records returned for this account."
continue
}
Write-Output "[DEBUG] Records returned for account $($account.id): $($account.records.Count)"
foreach ($record in $account.records) {
if ($DEBUG_MODE -and $batchCount -lt 3) {
Write-DebugLog "Sample record" $record
if ($record.fieldsMap) {
Write-DebugLog "Sample fieldsMap keys" ($record.fieldsMap.PSObject.Properties.Name)
}
}
Print-Event $record
$totalEvents++
$batchCount++
}
}
Write-Output "[INFO] Batch fetched: $($feed.fetchedCount)"
Write-Output "[DEBUG] Batch printed: $batchCount"
Write-Output "[DEBUG] Next marker: $($feed.marker)"
if (($feed.fetchedCount -eq 0) -or [string]::IsNullOrWhiteSpace($feed.marker)) {
Write-Output "[INFO] Stopping because fetchedCount is 0 or marker is empty."
break
}
$marker = $feed.marker
}
Write-Output "[INFO] Total events retrieved: $totalEvents"
}
Fetch-Events
# end script -----------------------------------------------------------------------------