Custom Agent Inventory
Query
let NormalizePlatform = (value:string) { replace_regex(tolower(value), @'[^a-z0-9]', '') };
AgentsInfo
| where TimeGenerated > ago(14d)
| extend Snapshot=coalesce(todatetime(column_ifexists('Timestamp', datetime(null))), TimeGenerated),
InventoryId=tostring(AgentId),
InventoryAgent=coalesce(tostring(column_ifexists('AgentName', '')), tostring(column_ifexists('Name', ''))),
EntraId=coalesce(tostring(column_ifexists('EntraAgentID', '')), tostring(column_ifexists('EntraAgentId', ''))),
SourceId=tostring(column_ifexists('SourceAgentId', '')),
Observability=todynamic(tostring(column_ifexists('ObservabilityID', dynamic(null)))),
McpServers=todynamic(tostring(column_ifexists('McpServers', dynamic(null))))
| where isnotempty(InventoryId)
| summarize arg_max(Snapshot, *) by InventoryId
| extend Platform=tostring(Platform), NormalizedPlatform=NormalizePlatform(tostring(Platform))
| extend Managed=NormalizedPlatform contains 'foundry' or NormalizedPlatform contains 'copilot'
or NormalizedPlatform contains 'powerplatform'
| extend Custom=not(Managed) and NormalizedPlatform in ('other', 'custom', 'sdk', 'external',
'thirdparty', 'aws', 'amazonbedrock', 'bedrock', 'amazonbedrockagentcore',
'awsbedrock', 'agentcore', 'openai', 'anthropic', 'langchain', 'langgraph')
| project Snapshot, InventoryId, InventoryAgent, EntraId, SourceId, Observability,
Platform, Managed, Custom, McpServersExplanation
This KQL query processes data from the AgentsInfo table to extract and transform information about agents over the past 14 days. Here's a simplified breakdown of what the query does:
-
Normalize Platform Names: A function
NormalizePlatformis defined to convert platform names to lowercase and remove any non-alphanumeric characters. -
Filter Recent Data: The query filters the data to include only records generated in the last 14 days.
-
Extend Columns: Several new columns are created:
Snapshot: The most recent timestamp from either the 'Timestamp' column or 'TimeGenerated'.InventoryId: The agent's ID.InventoryAgent: The agent's name, derived from either 'AgentName' or 'Name'.EntraId: The Entra agent ID, derived from either 'EntraAgentID' or 'EntraAgentId'.SourceId: The source agent ID.ObservabilityandMcpServers: Dynamic fields extracted from their respective columns.
-
Filter Non-Empty Inventory IDs: Only records with a non-empty
InventoryIdare retained. -
Summarize Data: The query summarizes the data to keep the most recent record (
arg_max) for eachInventoryId. -
Normalize and Classify Platforms:
Platformis extracted and normalized using theNormalizePlatformfunction.Managed: A boolean indicating if the normalized platform name contains 'foundry', 'copilot', or 'powerplatform'.Custom: A boolean indicating if the platform is not managed and falls into a predefined list of custom platform names.
-
Select Columns: The final output includes selected columns:
Snapshot,InventoryId,InventoryAgent,EntraId,SourceId,Observability,Platform,Managed,Custom, andMcpServers.
In summary, this query processes agent information to identify and classify platforms as either managed or custom, based on their normalized names, while retaining only the most recent data for each agent.