Query Details

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, McpServers

Explanation

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:

  1. Normalize Platform Names: A function NormalizePlatform is defined to convert platform names to lowercase and remove any non-alphanumeric characters.

  2. Filter Recent Data: The query filters the data to include only records generated in the last 14 days.

  3. 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.
    • Observability and McpServers: Dynamic fields extracted from their respective columns.
  4. Filter Non-Empty Inventory IDs: Only records with a non-empty InventoryId are retained.

  5. Summarize Data: The query summarizes the data to keep the most recent record (arg_max) for each InventoryId.

  6. Normalize and Classify Platforms:

    • Platform is extracted and normalized using the NormalizePlatform function.
    • 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.
  7. Select Columns: The final output includes selected columns: Snapshot, InventoryId, InventoryAgent, EntraId, SourceId, Observability, Platform, Managed, Custom, and McpServers.

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.