[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699JTP2W99SBACQS7E58CH9":3,"skill-same:01M699JTP2W99SBACQS7E58CH9":88},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":51,"commitSha":52,"skillDirectory":53,"forksCount":54,"repositoryHtmlUrl":55,"repositoryHomepageUrl":6,"ownerHtmlUrl":56,"ownerBlogUrl":57,"ownerDescription":58,"updatedAt":59,"install":60,"resources":73},"01M699JTP2W99SBACQS7E58CH9","azure-kusto-irql-graph",null,"Apply IRQL graph functions to KQL or IRQL query results for Kusto Explorer visualization. Generates Lift_To_Graph mappings and composes Graph_Render_View, Graph_Fold_By_Property, Extract_Node_*, Enrich_Node_*, and Enrich_Graph_* calls. Accepts a supplied query or limited basic natural-language source request; it is not a general natural-language-to-KQL\u002FIRQL skill. WHEN: Lift_To_Graph, Graph_Render_View, Graph_Fold_By_Property, IRQL graph enrichment, graph mapping for existing query results, icon-decorated graph, fold graph nodes. Use azure-kusto-graph for native make-graph analysis, graph-match, shortest paths, components, or persistent graphs.","microsoft\u002Fazure-skills","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699HXPKQFT1BH5KD1PG0CB4",1640,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002F.github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000013","分析与可视化","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,9,40,41,42,43],"azure kusto irql graph","azure kusto irql","azure kusto","azure","graph","query","when","request","source","natural-language","enrich","render","native","make","paths","mapping","node","analysis","visualization","components","2026-11-10 10:12:30",false,"---\nname: azure-kusto-irql-graph\ndescription: \"Apply IRQL graph functions to KQL or IRQL query results for Kusto Explorer visualization. Generates Lift_To_Graph mappings and composes Graph_Render_View, Graph_Fold_By_Property, Extract_Node_*, Enrich_Node_*, and Enrich_Graph_* calls. Accepts a supplied query or limited basic natural-language source request; it is not a general natural-language-to-KQL\u002FIRQL skill. WHEN: Lift_To_Graph, Graph_Render_View, Graph_Fold_By_Property, IRQL graph enrichment, graph mapping for existing query results, icon-decorated graph, fold graph nodes. Use azure-kusto-graph for native make-graph analysis, graph-match, shortest paths, components, or persistent graphs.\"\nlicense: MIT\nmetadata:\n  author: Microsoft\n  version: \"1.2.1\"\n---\n\n# IRQL Graph Functions -- Query Results to Visualization\n\nApply the IRQL graph function family to tabular results. Given a KQL or IRQL query and the user's graph description, generate a `Lift_To_Graph` mapping and compose only the stored graph functions needed to visualize, fold, extract, or enrich the graph in Kusto Explorer. The source query does not need to use IRQL.\n\n## Scope and Routing\n\n| Request | Use |\n|---|---|\n| Turn supplied KQL\u002FIRQL rows into an icon-decorated visual graph | This skill: `Lift_To_Graph` + `Graph_Render_View` |\n| Fold nodes or apply `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` | This skill |\n| Use `make-graph`, `graph-match`, shortest paths, connected components, graph models, or snapshots | `azure-kusto-graph` |\n| Author a non-trivial KQL\u002FIRQL investigation from natural language | A Kusto or IRQL query-generation skill, then this skill |\n\nIf a request mixes visualization and native graph analysis, use this skill for the lift\u002Frender portion and `azure-kusto-graph` for operator semantics. Do not replace graph-lift functions with a hand-built edges-first graph unless the user asks for native graph operators.\n\n## Input Contract\n\n- **Preferred input**: a working KQL\u002FIRQL query that produces tabular results, plus a natural-language description of the desired nodes, edges, labels, icons, extracts, enrichments, or folds.\n- This skill is **not a natural-language-to-KQL or NL-to-IRQL converter**. It transforms existing query results into graph visualizations. For general NL-to-KQL or NL-to-IRQL conversion, use a dedicated query-generation skill (available separately).\n- Preserve the supplied query's retrieval, joins, filters, and aggregations. Add only projections or synthetic IDs required by the graph mapping.\n- A basic natural-language source request is supported only when it maps directly to one known table or IRQL `Get_*` selector with obvious columns and simple filters. State the assumed source, and do not invent joins, schema, or investigation logic.\n- For non-trivial query construction, use a separate Kusto\u002FIRQL query-generation skill first, then apply this skill to its output.\n- If no query or output schema is available and the source is not trivial, request the KQL query or its result columns before generating a mapping.\n\n## Activation Triggers\n\nUse this skill when the user:\n- Supplies KQL\u002FIRQL results and asks for an IRQL graph visualization or mapping\n- Mentions `Lift_To_Graph`, `Graph_Render_View`, or `Graph_Fold_By_Property`\n- Asks for icon-decorated node\u002Fedge mappings in Kusto Explorer\n- Wants to fold\u002Fcollapse nodes by a shared property\n- Requests graph extraction or enrichment through `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*`\n\nDo not activate this skill solely for `graph-match`, graph paths\u002Fcomponents, persistent graphs, or generic `make-graph` construction; those belong to `azure-kusto-graph`.\n\n**Not a natural-language-to-KQL\u002FIRQL converter.** The input should generally be a working KQL or IRQL query whose results need graph visualization. Basic NL source requests work only for trivial single-table\u002Fselector cases. For general NL-to-KQL or NL-to-IRQL, use a dedicated query-generation skill (available separately).\n\n## Environment\n\n- **Cluster**: `https:\u002F\u002Fkc7001.eastus.kusto.windows.net`\n- **Databases**: `ValdyTimes`, `JoJosHospital` (graph functions pre-deployed)\n- **Rendering**: Kusto Explorer desktop app (make-graph visualization window)\n- **Tool**: `kusto_query` (via Azure MCP Server)\n\n### Function Preflight\n\n`Lift_To_Graph` and `Graph_Render_View` are stored functions, not built-in Kusto operators. Before generating or running a lift pipeline against a target database, check what is deployed:\n\n```kql\n.show functions\n| where Name in~ (\"Lift_To_Graph\", \"Graph_Render_View\", \"Graph_Fold_By_Property\")\n| project Name\n```\n\n- `Lift_To_Graph` and `Graph_Render_View` are required.\n- `Graph_Fold_By_Property` is required only when folding is requested.\n- Check any `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` function before using it; omit optional enrichment when unavailable unless the user wants it deployed.\n- If a required function is missing and you have permission to alter the database, **ask the user for confirmation before deploying**. Then use the `.create-or-alter function` definitions in [references\u002FDEPLOY_IRQL_FUNCTIONS.md](references\u002FDEPLOY_IRQL_FUNCTIONS.md). Run the relevant `.create-or-alter` block, then rerun the preflight check to confirm.\n- If you do not have alter permissions, tell the user which functions are missing and point them to `references\u002FDEPLOY_IRQL_FUNCTIONS.md` for manual deployment.\n\n## IRQL Graph Function Family\n\n### `Lift_To_Graph(T, mappingJson)`\n\nTransforms any tabular KQL result into a unified node + edge table.\n\n**Input**: Any table `T` + a JSON mapping string.\n**Output**: Rows with `EntityType` = `\"node\"` or `\"edge\"`, ready for `make-graph`.\n\n### `Graph_Render_View(T)`\n\nTakes `Lift_To_Graph` output, splits nodes\u002Fedges, and calls `make-graph` to open Kusto Explorer's graph window.\n\n### `Graph_Fold_By_Property(T, NodeType, PropertyName)`\n\nCollapses nodes of a given type sharing a property value into a single node. Rewires edges automatically.\n\n### Graph Extraction and Enrichment Functions\n\nThese are additional stored functions that must already be deployed on the target database. They are **not** bundled in `references\u002FDEPLOY_IRQL_FUNCTIONS.md`. Use `.show functions` to verify availability before including in a pipeline.\n\n| Function | Operation | Key Property |\n|---|---|---|\n| `Extract_Node_Email_Sender_Domain(T, displayName)` | Adds `Domain` to node props | `EmailSender` |\n| `Extract_Node_Employee_Firstname(T, displayName)` | Adds `Firstname` to node props | `Name` |\n| `Extract_Node_Event_Network_Domain(T, displayName)` | Adds `DomainName` to node props | `Url` |\n| `Enrich_Node_Ip_Employee(T, displayName)` | Adds employee info to IP nodes | `ClientIp` |\n| `Enrich_Node_Username_Employee(T, displayName)` | Adds employee info to user nodes | `Username` |\n| `Enrich_Node_Event_Authentication_Username(T, displayName)` | Adds auth context | `Username` |\n| `Enrich_Node_Ip_Domain(T, displayName)` | Adds DNS domains | `ClientIp` |\n| `Enrich_Node_Ip_Event_NetworkOutbound(T, displayName)` | Adds outbound events | `ClientIp` |\n| `Enrich_Graph_Ip_Employee(T, mappingJson)` | Expands graph with employee nodes | `ClientIp` |\n| `Enrich_Graph_Username_Employee(T, mappingJson)` | Expands graph with employee nodes | `Username` |\n| `Enrich_Graph_Event_Authentication_Username(T, mappingJson)` | Expands with auth nodes | `Username` |\n\n## Mapping JSON Schema\n\nThe JSON mapping has two arrays: `node_types` and `edges`.\n\n### `node_types[]`\n\n| Field | Required | Description |\n|---|---|---|\n| `type` | Yes | Node type label (e.g. `\"User\"`, `\"Host\"`, `\"IP\"`) |\n| `id` | Yes | Prefix for node ID; usually same as type |\n| `key` | Yes | Column name whose value becomes the node's identity |\n| `props` | Yes | Array of columns to carry as node properties |\n| `defaults` | No | Object of fallback values for null\u002Fempty properties |\n| `defIcon` | No | Default icon URL for this node type |\n| `displayName` | No | Column to use for display label (defaults to `id`) |\n| `color` | No | Column to source color from |\n| `size` | No | Column to source size from |\n\n### `edges[]`\n\n| Field | Required | Description |\n|---|---|---|\n| `type` | Yes | Edge type label (e.g. `\"AuthenticatesTo\"`, `\"SentEmail\"`) |\n| `source` | Yes | `{\"id\": \"\u003Cprefix>\", \"type\": \"\u003CNodeType>\"}` |\n| `target` | Yes | `{\"id\": \"\u003Cprefix>\", \"type\": \"\u003CNodeType>\"}` |\n| `props` | No | Array of columns to carry as edge properties |\n| `displayName` | No | Column for edge label |\n| `color` | No | Column for edge color |\n\n### Icon Repository\n\nUse icons from `https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002F`:\n- IP: `Public-IP-Addresses-(Classic).svg`\n- Host\u002FVM: `Virtual-Machine.svg`\n- User: `Users.svg`\n- Email: `Mailbox.svg` (or `azure-cds\u002Fcommand-1070-Mail.svg`)\n- Process: `App-Services.svg`\n- File: `Storage-Accounts.svg`\n- Alert: `Activity-Log.svg`\n- Domain: `DNS-Zones.svg`\n\n## Mapping Generation Rules\n\nGiven the supplied query columns and the user's graph description, generate the mapping JSON by:\n\n1. **Identify entities** -> each distinct noun becomes a `node_type`\n2. **Identify relationships** -> each verb\u002Fpreposition becomes an `edge`\n3. **Map to columns** -> use actual columns produced by the supplied query; never assume unavailable columns\n4. **Set direction** -> source is the actor, target is the acted-upon\n5. **Add properties** -> include columns relevant to investigation (timestamps, results, hashes)\n6. **Assign icons** -> pick from the icon set above based on entity type\n\n### Column Reference (IRQL unified schema)\n\n| Entity | Key Column | Available Props |\n|---|---|---|\n| User | `Username` | `Username`, `Name`, `Role`, `Email` |\n| Host | `Hostname` | `Hostname` |\n| IP | `ClientIp` | `ClientIp` |\n| Email Message | `Subject` | `EnvTime`, `Subject`, `Verdict`, `Url` |\n| Sender | `EmailSender` | `EmailSender`, `Domain` |\n| Recipient | `EmailRecipient` | `EmailRecipient` |\n| Process | `ProcessName` | `EnvTime`, `ProcessName`, `ProcessCommandLine`, `ProcessHash` |\n| File | `Filename` | `EnvTime`, `Filename`, `Path`, `Sha256` |\n| Domain | `DomainName` | `DomainName` |\n| Auth Event | (synthetic ID) | `EnvTime`, `UserAgent`, `Result`, `Description` |\n\n## Function Selection\n\n1. Start with the supplied KQL\u002FIRQL tabular pipeline.\n2. Use `Lift_To_Graph(mapping)` to create graph entities.\n3. Add `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` only when requested and compatible with the mapped keys.\n4. Add `Graph_Fold_By_Property()` only when grouping\u002Fcollapse is requested.\n5. End visual output with `Graph_Render_View()`.\n6. Preflight the exact stored functions selected for the pipeline.\n\n## Pipeline Pattern\n\n```kql\n\u002F\u002F 1. Preserve the supplied KQL or IRQL query\n\u003Cinput query>\n\u002F\u002F 2. Lift to graph\n| invoke Lift_To_Graph(\u003Cmapping_json>)\n\u002F\u002F 3. Optionally extract or enrich graph entities\n| invoke \u003CExtract_Node_* | Enrich_Node_* | Enrich_Graph_*>()\n\u002F\u002F 4. Optionally fold nodes when requested\n| invoke Graph_Fold_By_Property(\"\u003CNodeType>\", \"\u003CPropertyName>\")\n\u002F\u002F 5. Render\n| invoke Graph_Render_View()\n```\n\n## Examples\n\nFor additional prompts and worked examples, see [references\u002FEXAMPLES.md](references\u002FEXAMPLES.md).\n\n### Authentication graph: IP -> AuthEvent -> User -> Host\n\n**Input query**: `Get_Event_Authentication_All | where Result == \"Failed Login\" | take 200`\n\n**Graph request**: \"Show IPs, authentication events, users, and hosts; fold events by result.\"\n\n```kql\nlet auth_mapping = '{\"node_types\":[{\"type\":\"SrcIp\",\"id\":\"SrcIp\",\"key\":\"ClientIp\",\"props\":[\"ClientIp\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FPublic-IP-Addresses-(Classic).svg\"},{\"type\":\"Host\",\"id\":\"Host\",\"key\":\"Hostname\",\"props\":[\"Hostname\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FVirtual-Machine.svg\"},{\"type\":\"User\",\"id\":\"User\",\"key\":\"Username\",\"props\":[\"Username\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FUsers.svg\"},{\"type\":\"AuthEvent\",\"id\":\"AuthEvent\",\"key\":\"AuthEventId\",\"props\":[\"AuthEventId\",\"EnvTime\",\"UserAgent\",\"Result\",\"Description\"],\"defaults\":{\"Result\":\"unknown\"},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FActivity-Log.svg\"}],\"edges\":[{\"type\":\"RequestsAuth\",\"source\":{\"id\":\"SrcIp\",\"type\":\"SrcIp\"},\"target\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"props\":[\"EnvTime\"]},{\"type\":\"TargetsUser\",\"source\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"target\":{\"id\":\"User\",\"type\":\"User\"},\"props\":[\"EnvTime\"]},{\"type\":\"AgainstHost\",\"source\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"target\":{\"id\":\"Host\",\"type\":\"Host\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_Authentication_All\n| extend AuthEventId = strcat(Username, \"_\", Hostname, \"_\", EnvTime)\n| where Result == \"Failed Login\"\n| take 200\n| invoke Lift_To_Graph(auth_mapping)\n| invoke Graph_Fold_By_Property(\"AuthEvent\", \"Result\")\n| invoke Graph_Render_View()\n```\n\n### Email graph: Sender -> Message -> Recipient\n\n**Input query**: `Get_Email_All | take 400`\n\n**Graph request**: \"Visualize sender-to-message-to-recipient flow and fold messages by verdict.\"\n\n```kql\nlet mail_mapping = '{\"node_types\":[{\"type\":\"EmailMessage\",\"id\":\"Message\",\"key\":\"Subject\",\"props\":[\"EnvTime\",\"Subject\",\"Verdict\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FMedia-File.svg\"},{\"type\":\"Sender\",\"id\":\"Email\",\"key\":\"EmailSender\",\"props\":[\"EmailSender\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-cds\u002Fcommand-1070-Mail.svg\"},{\"type\":\"Recipient\",\"id\":\"Email\",\"key\":\"EmailRecipient\",\"props\":[\"EmailRecipient\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-cds\u002Fcommand-1070-Mail.svg\"}],\"edges\":[{\"type\":\"SentBy\",\"source\":{\"id\":\"Message\",\"type\":\"EmailMessage\"},\"target\":{\"id\":\"Email\",\"type\":\"Sender\"},\"props\":[\"EnvTime\",\"Verdict\"]},{\"type\":\"DeliveredTo\",\"source\":{\"id\":\"Message\",\"type\":\"EmailMessage\"},\"target\":{\"id\":\"Email\",\"type\":\"Recipient\"},\"props\":[\"EnvTime\",\"Verdict\"]}]}';\nGet_Email_All\n| take 400\n| invoke Lift_To_Graph(mail_mapping)\n| invoke Graph_Fold_By_Property(\"EmailMessage\", \"Verdict\")\n| invoke Graph_Render_View()\n```\n\n### Suspicious domain investigation (end-to-end)\n\n**Basic source request**: \"Use outbound network events for these suspicious domains and graph IP-to-domain connections enriched with employee names.\"\n\nThis is the limited fallback: one known selector, one extractor, and one direct filter.\n\n```kql\nlet suspicious_domain_mapping = '{\"node_types\":[{\"type\":\"IP\",\"id\":\"IP\",\"key\":\"ClientIp\",\"props\":[\"ClientIp\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FPublic-IP-Addresses-(Classic).svg\"},{\"type\":\"Domain\",\"id\":\"Domain\",\"key\":\"DomainName\",\"props\":[\"DomainName\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FDNS-Zones.svg\"}],\"edges\":[{\"type\":\"ConnectsTo\",\"source\":{\"id\":\"IP\",\"type\":\"IP\"},\"target\":{\"id\":\"Domain\",\"type\":\"Domain\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_NetworkOutbound\n| invoke Extract_Event_Network_Domain()\n| where DomainName has_any (\"raisinkanes.com\", \"nothing-to-see-here.net\", \"totally-legit-domain.com\")\n| invoke Lift_To_Graph(suspicious_domain_mapping)\n| invoke Enrich_Node_Ip_Employee(\"Name\")\n| invoke Graph_Fold_By_Property(\"Domain\", \"DomainName\")\n| invoke Graph_Render_View()\n```\n\n### Process execution graph: User -> Process -> ParentProcess\n\n**Input query**: `Get_Event_Process_All | where ProcessCommandLine has \"powershell\" | take 300`\n\n**Graph request**: \"Visualize process, parent process, host, and user relationships.\"\n\n```kql\nlet proc_mapping = '{\"node_types\":[{\"type\":\"Process\",\"id\":\"Proc\",\"key\":\"ProcessName\",\"props\":[\"ProcessName\",\"ProcessCommandLine\",\"ProcessHash\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FApp-Services.svg\"},{\"type\":\"ParentProcess\",\"id\":\"Proc\",\"key\":\"ParentProcessName\",\"props\":[\"ParentProcessName\",\"ParentProcessHash\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FApp-Services.svg\"},{\"type\":\"Host\",\"id\":\"Host\",\"key\":\"Hostname\",\"props\":[\"Hostname\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FVirtual-Machine.svg\"},{\"type\":\"User\",\"id\":\"User\",\"key\":\"Username\",\"props\":[\"Username\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FUsers.svg\"}],\"edges\":[{\"type\":\"SpawnedBy\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"Proc\",\"type\":\"ParentProcess\"},\"props\":[\"EnvTime\"]},{\"type\":\"RanOn\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"Host\",\"type\":\"Host\"},\"props\":[\"EnvTime\"]},{\"type\":\"ExecutedBy\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"User\",\"type\":\"User\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_Process_All\n| where ProcessCommandLine has \"powershell\"\n| take 300\n| invoke Lift_To_Graph(proc_mapping)\n| invoke Graph_Render_View()\n```\n\n## Query Results -> Mapping Translation\n\nWhen the user supplies a query and describes the graph:\n\n1. Inspect the query's final output columns\n2. Parse the entity nouns and relationship verbs\n3. Generate the mapping JSON using only those columns\n4. Preserve the supplied pipeline and append `Lift_To_Graph()`\n5. Include `Graph_Render_View()` at the end\n6. If the user mentions grouping\u002Fcollapsing and the function exists, add `Graph_Fold_By_Property()`\n\nOutput the complete KQL -- the supplied query plus mapping JSON inline as a string `let` binding -- after the required-function preflight passes. Clearly mark unverified function dependencies when the target database cannot be checked.\n\n## Opening Queries in Kusto Explorer (Windows Only)\n\n> **Optional convenience feature.** The default workflow is to output the KQL in chat and let the user copy it into Kusto Explorer or the VS Code Kusto extension manually. Auto-launch is opt-in only.\n\nAlways output the complete KQL query in the chat response with Step 1 (connect) and Step 2 (query) clearly labeled:\n\n```\n\u002F\u002F Step 1: Connect to your cluster (skip if already connected)\n\u002F\u002F Example: uncomment to connect to the KC7 training cluster\n\u002F\u002F #connect cluster('kc7001.eastus.kusto.windows.net').database('ValdyTimes')\n\u002F\u002F Or replace with your own cluster:\n\u002F\u002F #connect cluster('\u003CYOUR_CLUSTER>').database('\u003CYOUR_DATABASE>')\n\n\u002F\u002F Step 2: Run the query below\n\u003CKQL_QUERY>\n```\n\nIf the user asks to save or open in Kusto Explorer, follow the procedure in [references\u002FKUSTO_EXPLORER_LAUNCH.md](references\u002FKUSTO_EXPLORER_LAUNCH.md). Key rules:\n\n- Use `ask_user` to confirm before writing files or launching executables\n- Display file contents in chat so the user can review before opening\n- Never use shell interpolation or here-strings — write files via `Set-Content`\u002F`Add-Content`\n- Never encode queries into browser URLs\n- On macOS\u002FLinux, save the `.kql` file and suggest the VS Code Kusto extension or ADX Web Explorer\n","# IRQL Graph Functions -- Query Results to Visualization\n\nApply the IRQL graph function family to tabular results. Given a KQL or IRQL query and the user's graph description, generate a `Lift_To_Graph` mapping and compose only the stored graph functions needed to visualize, fold, extract, or enrich the graph in Kusto Explorer. The source query does not need to use IRQL.\n\n## Scope and Routing\n\n| Request | Use |\n|---|---|\n| Turn supplied KQL\u002FIRQL rows into an icon-decorated visual graph | This skill: `Lift_To_Graph` + `Graph_Render_View` |\n| Fold nodes or apply `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` | This skill |\n| Use `make-graph`, `graph-match`, shortest paths, connected components, graph models, or snapshots | `azure-kusto-graph` |\n| Author a non-trivial KQL\u002FIRQL investigation from natural language | A Kusto or IRQL query-generation skill, then this skill |\n\nIf a request mixes visualization and native graph analysis, use this skill for the lift\u002Frender portion and `azure-kusto-graph` for operator semantics. Do not replace graph-lift functions with a hand-built edges-first graph unless the user asks for native graph operators.\n\n## Input Contract\n\n- **Preferred input**: a working KQL\u002FIRQL query that produces tabular results, plus a natural-language description of the desired nodes, edges, labels, icons, extracts, enrichments, or folds.\n- This skill is **not a natural-language-to-KQL or NL-to-IRQL converter**. It transforms existing query results into graph visualizations. For general NL-to-KQL or NL-to-IRQL conversion, use a dedicated query-generation skill (available separately).\n- Preserve the supplied query's retrieval, joins, filters, and aggregations. Add only projections or synthetic IDs required by the graph mapping.\n- A basic natural-language source request is supported only when it maps directly to one known table or IRQL `Get_*` selector with obvious columns and simple filters. State the assumed source, and do not invent joins, schema, or investigation logic.\n- For non-trivial query construction, use a separate Kusto\u002FIRQL query-generation skill first, then apply this skill to its output.\n- If no query or output schema is available and the source is not trivial, request the KQL query or its result columns before generating a mapping.\n\n## Activation Triggers\n\nUse this skill when the user:\n- Supplies KQL\u002FIRQL results and asks for an IRQL graph visualization or mapping\n- Mentions `Lift_To_Graph`, `Graph_Render_View`, or `Graph_Fold_By_Property`\n- Asks for icon-decorated node\u002Fedge mappings in Kusto Explorer\n- Wants to fold\u002Fcollapse nodes by a shared property\n- Requests graph extraction or enrichment through `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*`\n\nDo not activate this skill solely for `graph-match`, graph paths\u002Fcomponents, persistent graphs, or generic `make-graph` construction; those belong to `azure-kusto-graph`.\n\n**Not a natural-language-to-KQL\u002FIRQL converter.** The input should generally be a working KQL or IRQL query whose results need graph visualization. Basic NL source requests work only for trivial single-table\u002Fselector cases. For general NL-to-KQL or NL-to-IRQL, use a dedicated query-generation skill (available separately).\n\n## Environment\n\n- **Cluster**: `https:\u002F\u002Fkc7001.eastus.kusto.windows.net`\n- **Databases**: `ValdyTimes`, `JoJosHospital` (graph functions pre-deployed)\n- **Rendering**: Kusto Explorer desktop app (make-graph visualization window)\n- **Tool**: `kusto_query` (via Azure MCP Server)\n\n### Function Preflight\n\n`Lift_To_Graph` and `Graph_Render_View` are stored functions, not built-in Kusto operators. Before generating or running a lift pipeline against a target database, check what is deployed:\n\n```kql\n.show functions\n| where Name in~ (\"Lift_To_Graph\", \"Graph_Render_View\", \"Graph_Fold_By_Property\")\n| project Name\n```\n\n- `Lift_To_Graph` and `Graph_Render_View` are required.\n- `Graph_Fold_By_Property` is required only when folding is requested.\n- Check any `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` function before using it; omit optional enrichment when unavailable unless the user wants it deployed.\n- If a required function is missing and you have permission to alter the database, **ask the user for confirmation before deploying**. Then use the `.create-or-alter function` definitions in [references\u002FDEPLOY_IRQL_FUNCTIONS.md](references\u002FDEPLOY_IRQL_FUNCTIONS.md). Run the relevant `.create-or-alter` block, then rerun the preflight check to confirm.\n- If you do not have alter permissions, tell the user which functions are missing and point them to `references\u002FDEPLOY_IRQL_FUNCTIONS.md` for manual deployment.\n\n## IRQL Graph Function Family\n\n### `Lift_To_Graph(T, mappingJson)`\n\nTransforms any tabular KQL result into a unified node + edge table.\n\n**Input**: Any table `T` + a JSON mapping string.\n**Output**: Rows with `EntityType` = `\"node\"` or `\"edge\"`, ready for `make-graph`.\n\n### `Graph_Render_View(T)`\n\nTakes `Lift_To_Graph` output, splits nodes\u002Fedges, and calls `make-graph` to open Kusto Explorer's graph window.\n\n### `Graph_Fold_By_Property(T, NodeType, PropertyName)`\n\nCollapses nodes of a given type sharing a property value into a single node. Rewires edges automatically.\n\n### Graph Extraction and Enrichment Functions\n\nThese are additional stored functions that must already be deployed on the target database. They are **not** bundled in `references\u002FDEPLOY_IRQL_FUNCTIONS.md`. Use `.show functions` to verify availability before including in a pipeline.\n\n| Function | Operation | Key Property |\n|---|---|---|\n| `Extract_Node_Email_Sender_Domain(T, displayName)` | Adds `Domain` to node props | `EmailSender` |\n| `Extract_Node_Employee_Firstname(T, displayName)` | Adds `Firstname` to node props | `Name` |\n| `Extract_Node_Event_Network_Domain(T, displayName)` | Adds `DomainName` to node props | `Url` |\n| `Enrich_Node_Ip_Employee(T, displayName)` | Adds employee info to IP nodes | `ClientIp` |\n| `Enrich_Node_Username_Employee(T, displayName)` | Adds employee info to user nodes | `Username` |\n| `Enrich_Node_Event_Authentication_Username(T, displayName)` | Adds auth context | `Username` |\n| `Enrich_Node_Ip_Domain(T, displayName)` | Adds DNS domains | `ClientIp` |\n| `Enrich_Node_Ip_Event_NetworkOutbound(T, displayName)` | Adds outbound events | `ClientIp` |\n| `Enrich_Graph_Ip_Employee(T, mappingJson)` | Expands graph with employee nodes | `ClientIp` |\n| `Enrich_Graph_Username_Employee(T, mappingJson)` | Expands graph with employee nodes | `Username` |\n| `Enrich_Graph_Event_Authentication_Username(T, mappingJson)` | Expands with auth nodes | `Username` |\n\n## Mapping JSON Schema\n\nThe JSON mapping has two arrays: `node_types` and `edges`.\n\n### `node_types[]`\n\n| Field | Required | Description |\n|---|---|---|\n| `type` | Yes | Node type label (e.g. `\"User\"`, `\"Host\"`, `\"IP\"`) |\n| `id` | Yes | Prefix for node ID; usually same as type |\n| `key` | Yes | Column name whose value becomes the node's identity |\n| `props` | Yes | Array of columns to carry as node properties |\n| `defaults` | No | Object of fallback values for null\u002Fempty properties |\n| `defIcon` | No | Default icon URL for this node type |\n| `displayName` | No | Column to use for display label (defaults to `id`) |\n| `color` | No | Column to source color from |\n| `size` | No | Column to source size from |\n\n### `edges[]`\n\n| Field | Required | Description |\n|---|---|---|\n| `type` | Yes | Edge type label (e.g. `\"AuthenticatesTo\"`, `\"SentEmail\"`) |\n| `source` | Yes | `{\"id\": \"\u003Cprefix>\", \"type\": \"\u003CNodeType>\"}` |\n| `target` | Yes | `{\"id\": \"\u003Cprefix>\", \"type\": \"\u003CNodeType>\"}` |\n| `props` | No | Array of columns to carry as edge properties |\n| `displayName` | No | Column for edge label |\n| `color` | No | Column for edge color |\n\n### Icon Repository\n\nUse icons from `https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002F`:\n- IP: `Public-IP-Addresses-(Classic).svg`\n- Host\u002FVM: `Virtual-Machine.svg`\n- User: `Users.svg`\n- Email: `Mailbox.svg` (or `azure-cds\u002Fcommand-1070-Mail.svg`)\n- Process: `App-Services.svg`\n- File: `Storage-Accounts.svg`\n- Alert: `Activity-Log.svg`\n- Domain: `DNS-Zones.svg`\n\n## Mapping Generation Rules\n\nGiven the supplied query columns and the user's graph description, generate the mapping JSON by:\n\n1. **Identify entities** -> each distinct noun becomes a `node_type`\n2. **Identify relationships** -> each verb\u002Fpreposition becomes an `edge`\n3. **Map to columns** -> use actual columns produced by the supplied query; never assume unavailable columns\n4. **Set direction** -> source is the actor, target is the acted-upon\n5. **Add properties** -> include columns relevant to investigation (timestamps, results, hashes)\n6. **Assign icons** -> pick from the icon set above based on entity type\n\n### Column Reference (IRQL unified schema)\n\n| Entity | Key Column | Available Props |\n|---|---|---|\n| User | `Username` | `Username`, `Name`, `Role`, `Email` |\n| Host | `Hostname` | `Hostname` |\n| IP | `ClientIp` | `ClientIp` |\n| Email Message | `Subject` | `EnvTime`, `Subject`, `Verdict`, `Url` |\n| Sender | `EmailSender` | `EmailSender`, `Domain` |\n| Recipient | `EmailRecipient` | `EmailRecipient` |\n| Process | `ProcessName` | `EnvTime`, `ProcessName`, `ProcessCommandLine`, `ProcessHash` |\n| File | `Filename` | `EnvTime`, `Filename`, `Path`, `Sha256` |\n| Domain | `DomainName` | `DomainName` |\n| Auth Event | (synthetic ID) | `EnvTime`, `UserAgent`, `Result`, `Description` |\n\n## Function Selection\n\n1. Start with the supplied KQL\u002FIRQL tabular pipeline.\n2. Use `Lift_To_Graph(mapping)` to create graph entities.\n3. Add `Extract_Node_*`, `Enrich_Node_*`, or `Enrich_Graph_*` only when requested and compatible with the mapped keys.\n4. Add `Graph_Fold_By_Property()` only when grouping\u002Fcollapse is requested.\n5. End visual output with `Graph_Render_View()`.\n6. Preflight the exact stored functions selected for the pipeline.\n\n## Pipeline Pattern\n\n```kql\n\u002F\u002F 1. Preserve the supplied KQL or IRQL query\n\u003Cinput query>\n\u002F\u002F 2. Lift to graph\n| invoke Lift_To_Graph(\u003Cmapping_json>)\n\u002F\u002F 3. Optionally extract or enrich graph entities\n| invoke \u003CExtract_Node_* | Enrich_Node_* | Enrich_Graph_*>()\n\u002F\u002F 4. Optionally fold nodes when requested\n| invoke Graph_Fold_By_Property(\"\u003CNodeType>\", \"\u003CPropertyName>\")\n\u002F\u002F 5. Render\n| invoke Graph_Render_View()\n```\n\n## Examples\n\nFor additional prompts and worked examples, see [references\u002FEXAMPLES.md](references\u002FEXAMPLES.md).\n\n### Authentication graph: IP -> AuthEvent -> User -> Host\n\n**Input query**: `Get_Event_Authentication_All | where Result == \"Failed Login\" | take 200`\n\n**Graph request**: \"Show IPs, authentication events, users, and hosts; fold events by result.\"\n\n```kql\nlet auth_mapping = '{\"node_types\":[{\"type\":\"SrcIp\",\"id\":\"SrcIp\",\"key\":\"ClientIp\",\"props\":[\"ClientIp\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FPublic-IP-Addresses-(Classic).svg\"},{\"type\":\"Host\",\"id\":\"Host\",\"key\":\"Hostname\",\"props\":[\"Hostname\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FVirtual-Machine.svg\"},{\"type\":\"User\",\"id\":\"User\",\"key\":\"Username\",\"props\":[\"Username\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FUsers.svg\"},{\"type\":\"AuthEvent\",\"id\":\"AuthEvent\",\"key\":\"AuthEventId\",\"props\":[\"AuthEventId\",\"EnvTime\",\"UserAgent\",\"Result\",\"Description\"],\"defaults\":{\"Result\":\"unknown\"},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FActivity-Log.svg\"}],\"edges\":[{\"type\":\"RequestsAuth\",\"source\":{\"id\":\"SrcIp\",\"type\":\"SrcIp\"},\"target\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"props\":[\"EnvTime\"]},{\"type\":\"TargetsUser\",\"source\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"target\":{\"id\":\"User\",\"type\":\"User\"},\"props\":[\"EnvTime\"]},{\"type\":\"AgainstHost\",\"source\":{\"id\":\"AuthEvent\",\"type\":\"AuthEvent\"},\"target\":{\"id\":\"Host\",\"type\":\"Host\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_Authentication_All\n| extend AuthEventId = strcat(Username, \"_\", Hostname, \"_\", EnvTime)\n| where Result == \"Failed Login\"\n| take 200\n| invoke Lift_To_Graph(auth_mapping)\n| invoke Graph_Fold_By_Property(\"AuthEvent\", \"Result\")\n| invoke Graph_Render_View()\n```\n\n### Email graph: Sender -> Message -> Recipient\n\n**Input query**: `Get_Email_All | take 400`\n\n**Graph request**: \"Visualize sender-to-message-to-recipient flow and fold messages by verdict.\"\n\n```kql\nlet mail_mapping = '{\"node_types\":[{\"type\":\"EmailMessage\",\"id\":\"Message\",\"key\":\"Subject\",\"props\":[\"EnvTime\",\"Subject\",\"Verdict\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FMedia-File.svg\"},{\"type\":\"Sender\",\"id\":\"Email\",\"key\":\"EmailSender\",\"props\":[\"EmailSender\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-cds\u002Fcommand-1070-Mail.svg\"},{\"type\":\"Recipient\",\"id\":\"Email\",\"key\":\"EmailRecipient\",\"props\":[\"EmailRecipient\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-cds\u002Fcommand-1070-Mail.svg\"}],\"edges\":[{\"type\":\"SentBy\",\"source\":{\"id\":\"Message\",\"type\":\"EmailMessage\"},\"target\":{\"id\":\"Email\",\"type\":\"Sender\"},\"props\":[\"EnvTime\",\"Verdict\"]},{\"type\":\"DeliveredTo\",\"source\":{\"id\":\"Message\",\"type\":\"EmailMessage\"},\"target\":{\"id\":\"Email\",\"type\":\"Recipient\"},\"props\":[\"EnvTime\",\"Verdict\"]}]}';\nGet_Email_All\n| take 400\n| invoke Lift_To_Graph(mail_mapping)\n| invoke Graph_Fold_By_Property(\"EmailMessage\", \"Verdict\")\n| invoke Graph_Render_View()\n```\n\n### Suspicious domain investigation (end-to-end)\n\n**Basic source request**: \"Use outbound network events for these suspicious domains and graph IP-to-domain connections enriched with employee names.\"\n\nThis is the limited fallback: one known selector, one extractor, and one direct filter.\n\n```kql\nlet suspicious_domain_mapping = '{\"node_types\":[{\"type\":\"IP\",\"id\":\"IP\",\"key\":\"ClientIp\",\"props\":[\"ClientIp\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FPublic-IP-Addresses-(Classic).svg\"},{\"type\":\"Domain\",\"id\":\"Domain\",\"key\":\"DomainName\",\"props\":[\"DomainName\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FDNS-Zones.svg\"}],\"edges\":[{\"type\":\"ConnectsTo\",\"source\":{\"id\":\"IP\",\"type\":\"IP\"},\"target\":{\"id\":\"Domain\",\"type\":\"Domain\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_NetworkOutbound\n| invoke Extract_Event_Network_Domain()\n| where DomainName has_any (\"raisinkanes.com\", \"nothing-to-see-here.net\", \"totally-legit-domain.com\")\n| invoke Lift_To_Graph(suspicious_domain_mapping)\n| invoke Enrich_Node_Ip_Employee(\"Name\")\n| invoke Graph_Fold_By_Property(\"Domain\", \"DomainName\")\n| invoke Graph_Render_View()\n```\n\n### Process execution graph: User -> Process -> ParentProcess\n\n**Input query**: `Get_Event_Process_All | where ProcessCommandLine has \"powershell\" | take 300`\n\n**Graph request**: \"Visualize process, parent process, host, and user relationships.\"\n\n```kql\nlet proc_mapping = '{\"node_types\":[{\"type\":\"Process\",\"id\":\"Proc\",\"key\":\"ProcessName\",\"props\":[\"ProcessName\",\"ProcessCommandLine\",\"ProcessHash\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FApp-Services.svg\"},{\"type\":\"ParentProcess\",\"id\":\"Proc\",\"key\":\"ParentProcessName\",\"props\":[\"ParentProcessName\",\"ParentProcessHash\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FApp-Services.svg\"},{\"type\":\"Host\",\"id\":\"Host\",\"key\":\"Hostname\",\"props\":[\"Hostname\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FVirtual-Machine.svg\"},{\"type\":\"User\",\"id\":\"User\",\"key\":\"Username\",\"props\":[\"Username\"],\"defaults\":{},\"defIcon\":\"https:\u002F\u002Fraw.githubusercontent.com\u002Fbenc-uk\u002Ficon-collection\u002Fmaster\u002Fazure-icons\u002FUsers.svg\"}],\"edges\":[{\"type\":\"SpawnedBy\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"Proc\",\"type\":\"ParentProcess\"},\"props\":[\"EnvTime\"]},{\"type\":\"RanOn\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"Host\",\"type\":\"Host\"},\"props\":[\"EnvTime\"]},{\"type\":\"ExecutedBy\",\"source\":{\"id\":\"Proc\",\"type\":\"Process\"},\"target\":{\"id\":\"User\",\"type\":\"User\"},\"props\":[\"EnvTime\"]}]}';\nGet_Event_Process_All\n| where ProcessCommandLine has \"powershell\"\n| take 300\n| invoke Lift_To_Graph(proc_mapping)\n| invoke Graph_Render_View()\n```\n\n## Query Results -> Mapping Translation\n\nWhen the user supplies a query and describes the graph:\n\n1. Inspect the query's final output columns\n2. Parse the entity nouns and relationship verbs\n3. Generate the mapping JSON using only those columns\n4. Preserve the supplied pipeline and append `Lift_To_Graph()`\n5. Include `Graph_Render_View()` at the end\n6. If the user mentions grouping\u002Fcollapsing and the function exists, add `Graph_Fold_By_Property()`\n\nOutput the complete KQL -- the supplied query plus mapping JSON inline as a string `let` binding -- after the required-function preflight passes. Clearly mark unverified function dependencies when the target database cannot be checked.\n\n## Opening Queries in Kusto Explorer (Windows Only)\n\n> **Optional convenience feature.** The default workflow is to output the KQL in chat and let the user copy it into Kusto Explorer or the VS Code Kusto extension manually. Auto-launch is opt-in only.\n\nAlways output the complete KQL query in the chat response with Step 1 (connect) and Step 2 (query) clearly labeled:\n\n```\n\u002F\u002F Step 1: Connect to your cluster (skip if already connected)\n\u002F\u002F Example: uncomment to connect to the KC7 training cluster\n\u002F\u002F #connect cluster('kc7001.eastus.kusto.windows.net').database('ValdyTimes')\n\u002F\u002F Or replace with your own cluster:\n\u002F\u002F #connect cluster('\u003CYOUR_CLUSTER>').database('\u003CYOUR_DATABASE>')\n\n\u002F\u002F Step 2: Run the query below\n\u003CKQL_QUERY>\n```\n\nIf the user asks to save or open in Kusto Explorer, follow the procedure in [references\u002FKUSTO_EXPLORER_LAUNCH.md](references\u002FKUSTO_EXPLORER_LAUNCH.md). Key rules:\n\n- Use `ask_user` to confirm before writing files or launching executables\n- Display file contents in chat so the user can review before opening\n- Never use shell interpolation or here-strings — write files via `Set-Content`\u002F`Add-Content`\n- Never encode queries into browser URLs\n- On macOS\u002FLinux, save the `.kql` file and suggest the VS Code Kusto extension or ADX Web Explorer\n",{"name":5,"license":15,"metadata":49,"description":7},{"author":12,"version":50},"1.2.1","main","fbda857c484a85c7ce644f56809b7f204471fb69",".github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph",267,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-14 01:56:00",{"source":8,"skillName":5,"commands":61,"prompt":71,"zipAvailable":72},[62,65,68],{"tool":63,"command":64},"npx","npx skills add microsoft\u002Fazure-skills --skill azure-kusto-irql-graph",{"tool":66,"command":67},"bunx","bunx skills add microsoft\u002Fazure-skills --skill azure-kusto-irql-graph",{"tool":69,"command":70},"pnpm","pnpm dlx skills add microsoft\u002Fazure-skills --skill azure-kusto-irql-graph","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002F.github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph\u002FSKILL.md",true,[74,80,84],{"path":75,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":78,"sourceHtmlUrl":79},"references\u002FDEPLOY_IRQL_FUNCTIONS.md","REFERENCE","参考文档",11414,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002F.github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph\u002Freferences\u002FDEPLOY_IRQL_FUNCTIONS.md",{"path":81,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":82,"sourceHtmlUrl":83},"references\u002FEXAMPLES.md",3642,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002F.github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph\u002Freferences\u002FEXAMPLES.md",{"path":85,"resourceType":76,"resourceTypeDesc":77,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002FKUSTO_EXPLORER_LAUNCH.md",2659,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002F.github\u002Fplugins\u002Fazure-kusto-graph-skills\u002Fskills\u002Fazure-kusto-irql-graph\u002Freferences\u002FKUSTO_EXPLORER_LAUNCH.md",[89,117,144,166,182,199],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":98,"publishedAt":44},"01M699VFT1T15GFDGC4K4ZHY4N","python-appservice-deploy","Deploy Python (Flask\u002FDjango\u002FFastAPI) code to Azure App Service Linux. WHEN: \"Flask App Service\", \"Django App Service\", \"FastAPI App Service\", \"deploy Python to App Service\". DO NOT USE FOR: Container Apps, Functions, non-Python, Terraform\u002FBicep\u002FIaC, full infra — use azure-prepare.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fpython-appservice-deploy\u002FSKILL.md",[95],{"categoryNo":96,"categoryName":97,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",[99,100,101,102,103,104,105,106,107,108,27,109,110,111,112,113,30,114,115,116],"python appservice deploy","deploy","python","linux","infra","app","do","django","for","azure app service","container","iac","fastapi","use","apps","code","functions","fastapi app",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":127,"publishedAt":44},"01M699VDV3PT5P0YDXRT4GM2TJ","preset","Intelligently deploys Azure OpenAI models to optimal regions by analyzing capacity across all available regions. Automatically checks current region first and shows alternatives if needed. USE FOR: quick deployment, optimal region, best region, automatic region selection, fast setup, multi-region capacity check, high availability deployment, deploy to best location. DO NOT USE FOR: custom SKU selection (use customize), specific version selection (use customize), custom capacity configuration (use customize), PTU deployments (use customize).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft-foundry\u002Fmodels\u002Fdeploy-model\u002Fpreset\u002FSKILL.md",[123,124],{"categoryNo":96,"categoryName":97,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":125,"categoryName":126,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[119,100,128,9,129,130,105,131,132,107,133,134,135,27,136,137,138,112,139,140,141,142,143],"setup","capacity","customize","quick","availability","deployment","alternatives","selection","custom","deployments","high availability","version","across","check","multi","first",{"skillNo":145,"name":130,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":150,"publishedAt":44},"01M699VBT6YFAKBWCK890XDB6N","Interactive guided deployment flow for Azure OpenAI models with full customization control. Step-by-step selection of model version, SKU (GlobalStandard\u002FStandard\u002FProvisionedManaged), capacity, RAI policy (content filter), and advanced options (dynamic quota, priority processing, spillover). USE FOR: custom deployment, customize model deployment, choose version, select SKU, set capacity, configure content filter, RAI policy, deployment options, detailed deployment, advanced deployment, PTU deployment, provisioned throughput. DO NOT USE FOR: quick deployment to optimal region (use preset).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft-foundry\u002Fmodels\u002Fdeploy-model\u002Fcustomize\u002FSKILL.md",[149],{"categoryNo":125,"categoryName":126,"taxonomyType":21,"taxonomyTypeDesc":22},[130,119,9,129,151,152,131,153,154,155,156,157,135,158,159,160,161,162,163,164,165,105,107,133],"policy","SET","processing","advanced","model","select","choose","configure","filter","azure openai","options","flow","openai","throughput","full",{"skillNo":167,"name":129,"nameZh":6,"description":168,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":44},"01M699V9FXHBSWG3Y48057VAYZ","Discovers available Azure OpenAI model capacity across regions and projects. Analyzes quota limits, compares availability, and recommends optimal deployment locations based on capacity requirements. USE FOR: find capacity, check quota, where can I deploy, capacity discovery, best region for capacity, multi-project capacity search, quota analysis, model availability, region comparison, check TPM availability. DO NOT USE FOR: actual deployment (hand off to preset or customize after discovery), quota increase requests (direct user to Azure Portal), listing existing deployments.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft-foundry\u002Fmodels\u002Fdeploy-model\u002Fcapacity\u002FSKILL.md",[],[129,119,100,9,130,172,155,173,174,41,175,176,140,160,177,178,163,179,180,105,132,107,181,133],"projects","project","search","listing","hand","limits","azure portal","direct","TPM","discovery",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":186,"categories":187,"keywords":190,"publishedAt":44},"01M699V7GW2RF4AB3RE3Z8Y048","deploy-model","Unified Azure OpenAI model deployment skill with intelligent intent-based routing. Handles quick preset deployments, fully customized deployments (version\u002FSKU\u002Fcapacity\u002FRAI policy), and capacity discovery across regions and projects. USE FOR: deploy model, deploy gpt, create deployment, model deployment, deploy openai model, set up model, provision model, find capacity, check model availability, where can I deploy, best region for model, capacity analysis. DO NOT USE FOR: listing existing deployments (use foundry_models_deployments_list MCP tool), deleting deployments, agent creation (use agent\u002Fcreate), project creation (use project\u002Fcreate).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft-foundry\u002Fmodels\u002Fdeploy-model\u002FSKILL.md",[188,189],{"categoryNo":96,"categoryName":97,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":125,"categoryName":126,"taxonomyType":21,"taxonomyTypeDesc":22},[100,191,155,119,192,193,9,129,151,152,172,131,194,173,195,41,175,140,196,160,197,198,163,105,132],"deploy model","MCP","foundry","creation","up","create","intent","list",{"skillNo":200,"name":201,"nameZh":6,"description":202,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":203,"categories":204,"keywords":206,"publishedAt":44},"01M699V3NA4YQKCHJTVWHBQH10","finetuning","Fine-tune models on Microsoft Foundry using SFT (supervised), DPO (preference), or RFT (reinforcement with graders). Covers dataset preparation, training job submission, deployment, and evaluation. USE FOR: fine-tune, SFT, DPO, RFT, training data, grader, distillation, fine-tuned model, training job, large file upload, calibrate grader, deploy fine-tuned model, evaluate fine-tuned model. DO NOT USE FOR: general model deployment without fine-tuning (use deploy-model), agent creation (use agents), prompt optimization without training (use prompt-optimizer).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fazure-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft-foundry\u002Ffinetuning\u002FSKILL.md",[205],{"categoryNo":125,"categoryName":126,"taxonomyType":21,"taxonomyTypeDesc":22},[201,207,100,193,208,9,209,194,155,210,211,212,213,214,215,216,217,218,105,107,219,220,133,221],"placeholder","microsoft foundry","Prompt Optimization","training","dataset","optimizer","Evaluation","tuning","grader","data","supervised","distillation","Optimization","calibrate","submission"]