{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 9,
      "content": {
        "version": "KqlParameterItem/1.0",
        "parameters": [
          {
            "id": "473bbb41-6551-461e-927a-6fc37f71916c",
            "version": "KqlParameterItem/1.0",
            "name": "Subscription",
            "label": "Subscription",
            "type": 6,
            "isRequired": true,
            "multiSelect": true,
            "quote": "'",
            "delimiter": ",",
            "typeSettings": {
              "additionalResourceOptions": [
                "value::all"
              ],
              "includeAll": true,
              "showDefault": false
            },
            "timeContext": {
              "durationMs": 86400000
            },
            "value": [
              "value::all"
            ]
          },
          {
            "id": "7c088804-0799-486c-9175-010afee43089",
            "version": "KqlParameterItem/1.0",
            "name": "Workspace",
            "label": "Workspace",
            "type": 5,
            "isRequired": true,
            "multiSelect": true,
            "quote": "'",
            "delimiter": ",",
            "query": "where type =~ 'microsoft.operationalinsights/workspaces' | project id",
            "crossComponentResources": [
              "{Subscription}"
            ],
            "typeSettings": {
              "additionalResourceOptions": [
                "value::all"
              ],
              "includeAll": true,
              "showDefault": false
            },
            "timeContext": {
              "durationMs": 86400000
            },
            "queryType": 1,
            "resourceType": "microsoft.resourcegraph/resources",
            "value": [
              "value::all"
            ]
          },
          {
            "id": "8c371768-ea44-4d8e-aca7-fcd39ea1f603",
            "version": "KqlParameterItem/1.0",
            "name": "TimeRange",
            "type": 4,
            "isRequired": true,
            "value": {
              "durationMs": 86400000
            },
            "typeSettings": {
              "selectableValues": [
                {
                  "durationMs": 3600000
                },
                {
                  "durationMs": 14400000
                },
                {
                  "durationMs": 43200000
                },
                {
                  "durationMs": 86400000
                },
                {
                  "durationMs": 172800000
                },
                {
                  "durationMs": 604800000
                },
                {
                  "durationMs": 2592000000
                }
              ]
            }
          },
          {
            "id": "fef32a17-edba-4823-9f43-1c8002880e37",
            "version": "KqlParameterItem/1.0",
            "name": "SiteFilter",
            "label": "Sites",
            "type": 2,
            "isRequired": false,
            "multiSelect": true,
            "quote": "'",
            "delimiter": ",",
            "typeSettings": {
              "additionalResourceOptions": [
                "value::all"
              ],
              "showDefault": false
            },
            "defaultValue": "value::all",
            "query": "let H = Unifi_SiteManager_Hosts_CL\n    | summarize arg_max(TimeGenerated, *) by Id\n    | project HostId = Id, FriendlyName = tostring(ReportedState.name);\nUnifi_SiteManager_Sites_CL\n| where TimeGenerated > ago(2h)\n| summarize arg_max(TimeGenerated, *) by SiteId\n| join kind=leftouter H on HostId\n| extend MetaName = tostring(Meta.name), Suffix = substring(tostring(SiteId), 0, 6)\n| project value = tostring(SiteId),\n          label = coalesce(\n              iif(isnotempty(FriendlyName), FriendlyName, ''),\n              iif(MetaName != 'default' and isnotempty(MetaName), MetaName, ''),\n              strcat(MetaName, ' (', Suffix, ')'))\n| order by label asc",
            "crossComponentResources": [
              "{Workspace}"
            ],
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          }
        ],
        "style": "pills",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "parameters"
    },
    {
      "type": 1,
      "content": {
        "json": "<div style=\"display:flex;align-items:center;padding:8px 0 16px 0;border-bottom:1px solid #1e293b\"><svg width=\"40\" height=\"40\" style=\"margin-right:14px;flex-shrink:0;fill:#0559C9\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M494.2 0h-31.8v31.8h31.8zM383.1 222.4v-63.6h63.5v63.5h63.5c1.1 58.9-3.4 110.2-33.3 161.6-86.6 152.4-300.5 172.9-414 39.2C36.3 392.4 17.2 355 8.3 315c-4.5-21.7-6.5-49.2-6.5-72.5V4h127l.2 242c.6 31.3 6.3 63.5 25 88 53.9 73 167.9 66.3 212.1-13.1 15.9-26.6 17.3-68.7 17-98.5m15.8-174.8h47.6v47.6H510v63.5h-63.5V95.3h-47.6z\"/></svg><div><div style=\"font-size:22px;font-weight:600;letter-spacing:-0.5px\">UniFi Site Manager</div><div style=\"font-size:13px;color:#94a3b8;margin-top:2px\">Estate-wide visibility across every UniFi-managed site, host, device and ISP link. Site health, device inventory, ISP performance, firmware drift, security posture and admin operations polled every 5 minutes from the Site Manager API. Scope every panel with the time range and Sites filter below; the Hunts tab embeds the 8 packaged hunting queries.</div></div></div>"
      },
      "name": "header"
    },
    {
      "type": 11,
      "content": {
        "version": "LinkItem/1.0",
        "style": "tabs",
        "links": [
          {
            "id": "89624eb5-36c5-4212-925c-25d486a4726a",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Overview",
            "subTarget": "overview",
            "style": "link"
          },
          {
            "id": "dad2dd89-89a9-4a32-abac-cab017d21317",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Sites",
            "subTarget": "sites",
            "style": "link"
          },
          {
            "id": "1442d4dc-6117-4498-bc9f-35d9410518b9",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "ISP Performance",
            "subTarget": "isp",
            "style": "link"
          },
          {
            "id": "12715240-d822-42b2-a743-46f50f5601e0",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Devices",
            "subTarget": "devices",
            "style": "link"
          },
          {
            "id": "ed82a37e-9981-49ba-b6e6-60dea6020ea2",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Security",
            "subTarget": "security",
            "style": "link"
          },
          {
            "id": "a04a9773-6fe2-4eea-8754-a841222b7fab",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Operations",
            "subTarget": "operations",
            "style": "link"
          },
          {
            "id": "c6c81d2b-21a1-4c48-be9e-7ca410b029d3",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Hunts",
            "subTarget": "hunts",
            "style": "link"
          },
          {
            "id": "2b5d338c-6755-4eb8-ac26-01d085acbbf6",
            "cellValue": "selectedTab",
            "linkTarget": "parameter",
            "linkLabel": "Pipeline Health",
            "subTarget": "pipeline",
            "style": "link"
          }
        ]
      },
      "name": "tabs"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Estate at a glance</div>"
            },
            "name": "div-estate-at-a-glance-2e4bd3"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let S = Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId);\nlet SelectedHostIds = toscalar(S | summarize make_set(HostId));\nlet H = Unifi_SiteManager_Hosts_CL | where \"value::all\" in~ ({SiteFilter}) or Id in (SelectedHostIds) | summarize arg_max(TimeGenerated, *) by Id;\nlet D = Unifi_SiteManager_Devices_CL | summarize arg_max(TimeGenerated, *) by Id;\nlet I = SecurityIncident | where TimeGenerated > ago(7d) | where Title startswith \"UniFi Site Manager\" | summarize arg_max(LastModifiedTime, *) by IncidentNumber | where Status != \"Closed\";\nunion\n  (S | summarize V=toreal(count())                                                              | extend Metric=\"Sites\",                Order=1),\n  (H | summarize V=toreal(count())                                                              | extend Metric=\"Hosts\",                Order=2),\n  (D | summarize V=toreal(count())                                                              | extend Metric=\"Devices (estate)\",     Order=3),\n  (D | where Status =~ \"online\"                                                                 | summarize V=toreal(count()) | extend Metric=\"Online\",                Order=4),\n  (D | where Status =~ \"offline\"                                                                | summarize V=toreal(count()) | extend Metric=\"Offline\",               Order=5),\n  (D | where FirmwareStatus in~ (\"UpdateAvailable\",\"updatePending\")                             | summarize V=toreal(count()) | extend Metric=\"Need firmware update\", Order=6),\n  (S | extend WanUptime=todouble(SiteStatistics.percentages.wanUptime)                          | summarize V=todouble(round(avg(WanUptime),1)) | extend Metric=\"Avg WAN uptime %\", Order=7),\n  (I | summarize V=toreal(count())                                                              | extend Metric=\"Open incidents\",       Order=8)\n| order by Order asc | project Metric, Value=V",
              "size": 3,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Metric",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Value",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  }
                },
                "showBorder": false
              }
            },
            "name": "q-f4405255"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Open incidents</div>"
            },
            "name": "div-open-incidents-ee5177"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "SecurityIncident\n| where TimeGenerated > ago(30d)\n| where Title startswith \"UniFi Site Manager\"\n| summarize arg_max(LastModifiedTime, *) by IncidentNumber\n| where Status != \"Closed\"\n| extend AgeDays = datetime_diff(\"day\", now(), CreatedTime)\n| project Severity, [\"Incident #\"]=IncidentNumber, Title, Status, [\"Alerts\"]=array_length(AlertIds), Opened=CreatedTime, [\"Last update\"]=LastModifiedTime, [\"Age (d)\"]=AgeDays\n| order by Severity asc, Opened desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Open UniFi Site Manager-related Sentinel incidents",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Severity",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "colors",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "High",
                          "representation": "redBright",
                          "text": "High"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Medium",
                          "representation": "orange",
                          "text": "Medium"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Low",
                          "representation": "yellow",
                          "text": "Low"
                        },
                        {
                          "operator": "Default",
                          "representation": "blue",
                          "text": "Informational"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "Opened",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "Last update",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "Age (d)",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  }
                ]
              },
              "noDataMessage": "No open UniFi Site Manager incidents. Enable the 21 packaged analytic rules under Configuration -> Analytics -> Rule templates to start populating this list.",
              "noDataMessageStyle": 5
            },
            "name": "q-cbb2c274"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Incident creation timeline</div>"
            },
            "name": "div-incident-creation-ti-918403"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "SecurityIncident\n| where TimeGenerated {TimeRange}\n| where Title startswith \"UniFi Site Manager\"\n| summarize Incidents=count() by bin(CreatedTime, 1h), Severity\n| order by CreatedTime asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "Incidents created per hour (by severity)",
              "noDataMessage": "No incidents created in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-414d6cd3",
            "customWidth": "66"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "SecurityIncident\n| where TimeGenerated {TimeRange}\n| where Title startswith \"UniFi Site Manager\"\n| summarize arg_max(LastModifiedTime, *) by IncidentNumber\n| summarize Incidents=count() by Severity",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "piechart",
              "title": "Severity mix",
              "noDataMessage": "No incidents in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-3c6e9381",
            "customWidth": "33"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Top sites by issues</div>"
            },
            "name": "div-top-sites-by-issues-1a56a5"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _siteNames = Unifi_SiteManager_Sites_CL\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | where isnotempty(SiteId)\n    | join kind=leftouter (\n        Unifi_SiteManager_Hosts_CL\n        | summarize arg_max(TimeGenerated, *) by Id\n        | project HostId = Id, FriendlyName = tostring(ReportedState.name)\n      ) on HostId\n    | extend MetaName = tostring(Meta.name), Suffix = substring(tostring(SiteId), 0, 6)\n    | project SiteId = tostring(SiteId),\n              SiteName = coalesce(\n                  iif(isnotempty(FriendlyName), FriendlyName, \"\"),\n                  iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"),\n                  strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where TimeGenerated > ago(2h)\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n| where isnotempty(SiteId)\n| project-away SiteName\n| extend SiteId=tostring(SiteId),\n         Total=toint(SiteStatistics.counts.totalDevice),\n         Offline=toint(SiteStatistics.counts.offlineDevice),\n         OfflineGW=toint(SiteStatistics.counts.offlineGatewayDevice),\n         PendingUpdates=toint(SiteStatistics.counts.pendingUpdateDevice),\n         CritNotifs=toint(SiteStatistics.counts.criticalNotification),\n         WanUptime=todouble(SiteStatistics.percentages.wanUptime),\n         TxRetry=todouble(SiteStatistics.percentages.txRetry)\n| join kind=leftouter _siteNames on SiteId\n| extend IssueScore = Offline*5 + OfflineGW*10 + PendingUpdates*1 + CritNotifs*3 + iif(WanUptime < 95, 5, 0)\n| where IssueScore > 0\n| project SiteName, IssueScore, Offline, OfflineGW, PendingUpdates, CritNotifs, WanUptime, TxRetry\n| order by IssueScore desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Sites ranked by composite issue score",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "IssueScore",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "Offline",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "red"
                    }
                  },
                  {
                    "columnMatch": "OfflineGW",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "PendingUpdates",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "CritNotifs",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "WanUptime",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "greenRed",
                      "min": 80,
                      "max": 100
                    }
                  },
                  {
                    "columnMatch": "TxRetry",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "yellow"
                    }
                  }
                ]
              },
              "noDataMessage": "No sites with issues - estate is healthy.",
              "noDataMessageStyle": 5
            },
            "name": "q-2d468d59"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "overview"
      },
      "name": "group-overview"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Estate snapshot</div>"
            },
            "name": "div-estate-snapshot-59a215"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let S = Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId);\nunion\n  (S | summarize V=toreal(count())                                            | extend Metric=\"Total sites\",        Order=1),\n  (S | where IsOwner == true                                                  | summarize V=toreal(count()) | extend Metric=\"Owned\",              Order=2),\n  (S | extend U=todouble(SiteStatistics.percentages.wanUptime) | where U < 95 | summarize V=toreal(count()) | extend Metric=\"WAN uptime < 95%\",   Order=3),\n  (S | extend C=toint(SiteStatistics.counts.criticalNotification) | where C>0 | summarize V=toreal(count()) | extend Metric=\"Critical notifs\",    Order=4),\n  (S | extend O=toint(SiteStatistics.counts.offlineDevice) | where O > 0     | summarize V=toreal(count()) | extend Metric=\"Has offline devices\", Order=5),\n  (S | extend P=toint(SiteStatistics.counts.pendingUpdateDevice) | where P>0 | summarize V=toreal(count()) | extend Metric=\"Pending updates\",     Order=6),\n  (S | extend Insp=tostring(SiteStatistics.gateway.inspectionState) | where Insp != \"on\" | summarize V=toreal(count()) | extend Metric=\"DPI off / no inspect\", Order=7)\n| order by Order asc | project Metric, Value=V",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Metric",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Value",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  }
                },
                "showBorder": false
              }
            },
            "name": "q-0144ed7a"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Composition by site</div>"
            },
            "name": "div-composition-by-site-75e3d7"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _siteNames = Unifi_SiteManager_Sites_CL\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | where isnotempty(SiteId)\n    | join kind=leftouter (\n        Unifi_SiteManager_Hosts_CL\n        | summarize arg_max(TimeGenerated, *) by Id\n        | project HostId = Id, FriendlyName = tostring(ReportedState.name)\n      ) on HostId\n    | extend MetaName = tostring(Meta.name), Suffix = substring(tostring(SiteId), 0, 6)\n    | project SiteId = tostring(SiteId),\n              SiteName = coalesce(\n                  iif(isnotempty(FriendlyName), FriendlyName, \"\"),\n                  iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"),\n                  strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n| extend SiteId=tostring(SiteId),\n         Wired=toint(SiteStatistics.counts.wiredClient),\n         WiFi=toint(SiteStatistics.counts.wifiClient),\n         Guest=toint(SiteStatistics.counts.guestClient),\n         Devices=toint(SiteStatistics.counts.totalDevice)\n| join kind=leftouter _siteNames on SiteId\n| project SiteName, Devices, Wired, WiFi, Guest",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "barchart",
              "title": "Clients + devices per site"
            },
            "name": "q-7dcaaa0e",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Sites_CL\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n| extend ISP=tostring(SiteStatistics.ispInfo.name),\n         Org=tostring(SiteStatistics.ispInfo.organization)\n| summarize Sites=count(), Orgs=make_set(Org) by ISP\n| order by Sites desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "ISPs in use across the estate",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Sites",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  }
                ]
              }
            },
            "name": "q-8c878de9",
            "customWidth": "50"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Site inventory</div>"
            },
            "name": "div-site-inventory-d3cf56"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _siteNames = Unifi_SiteManager_Sites_CL\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | where isnotempty(SiteId)\n    | join kind=leftouter (\n        Unifi_SiteManager_Hosts_CL\n        | summarize arg_max(TimeGenerated, *) by Id\n        | project HostId = Id, FriendlyName = tostring(ReportedState.name)\n      ) on HostId\n    | extend MetaName = tostring(Meta.name), Suffix = substring(tostring(SiteId), 0, 6)\n    | project SiteId = tostring(SiteId),\n              SiteName = coalesce(\n                  iif(isnotempty(FriendlyName), FriendlyName, \"\"),\n                  iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"),\n                  strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n| where isnotempty(SiteId)\n| project-away SiteName\n| extend SiteId=tostring(SiteId),\n         Timezone=tostring(Meta.timezone),\n         Permission=Permission,\n         Devices=toint(SiteStatistics.counts.totalDevice),\n         Offline=toint(SiteStatistics.counts.offlineDevice),\n         WanUptime=todouble(SiteStatistics.percentages.wanUptime),\n         TxRetry=todouble(SiteStatistics.percentages.txRetry),\n         ISP=tostring(SiteStatistics.ispInfo.name),\n         IPSMode=tostring(SiteStatistics.gateway.ipsMode),\n         Inspection=tostring(SiteStatistics.gateway.inspectionState),\n         LastSnapshot=TimeGenerated\n| join kind=leftouter _siteNames on SiteId\n| project SiteName, Permission, Devices, Offline, WanUptime, TxRetry, ISP, IPSMode, Inspection, Timezone, LastSnapshot\n| order by SiteName asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Full site inventory snapshot",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Permission",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "Devices",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  },
                  {
                    "columnMatch": "Offline",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "red"
                    }
                  },
                  {
                    "columnMatch": "WanUptime",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "greenRed",
                      "min": 80,
                      "max": 100
                    }
                  },
                  {
                    "columnMatch": "TxRetry",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "IPSMode",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "Inspection",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "LastSnapshot",
                    "formatter": 6
                  }
                ]
              }
            },
            "name": "q-61110555"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "sites"
      },
      "name": "group-sites"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">ISP scorecard</div>"
            },
            "name": "div-isp-scorecard-f1098f"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let M = Unifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated {TimeRange}\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend AvgL=todouble(p.data.wan.avgLatency),\n         MaxL=todouble(p.data.wan.maxLatency),\n         PL  =todouble(p.data.wan.packetLoss),\n         DT  =todouble(p.data.wan.downtime),\n         UT  =todouble(p.data.wan.uptime);\nunion\n  (M | summarize V=todouble(round(avg(AvgL),1)) | extend Metric=\"Avg latency (ms)\",   Order=1),\n  (M | summarize V=todouble(round(max(MaxL),0)) | extend Metric=\"Peak latency (ms)\",  Order=2),\n  (M | summarize V=todouble(round(avg(PL),2))   | extend Metric=\"Avg packet loss %\",  Order=3),\n  (M | summarize V=todouble(round(sum(DT),0))   | extend Metric=\"Total downtime (s)\", Order=4),\n  (M | summarize V=todouble(round(avg(UT),2))   | extend Metric=\"Avg uptime %\",       Order=5),\n  (M | summarize V=toreal(count())              | extend Metric=\"Samples\",            Order=6)\n| order by Order asc | project Metric, Value=V",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Metric",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Value",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  }
                },
                "showBorder": false
              }
            },
            "name": "q-4ea04324"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Latency & loss</div>"
            },
            "name": "div-latency-and-loss-563ef7"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated {TimeRange}\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend t=todatetime(p.metricTime), L=todouble(p.data.wan.avgLatency)\n| where isnotnull(t) and isnotnull(L)\n| join kind=leftouter (H) on $left.SiteId == $right.SiteId\n| summarize Latency=avg(L) by bin(t, 30m), SiteName\n| order by t asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "Avg latency (ms) per site, over time",
              "noDataMessage": "No ISP latency samples in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-52d24253"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated {TimeRange}\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend t=todatetime(p.metricTime), PL=todouble(p.data.wan.packetLoss)\n| where isnotnull(t)\n| join kind=leftouter (H) on $left.SiteId == $right.SiteId\n| summarize PacketLoss=avg(PL) by bin(t, 30m), SiteName\n| order by t asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "Packet loss % per site, over time",
              "noDataMessage": "No packet-loss samples in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-c68a3158"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Throughput</div>"
            },
            "name": "div-throughput-6fca7e"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated {TimeRange}\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend t=todatetime(p.metricTime),\n         Down=todouble(p.data.wan.download_kbps),\n         Up  =todouble(p.data.wan.upload_kbps)\n| where isnotnull(t)\n| join kind=leftouter (H) on $left.SiteId == $right.SiteId\n| summarize DownKbps=avg(Down), UpKbps=avg(Up) by bin(t, 30m), SiteName\n| order by t asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "WAN throughput (down/up kbps) per site, over time",
              "noDataMessage": "No throughput samples in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-0180b5b8"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">WAN uptime rollup (last 7d)</div>"
            },
            "name": "div-wan-uptime-rollup-(l-97d524"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated > ago(7d)\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend UT=todouble(p.data.wan.uptime)\n| join kind=leftouter (H) on $left.SiteId == $right.SiteId\n| summarize AvgUptime=round(avg(UT),2), MinUptime=round(min(UT),2), Samples=count() by SiteName\n| order by AvgUptime asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Per-site WAN uptime over the last 7 days",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "AvgUptime",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "greenRed",
                      "min": 80,
                      "max": 100
                    }
                  },
                  {
                    "columnMatch": "MinUptime",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "greenRed",
                      "min": 80,
                      "max": 100
                    }
                  },
                  {
                    "columnMatch": "Samples",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  }
                ]
              }
            },
            "name": "q-64fa3e76"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "isp"
      },
      "name": "group-isp"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Device fleet snapshot</div>"
            },
            "name": "div-device-fleet-snapsho-6f55ae"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let D = Unifi_SiteManager_Devices_CL | summarize arg_max(TimeGenerated, *) by Id;\nunion\n  (D | summarize V=toreal(count())                                                | extend Metric=\"Total devices\",       Order=1),\n  (D | where Status =~ \"online\"                                                   | summarize V=toreal(count()) | extend Metric=\"Online\",              Order=2),\n  (D | where Status =~ \"offline\"                                                  | summarize V=toreal(count()) | extend Metric=\"Offline\",             Order=3),\n  (D | where FirmwareStatus =~ \"upToDate\"                                         | summarize V=toreal(count()) | extend Metric=\"Up-to-date firmware\", Order=4),\n  (D | where FirmwareStatus =~ \"UpdateAvailable\"                                  | summarize V=toreal(count()) | extend Metric=\"Updates available\",   Order=5),\n  (D | where FirmwareStatus =~ \"updatePending\"                                    | summarize V=toreal(count()) | extend Metric=\"Pending update\",      Order=6),\n  (D | where IsConsole == true                                                    | summarize V=toreal(count()) | extend Metric=\"Consoles\",            Order=7),\n  (D | where ProductLine =~ \"protect\"                                             | summarize V=toreal(count()) | extend Metric=\"Protect devices\",    Order=8)\n| order by Order asc | project Metric, Value=V",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Metric",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Value",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  }
                },
                "showBorder": false
              }
            },
            "name": "q-0682814a"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Distribution</div>"
            },
            "name": "div-distribution-04aecf"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| summarize Count=count() by ProductLine\n| order by Count desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "piechart",
              "title": "Devices by product line"
            },
            "name": "q-db3706d0",
            "customWidth": "33"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| summarize Count=count() by FirmwareStatus\n| order by Count desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "piechart",
              "title": "Firmware status"
            },
            "name": "q-5e491c86",
            "customWidth": "33"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| summarize Count=count() by Model\n| order by Count desc | take 12",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "barchart",
              "title": "Top 12 models"
            },
            "name": "q-2aaa49cc",
            "customWidth": "33"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Devices needing attention</div>"
            },
            "name": "div-devices-needing-atte-4cb504"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| where isnotempty(Id)\n| summarize arg_max(TimeGenerated, *) by Id\n| where isnotempty(Status) and isnotempty(FirmwareStatus)\n| where FirmwareStatus != \"upToDate\" or Status != \"online\"\n| extend Priority = case(\n    IsConsole == true and FirmwareStatus != \"upToDate\", \"CONSOLE OUT OF DATE\",\n    IsConsole == true and Status != \"online\",            \"CONSOLE OFFLINE\",\n    Status != \"online\",                                  \"Device offline\",\n    FirmwareStatus != \"upToDate\",                        \"Firmware update\",\n    \"\")\n| extend Issues = strcat_array(pack_array(\n    iif(Status != \"online\", strcat(\"Status:\", Status), \"\"),\n    iif(FirmwareStatus != \"upToDate\", strcat(\"firmware:\", FirmwareStatus), \"\")\n  ), \", \")\n| extend Issues = trim_start(\", \", trim_end(\", \", replace_string(Issues, \", , \", \", \")))\n| project Priority, Name, Model, ProductLine, Version, Status, FirmwareStatus, IsConsole, Ip, AdoptionTime, Issues\n| order by case(Priority startswith \"CONSOLE\", 0, Priority == \"Device offline\", 1, 2) asc, Status asc, FirmwareStatus asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Devices flagged with one or more issues",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Priority",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "contains",
                          "thresholdValue": "CONSOLE",
                          "representation": "critical",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Device offline",
                          "representation": "4",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Firmware update",
                          "representation": "pending",
                          "text": "{0}"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": "{0}"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "Status",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "online",
                          "representation": "success",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "offline",
                          "representation": "critical",
                          "text": "{0}"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": "{0}"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "FirmwareStatus",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "upToDate",
                          "representation": "success",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "updateAvailable",
                          "representation": "critical",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "updatePending",
                          "representation": "pending",
                          "text": "{0}"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": "{0}"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "IsConsole",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "true",
                          "representation": "4",
                          "text": "Console"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": ""
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "ProductLine",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "Issues",
                    "formatter": 11
                  }
                ]
              },
              "noDataMessage": "No devices need attention - estate healthy.",
              "noDataMessageStyle": 5
            },
            "name": "q-b9f37505"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Full device inventory</div>"
            },
            "name": "div-full-device-inventor-df4379"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| where isnotempty(Id)\n| summarize arg_max(TimeGenerated, *) by Id\n| where isnotempty(Status)\n| project Name, Model, ProductLine, Version, Status, FirmwareStatus, IsConsole, Ip, Mac, IsManaged, StartupTime, AdoptionTime\n| order by IsConsole desc, ProductLine asc, Status asc, Name asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "All devices (latest snapshot per device ID)",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Status",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "online",
                          "representation": "success",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "offline",
                          "representation": "critical",
                          "text": "{0}"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": "{0}"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "FirmwareStatus",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "upToDate",
                          "representation": "success",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "updateAvailable",
                          "representation": "critical",
                          "text": "{0}"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "updatePending",
                          "representation": "pending",
                          "text": "{0}"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": "{0}"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "IsConsole",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "true",
                          "representation": "4",
                          "text": "Console"
                        },
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "unknown",
                          "text": ""
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "ProductLine",
                    "formatter": 11
                  }
                ]
              }
            },
            "name": "q-823bc18a"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "devices"
      },
      "name": "group-devices"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Security posture summary</div>"
            },
            "name": "div-security-posture-sum-544eec"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let S = Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId);\nunion\n  (S | extend M=tostring(SiteStatistics.gateway.ipsMode)         | where M =~ \"ips\"   | summarize V=toreal(count()) | extend Metric=\"IPS active\",     Order=1),\n  (S | extend M=tostring(SiteStatistics.gateway.ipsMode)         | where M =~ \"ids\"   | summarize V=toreal(count()) | extend Metric=\"IDS only\",       Order=2),\n  (S | extend M=tostring(SiteStatistics.gateway.ipsMode)         | where M =~ \"off\"   | summarize V=toreal(count()) | extend Metric=\"No IPS/IDS\",     Order=3),\n  (S | extend I=tostring(SiteStatistics.gateway.inspectionState) | where I =~ \"on\"    | summarize V=toreal(count()) | extend Metric=\"Inspecting\",     Order=4),\n  (S | extend I=tostring(SiteStatistics.gateway.inspectionState) | where I != \"on\"    | summarize V=toreal(count()) | extend Metric=\"Inspect off\",    Order=5),\n  (S | extend R=toint(SiteStatistics.gateway.ipsSignature.rulesCount) | summarize V=todouble(round(avg(R),0)) | extend Metric=\"Avg sigs / gateway\", Order=6),\n  (S | extend C=toint(SiteStatistics.counts.criticalNotification) | summarize V=todouble(sum(C)) | extend Metric=\"Critical notifs\",  Order=7)\n| order by Order asc | project Metric, Value=V",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Metric",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Value",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  }
                },
                "showBorder": false
              }
            },
            "name": "q-5879a1be"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Per-site IPS / IDS configuration</div>"
            },
            "name": "div-per-site-ips---ids-c-d1056c"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _siteNames = Unifi_SiteManager_Sites_CL\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | where isnotempty(SiteId)\n    | join kind=leftouter (\n        Unifi_SiteManager_Hosts_CL\n        | summarize arg_max(TimeGenerated, *) by Id\n        | project HostId = Id, FriendlyName = tostring(ReportedState.name)\n      ) on HostId\n    | extend MetaName = tostring(Meta.name), Suffix = substring(tostring(SiteId), 0, 6)\n    | project SiteId = tostring(SiteId),\n              SiteName = coalesce(\n                  iif(isnotempty(FriendlyName), FriendlyName, \"\"),\n                  iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"),\n                  strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n| extend SiteId=tostring(SiteId),\n         IPSMode=tostring(SiteStatistics.gateway.ipsMode),\n         Inspection=tostring(SiteStatistics.gateway.inspectionState),\n         RulesCount=toint(SiteStatistics.gateway.ipsSignature.rulesCount),\n         RulesetType=tostring(SiteStatistics.gateway.ipsSignature.type),\n         CriticalNotifs=toint(SiteStatistics.counts.criticalNotification)\n| join kind=leftouter _siteNames on SiteId\n| project SiteName, IPSMode, Inspection, RulesCount, RulesetType, CriticalNotifs\n| order by IPSMode asc, SiteName asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Where is IPS/IDS configured and what's its inspection state?",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "IPSMode",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "Inspection",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "RulesCount",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  },
                  {
                    "columnMatch": "RulesetType",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "CriticalNotifs",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  }
                ]
              }
            },
            "name": "q-c6735c8d"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Signature counts over time</div>"
            },
            "name": "div-signature-counts-ove-4bcc46"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where TimeGenerated {TimeRange}\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| extend SiteId=tostring(SiteId), Sigs=toint(SiteStatistics.gateway.ipsSignature.rulesCount)\n| where isnotnull(Sigs)\n| join kind=leftouter H on SiteId\n| summarize Sigs=max(Sigs) by bin(TimeGenerated, 1h), SiteName\n| order by TimeGenerated asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "Live IPS signature count per gateway, over time",
              "noDataMessage": "No signature-count history yet. Site Manager polls every 5 min.",
              "noDataMessageStyle": 5
            },
            "name": "q-0053e102"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Security incidents from analytic rules</div>"
            },
            "name": "div-security-incidents-f-5ecdf6"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "SecurityIncident\n| where TimeGenerated {TimeRange}\n| where Title startswith \"UniFi Site Manager\" and (Title contains \"IPS\" or Title contains \"Critical\")\n| summarize arg_max(LastModifiedTime, *) by IncidentNumber\n| project Severity, IncidentNumber, Title, Status, CreatedTime, LastModifiedTime\n| order by CreatedTime desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Security-related incidents in this window",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Severity",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "colors",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "High",
                          "representation": "redBright",
                          "text": "High"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Medium",
                          "representation": "orange",
                          "text": "Medium"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Low",
                          "representation": "yellow",
                          "text": "Low"
                        },
                        {
                          "operator": "Default",
                          "representation": "blue",
                          "text": "Informational"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "CreatedTime",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "LastModifiedTime",
                    "formatter": 6
                  }
                ]
              },
              "noDataMessage": "No security incidents from the IPS/critical rules in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-a7131813"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "security"
      },
      "name": "group-security"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Host inventory</div>"
            },
            "name": "div-host-inventory-f39b81"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _selectedHostIds = toscalar(\n    Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | summarize make_set(HostId));\nUnifi_SiteManager_Hosts_CL\n| where \"value::all\" in~ ({SiteFilter}) or Id in (_selectedHostIds)\n| summarize arg_max(TimeGenerated, *) by Id\n| extend HostName=tostring(ReportedState.name),\n         Firmware=tostring(ReportedState.controller_uuid),\n         Hardware=tostring(ReportedState.hardware.shortname),\n         LastBackup=todatetime(LatestBackupTime),\n         LastStateChange=todatetime(LastConnectionStateChange),\n         RegistrationTime=todatetime(RegistrationTime)\n| project HostName, HostType, IpAddress, Hardware, IsBlocked, Owner, LastStateChange, LastBackup, RegistrationTime\n| order by HostName asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "All UniFi consoles / cloud-keys registered",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "hostType",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "Hardware",
                    "formatter": 11
                  },
                  {
                    "columnMatch": "LastStateChange",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "LastBackup",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "RegistrationTime",
                    "formatter": 6
                  }
                ]
              }
            },
            "name": "q-7f18e03a"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Backup recency</div>"
            },
            "name": "div-backup-recency-616e6c"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _selectedHostIds = toscalar(\n    Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | summarize make_set(HostId));\nUnifi_SiteManager_Hosts_CL\n| where \"value::all\" in~ ({SiteFilter}) or Id in (_selectedHostIds)\n| summarize arg_max(TimeGenerated, *) by Id\n| extend HostName=tostring(ReportedState.name),\n         LastBackup=todatetime(LatestBackupTime),\n         HoursSince=toint((now() - todatetime(LatestBackupTime)) / 1h)\n| where isnotnull(HoursSince)\n| extend Bucket=case(HoursSince < 24, \"<24h\", HoursSince < 168, \"<7d\", HoursSince < 720, \"<30d\", \"30+ days\")\n| summarize Hosts=count() by Bucket\n| order by case(Bucket==\"<24h\",1, Bucket==\"<7d\",2, Bucket==\"<30d\",3, 4) asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "barchart",
              "title": "When did each host last back up?"
            },
            "name": "q-0e759d72",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _selectedHostIds = toscalar(\n    Unifi_SiteManager_Sites_CL\n    | where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n    | summarize arg_max(TimeGenerated, *) by tostring(SiteId)\n    | summarize make_set(HostId));\nUnifi_SiteManager_Hosts_CL\n| where \"value::all\" in~ ({SiteFilter}) or Id in (_selectedHostIds)\n| summarize arg_max(TimeGenerated, *) by Id\n| extend HostName=tostring(ReportedState.name),\n         LastBackup=todatetime(LatestBackupTime),\n         HoursSinceBackup=toint((now() - todatetime(LatestBackupTime)) / 1h)\n| where HoursSinceBackup > 48 or isnull(HoursSinceBackup)\n| project HostName, HostType, IpAddress, LastBackup, HoursSinceBackup\n| order by HoursSinceBackup desc nulls first",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Hosts with stale backups (>48h)",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "LastBackup",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "HoursSinceBackup",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  }
                ]
              },
              "noDataMessage": "All hosts backed up within the last 48 hours - good hygiene.",
              "noDataMessageStyle": 5
            },
            "name": "q-f57510b9",
            "customWidth": "50"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Recent admin operations (incident-driven view)</div>"
            },
            "name": "div-recent-admin-operati-cb53c7"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "SecurityIncident\n| where TimeGenerated {TimeRange}\n| where Title startswith \"UniFi Site Manager\" and (Title contains \"adopted\" or Title contains \"log shipping\" or Title contains \"data connector\")\n| summarize arg_max(LastModifiedTime, *) by IncidentNumber\n| project Severity, IncidentNumber, Title, Status, CreatedTime\n| order by CreatedTime desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Operational events captured as Sentinel incidents",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Severity",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "colors",
                      "thresholdsGrid": [
                        {
                          "operator": "==",
                          "thresholdValue": "High",
                          "representation": "redBright",
                          "text": "High"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Medium",
                          "representation": "orange",
                          "text": "Medium"
                        },
                        {
                          "operator": "==",
                          "thresholdValue": "Low",
                          "representation": "yellow",
                          "text": "Low"
                        },
                        {
                          "operator": "Default",
                          "representation": "blue",
                          "text": "Informational"
                        }
                      ]
                    }
                  },
                  {
                    "columnMatch": "CreatedTime",
                    "formatter": 6
                  }
                ]
              },
              "noDataMessage": "No operational events in this window.",
              "noDataMessageStyle": 5
            },
            "name": "q-f0a8d2aa"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "operations"
      },
      "name": "group-operations"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"padding:14px 16px;background:rgba(59,130,246,0.07);border-left:4px solid #3b82f6;border-radius:4px;margin:8px 0;font-size:13px;line-height:1.5\"><strong>About this tab.</strong> Each panel below is an inline preview of one of the 8 saved Hunting Queries that ship with this solution. The result table is the hunt running live against the time range above. For a deeper dive, click <strong>\u25b6 Run in Log Analytics</strong> under any hunt - it opens the same KQL in the Logs blade so you can modify it, pivot the time range, save bookmarks, or add rows to an active investigation.</div>"
            },
            "name": "div-hunts-banner"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Stability: console churn & device flapping</div>"
            },
            "name": "div-stability:-console-c-e2d4c2"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Hosts_CL\n| where TimeGenerated > ago(7d)\n| summarize Snapshots=count(), DistinctStates=dcount(LastConnectionStateChange) by Id\n| where DistinctStates > 1\n| order by DistinctStates desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Hosts whose connection-state has changed multiple times in 7d",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "DistinctStates",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  }
                ]
              },
              "noDataMessage": "No console group churn - environment stable.",
              "noDataMessageStyle": 5
            },
            "name": "q-94dd8561",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| where TimeGenerated > ago(24h)\n| summarize StateChanges=dcount(Status) by Id, Name\n| where StateChanges > 1\n| order by StateChanges desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Devices that oscillated online <-> offline in the last 24h",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "StateChanges",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  }
                ]
              },
              "noDataMessage": "No flapping devices - stable estate.",
              "noDataMessageStyle": 5
            },
            "name": "q-6d016dc7",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "c431daa0-39c7-425c-b9ce-7fff359aacab",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Console Group Churn' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F13NsQrCUAyF4d2nyNiCi5NTXSrooFN1LvHe2AZsUm5SRPHhvSoIOn%2Fn8B%2BFz9w27LRHwY5Su1Vza%2Bvd7AHXnhLBgQfakFBCpwgrwE6LZSyz2zQMmPhO0AiO1qtbFXQSL8o5rNmcJXjj%2BWdV%2FMAFzWsVoeCs8ra6R%2BmohNMNOH6rv%2FecXWTSFCm9hn8aycITelnl18oAAAA%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-6125e9",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "d09a9ea9-2be4-4b4b-9f25-cf1fdfe1feec",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Device Flapping' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F1WMsQoCMRAFe79iyzuwUWy1OcFGqzvrsCbPyxZJIJsoih9vbETbmWHOUa5iRik4ceQZ2exxEws1w3HxortHBk0ScEBE5gJHO%2BI5deuN71ugNQTO8gSNpdnBc5yhW2dTjaXTxqr2dHmQuCVFDvhOf%2Fv2XDWRskP%2BxH%2FOQe0b9MeI%2F6cAAAA%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-f79785",
            "customWidth": "50"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Firmware: version diversity & drift hotspots</div>"
            },
            "name": "div-firmware:-version-di-ff3f71"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| summarize Versions=dcount(Version), Models=dcount(Model), Devices=count() by ProductLine\n| order by Versions desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "How many firmware versions per product line?",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Versions",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "Models",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  },
                  {
                    "columnMatch": "Devices",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  }
                ]
              }
            },
            "name": "q-51010438",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| summarize Devices=count(), UpdatesAvailable=countif(FirmwareStatus == \"UpdateAvailable\"), Pending=countif(FirmwareStatus == \"updatePending\") by Model\n| where UpdatesAvailable > 0 or Pending > 0\n| extend DriftPct = round(100.0 * (UpdatesAvailable + Pending) / Devices, 1)\n| order by DriftPct desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Models with the largest % of devices needing firmware",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "UpdatesAvailable",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "Pending",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "DriftPct",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright",
                      "min": 0,
                      "max": 100
                    }
                  }
                ]
              },
              "noDataMessage": "Every model is fully patched - clean estate.",
              "noDataMessageStyle": 5
            },
            "name": "q-9a4c0187",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "f1cdb1ab-87dc-4c64-b5c3-da0c3d6921c2",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Firmware Version Diversity' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F1WNQQrCMBBF955ilq30Cl0puGlXarchZr5lwCQySYuKh7e1Krh8j8%2F7xyBnMXvJaG2wPdRsMYpDMptm9aQ0eG9VHiCrvfH2VhzEY4cAtRlc0bqk052E%2F7YdNEkMqWYXh5CLceGyojYyLj%2FvZ5rs57Je7Lt41ciDy40ETOmoDJ31t0yM5F5vFFfuvAAAAA%3D%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-8b71d3",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "1526b0c5-2864-4450-9b50-4fcf9a6d7c78",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Firmware Drift Hotspots' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F4WPwUrDQBCG7z7FkNOmhpo%2BQASx4KVCofYcptk%2FcSC7kdlNW8WHd1ubgvTgcZjv%2F%2BafrZdW6o1EvLLnDlovsZcGoX5e3X1TGJ1jlS8Qa1c7Ppo3cXiBh3KELWiW0%2B6TxP5hL4qqGUYfTV7Q9sMmPDztWXre9fjdSGtaUXdgxSZyHANVFWXjmb2iWYqv4a347v%2FUBczOpdxg0adeh3cobirQI5U06OQ%2BjYnFMaaZliptXDeRKtJ005pFWc5LmpG50dxPhpwepscLWuRJNqiFnppcdRah%2BQG2e6epcgEAAA%3D%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-e9dbd5",
            "customWidth": "50"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Change control: off-hours adoption & WAN IP changes</div>"
            },
            "name": "div-change-control:-off--dbb329"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "Unifi_SiteManager_Devices_CL\n| summarize arg_max(TimeGenerated, *) by Id\n| where isnotempty(AdoptionTime)\n| extend AdoptionTime = todatetime(AdoptionTime),\n         Hour = hourofday(todatetime(AdoptionTime)),\n         DayOfWeek = dayofweek(todatetime(AdoptionTime)) / 1d\n| where Hour < 7 or Hour > 19 or DayOfWeek in (0, 6)\n| project AdoptionTime, Name, Model, ProductLine\n| order by AdoptionTime desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Devices adopted outside 07:00-19:00 weekdays",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "AdoptionTime",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "productLine",
                    "formatter": 11
                  }
                ]
              },
              "noDataMessage": "All device adoptions happened during business hours.",
              "noDataMessageStyle": 5
            },
            "name": "q-d7357ffa",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_Sites_CL\n| where TimeGenerated > ago(7d)\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| extend SiteId=tostring(SiteId), Ip=tostring(SiteStatistics.wans.WAN.externalIp)\n| where isnotempty(Ip)\n| summarize DistinctIPs=dcount(Ip), IPList=make_set(Ip) by SiteId\n| where DistinctIPs > 1\n| join kind=leftouter H on SiteId\n| project SiteName, DistinctIPs, IPList",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Sites where the external WAN IP changed in 7d",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "DistinctIPs",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  }
                ]
              },
              "noDataMessage": "All sites kept a stable external WAN IP - no failovers or carrier changes.",
              "noDataMessageStyle": 5
            },
            "name": "q-beda04e0",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "47b09d68-5e0e-43a1-996b-bbe28843e6ed",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Off-Hours Device Adoption' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F3WQQUsDQQyF7%2F0VOW5lQXtRBBXEQj1UPKh4XOLO2zbWmSyzWdsVf7wzirR76BwySXhfwstLkEaqJzE8cOAVYjXHp9Toqrvl5Ju63nuO8gXiuKo874pn8VggILLBlXQypbeBxCXtdo0Iki6owbc2FOy0NdGQkWkSYGcIjm4P2nRNpi6NslSMgXJC%2F%2B9e%2B5iU6%2FRp43gojjGH0JyHx%2BYV2CQyMdpsU36cpFOa7V38bryiC9L4l9%2FQ7DIX%2B6kSqDgr6Tw7a6O%2Bo7aRtZIC5%2BjV4aPMEtfXtpSABGh0iPlyo2M4dPUPngqGV5EBAAA%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-7e23e3",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "4f453b30-bac9-40ae-8ec2-ba6a3b2580d6",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud WAN IP Geo Deviation' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F5WTUW%2FTMBDH3%2FspjjzZKKrgBaQhIyHQaKRtmlQQj5UXX7rbHDuyHdbC4LNzbpsspeyBN%2Bfufv%2B7s%2F%2BxmGABCr46ami1pISX2uk1ht05rj5ewCPEvm11oB8IOqxXrd6IL9TiZ3QYdEJTwksJN1tIPqZAbi0io5WRTN55cnBPziiLTfJ9wgDitNeCyf%2FrRYZru%2BDvsE5wy3hlFHH2PBA6Y7dXukU1DhSw84HpZWKNueOclODdAWQl3CTG4BKTPiZbjuyBEpZ909BGxf7mkPx74RJelfBGTibbJ9RpYd5%2B16n22mKsURA1gqLzCdsubcV0EXm8VwlFwaEMDAPDCwWFwUb3NhWgeZWJ1FDEzHA8SPBUtU5iEgVRDIvylyykfDd73huzR3i4xYBw9EbwHvTai7dGjvniu7Y9np1pawsg9xvEz6xxTpYd8YvfIpy657RsNj7Us%2FdadcfB%2FOIUE9Vx%2FqBdnH%2F7cDXPGsFpW3VPA06uax9%2B8uGnzLs6VddRmdr3LuUSbnV9wRnV6ntcRdwFszP3o4zCE5rv5fXs3%2F%2FEIrtxJAf3DCYppypD4z%2BqVPd0ugMAAA%3D%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-a6dc97",
            "customWidth": "50"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">WAN performance: persistent issues & latency long-tail</div>"
            },
            "name": "div-wan-performance:-per-c7570d"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated > ago(7d)\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend PL=todouble(p.data.wan.packetLoss), Lat=todouble(p.data.wan.avgLatency)\n| join kind=leftouter H on SiteId\n| summarize HighLossPeriods=countif(PL > 1), HighLatPeriods=countif(Lat > 100), Total=count() by SiteName\n| where HighLossPeriods > 0 or HighLatPeriods > 0\n| extend LossPct=round(100.0*HighLossPeriods/Total, 1), LatPct=round(100.0*HighLatPeriods/Total, 1)\n| order by HighLossPeriods desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Sites with recurring high packet loss (>1%) or latency (>100ms) over 7d",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "HighLossPeriods",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "HighLatPeriods",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "LossPct",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright",
                      "min": 0,
                      "max": 100
                    }
                  },
                  {
                    "columnMatch": "LatPct",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange",
                      "min": 0,
                      "max": 100
                    }
                  }
                ]
              },
              "noDataMessage": "No persistent WAN issues - ISP links are healthy.",
              "noDataMessageStyle": 5
            },
            "name": "q-fe958ab8",
            "customWidth": "50"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let H = Unifi_SiteManager_Sites_CL | summarize arg_max(TimeGenerated, *) by tostring(SiteId) | join kind=leftouter (Unifi_SiteManager_Hosts_CL | summarize arg_max(TimeGenerated, *) by Id | project HostId=Id, FriendlyName=tostring(ReportedState.name)) on HostId | extend MetaName=tostring(Meta.name), Suffix=substring(tostring(SiteId), 0, 6) | project SiteId=tostring(SiteId), SiteName=coalesce(iif(isnotempty(FriendlyName), FriendlyName, \"\"), iif(MetaName != \"default\" and isnotempty(MetaName), MetaName, \"\"), strcat(MetaName, \" (\", Suffix, \")\"));\nUnifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated > ago(7d)\n| where \"value::all\" in~ ({SiteFilter}) or tostring(SiteId) in~ ({SiteFilter})\n| mv-expand p = Periods\n| extend ML=todouble(p.data.wan.maxLatency), AL=todouble(p.data.wan.avgLatency)\n| join kind=leftouter H on SiteId\n| summarize AvgPeakLat=round(avg(ML),0), AvgMeanLat=round(avg(AL),0), WorstPeak=round(max(ML),0) by SiteName\n| extend Tail = round(AvgPeakLat - AvgMeanLat, 0)\n| order by Tail desc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Where is peak latency dramatically worse than average? (long-tail hotspots)",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "AvgPeakLat",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "orange"
                    }
                  },
                  {
                    "columnMatch": "WorstPeak",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "Tail",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  }
                ]
              },
              "noDataMessage": "No latency long-tail signal detected.",
              "noDataMessageStyle": 5
            },
            "name": "q-e401d655",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "2b405459-faa2-40e9-abd7-d6037bcd8da8",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Persistent WAN Issues' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F5VSS2%2FTQBC%2B51cMPq0rE8IFpCJzQSqJlKJIKedo4h072653rfW4TaDw25l1Hs3rws3e%2BV7zsMQwhhx%2BOlOaxdww3aPDikL%2F3S6%2BTeEV2q6uMZhfBBiqRY1r9WBq%2Bk6OAjLpDG5SWG6AfcvBuEq1Qp3oVJiP3jh4Mk7nlkr2HVMAdek1Fub%2FeRkt2Cb4RyoYVkKf6NxI9S4YctpufmBN%2BSFQoMYHYc9ZNIZOamkK3u2IokRrFhrcE%2BMps5aXLSGDeVeWZp233XJXPG84g1EGn9KjZNtCfgmM3fdOhUdLbUHKmFKZ1nmmuuGNOm4kPe0rgySRp0jYB4Z3OSSaSuwsJ4DSypHUHiSc%2FedOQlIVyOroFVSyb1T%2B0iRNvwwu9zWZz4QTTBGXNniFlxUFgpNFwVfAyqvPOj3Uk2e0Hd3eorUJGPcX1O8oemesnMUfWUi4PKFLmMjVz%2B9p3cQuGzndhoLxuh0ctjibysC175aWVDPUKBt8QTdssHginvq2lc6nyFdB%2BFxJiVyxiUbXznccD2cbb3B8rmNTraL4bBtHFts5lhXNpjKKj2LZA5DP6%2FIUAaORQB48o91WVH%2Fm%2BzM5zPDMRZijOLdT7fj6No4eXnAeRFYrMRqObs5kPvTGWR8zylxDH9TfwOLhg5aZSNLzYFqO%2Bh9A%2FpeMXQQAAA%3D%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-37cdf6",
            "customWidth": "50"
          },
          {
            "type": 11,
            "content": {
              "version": "LinkItem/1.0",
              "style": "list",
              "links": [
                {
                  "id": "e14563cd-c369-4d64-99f2-776ef3f47048",
                  "cellValue": "run-in-logs",
                  "linkTarget": "OpenBlade",
                  "linkLabel": "Run 'UniFi Cloud Long-Tail Latency Hotspots' in Log Analytics",
                  "preText": "\u25b6  ",
                  "style": "link",
                  "linkIsContextBlade": true,
                  "bladeOpenContext": {
                    "bladeName": "LogsBlade",
                    "extensionName": "Microsoft_Azure_Monitoring_Logs",
                    "bladeParameters": [
                      {
                        "name": "resourceId",
                        "source": "static",
                        "value": "{Workspace}"
                      },
                      {
                        "name": "source",
                        "source": "static",
                        "value": "LogsBlade.AnalyticsShareLinkToQuery"
                      },
                      {
                        "name": "q",
                        "source": "static",
                        "value": "H4sIADDtBWoC%2F5WSQW%2FbMAyF7%2FkVnE%2FS4AY9bUAHDwgGdAmQDAXSYceAsWhXrSwZspwmW7ffPiq2G2fpZTdHjx%2FJFz5DAeaQwXerC71Z60ArtFiSP343my9LeIGmrSr0%2BicB%2BnJT4V7c64q%2BkiWPgVQK7yVsDxBcE7y2pWgYXSjJ5KPTFp60VZmhIrg2kAdxOWvO5P%2FN0opra%2B8eKQ%2FwwPhCZZrVW6%2FJKnP4hhVlrwt5qp1neh24x9SyJiU424PcifaBMVhRwHOy4pcOSGHdFoXeZ0277cV%2FDadwncIHOdqsE7LLwuj%2BOCl3aKjJSWhdCN1YF6iqw0GMjchzXykkCT9FYFgY3mWQKCqwNSEBZCujVkMRM8Nn34K3yjGI0SuIZDDKv2Qi5afJ5b0W6ztmvM7j0SYv8PxAnuDsUPAZsHTio5KverJD09LNDRqTgLZ%2FQPyKTW%2B14Vj85oP4ywhdlnG7andF%2Bzq6rDm6NXntVDM5XXHJf7hy7daQqKcK%2BYLPaKecpSVvZvMDO5%2B9XYO7cqiZvJ3eecxNt91knNbZrrwjfGI68661SnArsVrK9DpO25UrQnsuznrxh%2FNNiGyvxcx3YAz6EJSTvXvUhm13xaexcDUaw0mMBpxXvDJ3OTKKc%2FYXP5EHDfADAAA%3D"
                      }
                    ]
                  }
                }
              ]
            },
            "name": "hunt-link-79c408",
            "customWidth": "50"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "hunts"
      },
      "name": "group-hunts"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Ingest rate per table (last 24h)</div>"
            },
            "name": "div-ingest-rate-per-tabl-68924a"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "union withsource=Table Unifi_SiteManager_Sites_CL, Unifi_SiteManager_Hosts_CL, Unifi_SiteManager_Devices_CL, Unifi_SiteManager_ISPMetrics_CL\n| where TimeGenerated > ago(24h)\n| summarize Rows=count() by Table, bin(TimeGenerated, 1h)\n| order by TimeGenerated asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "timechart",
              "title": "Rows ingested per Site Manager table per hour (last 24h)",
              "noDataMessage": "No Site Manager data ingested in the last 24h - check the connector card under Sentinel > Data connectors.",
              "noDataMessageStyle": 5
            },
            "name": "q-67b70dda"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Per-table freshness</div>"
            },
            "name": "div-per-table-freshness-ab964f"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "union withsource=Table Unifi_SiteManager_Sites_CL, Unifi_SiteManager_Hosts_CL, Unifi_SiteManager_Devices_CL, Unifi_SiteManager_ISPMetrics_CL\n| summarize LastRow=max(TimeGenerated), TotalRows=count() by Table\n| extend MinutesAgo=toint((now() - LastRow) / 1m)\n| extend Status=case(MinutesAgo < 15, \"Fresh\", MinutesAgo < 60, \"Recent\", MinutesAgo < 360, \"Stale\", \"Very Stale\")\n| project Table, LastRow, MinutesAgo, TotalRows, Status\n| order by MinutesAgo asc",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "How current is each Site Manager table?",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "LastRow",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "MinutesAgo",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  },
                  {
                    "columnMatch": "TotalRows",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  },
                  {
                    "columnMatch": "Status",
                    "formatter": 11
                  }
                ]
              }
            },
            "name": "q-04846b0e"
          },
          {
            "type": 1,
            "content": {
              "json": "<div style=\"border-left:4px solid #3b82f6;padding:6px 12px;margin:8px 0 0 0;background:rgba(59,130,246,0.05);font-size:14px;font-weight:600;letter-spacing:0.3px;text-transform:uppercase;color:#94a3b8\">Log Analytics operational events</div>"
            },
            "name": "div-log-analytics-operat-4426a0"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "_LogOperation\n| where TimeGenerated > ago(24h)\n| where _ResourceId contains \"Unifi_SiteManager\" or Detail contains \"Unifi_SiteManager\"\n| project TimeGenerated, Operation, Level, Detail\n| order by TimeGenerated desc | take 100",
              "size": 0,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "title": "Log Analytics operational events touching Site Manager tables",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "TimeGenerated",
                    "formatter": 6
                  },
                  {
                    "columnMatch": "Level",
                    "formatter": 11
                  }
                ]
              },
              "noDataMessage": "No operational issues recorded in the last 24h.",
              "noDataMessageStyle": 5
            },
            "name": "q-9106fe14"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selectedTab",
        "comparison": "isEqualTo",
        "value": "pipeline"
      },
      "name": "group-pipeline"
    },
    {
      "type": 1,
      "content": {
        "json": "<div style=\"margin-top:32px;padding-top:16px;border-top:1px solid #1e293b;color:#64748b;font-size:12px\"><strong>UniFi Site Manager (CCF)</strong> - Microsoft Sentinel content from the UniFi Site Manager solution. Tables polled every 5 minutes from the Site Manager API: sites, hosts, devices, ISP metrics. Scope every panel via the time range and Sites filter at the top.</div>"
      },
      "name": "footer"
    }
  ],
  "fallbackResourceIds": [
    "Azure Monitor"
  ],
  "fromTemplateId": "sentinel-UnifiSiteManager-CCF",
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}