├── AzureADAuditLogs.json ├── AzureADHygiene ├── AzureADMaintenace.json ├── B2BFramework.json ├── CISAZT.json ├── CISAZTv2-Rev1.json ├── Conditional Access Summaries, Insights, Security & Monitoring (CA-SISM) ├── EIDSCAGov.json ├── EntraIDHygiene.json ├── M2131-EL-Validation.json ├── M2131v0.1.0-COPY.csv ├── M2131v0.2.0.csv ├── XDRSizing.kql ├── ca-cism2.json ├── catobepublished.json ├── cisaMAG.json ├── cismtrial2.json ├── customzt01.json ├── garbage.json ├── readme.md └── sentineldefendercost.json /AzureADAuditLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 1, 6 | "content": { 7 | "json": "## Azure AD audit logs" 8 | }, 9 | "name": "text - 1" 10 | }, 11 | { 12 | "type": 9, 13 | "content": { 14 | "version": "KqlParameterItem/1.0", 15 | "crossComponentResources": [ 16 | "{Workspace}" 17 | ], 18 | "parameters": [ 19 | { 20 | "id": "70406f7d-adc6-47c6-ba96-7fe4fd532828", 21 | "version": "KqlParameterItem/1.0", 22 | "name": "Workspace", 23 | "type": 5, 24 | "description": "Select at least one workspace that contains continuous export data based on the selected subscriptions", 25 | "isRequired": true, 26 | "multiSelect": true, 27 | "quote": "'", 28 | "delimiter": ",", 29 | "query": "resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| project id", 30 | "crossComponentResources": [ 31 | "value::all" 32 | ], 33 | "typeSettings": { 34 | "additionalResourceOptions": [], 35 | "showDefault": false 36 | }, 37 | "timeContext": { 38 | "durationMs": 0 39 | }, 40 | "timeContextFromParameter": "TimeRange", 41 | "queryType": 1, 42 | "resourceType": "microsoft.resourcegraph/resources", 43 | "value": [] 44 | }, 45 | { 46 | "id": "bc372bf5-2dcd-4efa-aa85-94b6e6fafe14", 47 | "version": "KqlParameterItem/1.0", 48 | "name": "TimeRange", 49 | "type": 4, 50 | "isRequired": true, 51 | "value": { 52 | "durationMs": 2592000000 53 | }, 54 | "typeSettings": { 55 | "selectableValues": [ 56 | { 57 | "durationMs": 300000 58 | }, 59 | { 60 | "durationMs": 900000 61 | }, 62 | { 63 | "durationMs": 1800000 64 | }, 65 | { 66 | "durationMs": 3600000 67 | }, 68 | { 69 | "durationMs": 14400000 70 | }, 71 | { 72 | "durationMs": 43200000 73 | }, 74 | { 75 | "durationMs": 86400000 76 | }, 77 | { 78 | "durationMs": 172800000 79 | }, 80 | { 81 | "durationMs": 259200000 82 | }, 83 | { 84 | "durationMs": 604800000 85 | }, 86 | { 87 | "durationMs": 1209600000 88 | }, 89 | { 90 | "durationMs": 2419200000 91 | }, 92 | { 93 | "durationMs": 2592000000 94 | }, 95 | { 96 | "durationMs": 5184000000 97 | }, 98 | { 99 | "durationMs": 7776000000 100 | } 101 | ], 102 | "allowCustom": true 103 | } 104 | }, 105 | { 106 | "id": "e032b9f7-5449-4180-9c20-75760afa96f6", 107 | "version": "KqlParameterItem/1.0", 108 | "name": "User", 109 | "type": 2, 110 | "isRequired": true, 111 | "multiSelect": true, 112 | "quote": "'", 113 | "delimiter": ",", 114 | "query": "AuditLogs\r\n| where SourceSystem == \"Azure AD\"\r\n| extend initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n//| where initiator!= \"\"\r\n| summarize Count = count() by initiator\r\n| order by Count desc, initiator asc\r\n| project Value = initiator, Label = strcat(initiator, ' - ', Count), Selected = false", 115 | "crossComponentResources": [ 116 | "{Workspace}" 117 | ], 118 | "isHiddenWhenLocked": true, 119 | "typeSettings": { 120 | "additionalResourceOptions": [ 121 | "value::all" 122 | ], 123 | "selectAllValue": "All", 124 | "showDefault": false 125 | }, 126 | "timeContext": { 127 | "durationMs": 0 128 | }, 129 | "timeContextFromParameter": "TimeRange", 130 | "defaultValue": "value::all", 131 | "queryType": 0, 132 | "resourceType": "microsoft.operationalinsights/workspaces" 133 | }, 134 | { 135 | "id": "0a59a0b3-6d93-4fee-bdbe-147383c510c6", 136 | "version": "KqlParameterItem/1.0", 137 | "name": "Category", 138 | "type": 2, 139 | "isRequired": true, 140 | "multiSelect": true, 141 | "quote": "'", 142 | "delimiter": ",", 143 | "query": "AuditLogs\r\n| extend initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n| where \"{User:lable}\" == \"All\" or initiator in ({User})\r\n| summarize Count = count() by Category\r\n| order by Count desc, Category asc\r\n| project Value = Category, Label = strcat(Category, ' - ', Count)", 144 | "crossComponentResources": [ 145 | "{Workspace}" 146 | ], 147 | "typeSettings": { 148 | "additionalResourceOptions": [ 149 | "value::all" 150 | ], 151 | "selectAllValue": "All", 152 | "showDefault": false 153 | }, 154 | "timeContext": { 155 | "durationMs": 0 156 | }, 157 | "timeContextFromParameter": "TimeRange", 158 | "defaultValue": "value::all", 159 | "queryType": 0, 160 | "resourceType": "microsoft.operationalinsights/workspaces" 161 | }, 162 | { 163 | "id": "4d2b245b-5e59-4eb6-9f51-ba926581ab47", 164 | "version": "KqlParameterItem/1.0", 165 | "name": "Result", 166 | "type": 2, 167 | "isRequired": true, 168 | "multiSelect": true, 169 | "quote": "'", 170 | "delimiter": ",", 171 | "query": "AuditLogs\r\n| extend initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n| where \"{User:lable}\" == \"All\" or initiator in ({User})\r\n| summarize Count = count() by Result\r\n| order by Count desc, Result asc\r\n| project Value = Result, Label = strcat(Result, ' - ', Count, ' sign-ins')", 172 | "crossComponentResources": [ 173 | "{Workspace}" 174 | ], 175 | "typeSettings": { 176 | "additionalResourceOptions": [ 177 | "value::all" 178 | ], 179 | "selectAllValue": "All", 180 | "showDefault": false 181 | }, 182 | "timeContext": { 183 | "durationMs": 0 184 | }, 185 | "timeContextFromParameter": "TimeRange", 186 | "defaultValue": "value::all", 187 | "queryType": 0, 188 | "resourceType": "microsoft.operationalinsights/workspaces" 189 | } 190 | ], 191 | "style": "pills", 192 | "queryType": 0, 193 | "resourceType": "microsoft.operationalinsights/workspaces" 194 | }, 195 | "name": "parameters - 1" 196 | }, 197 | { 198 | "type": 3, 199 | "content": { 200 | "version": "KqlItem/1.0", 201 | "query": "let data = AuditLogs\r\n| where \"{Category:lable}\" == \"All\" or Category in ({Category})\r\n| where \"{Result:lable}\" == \"All\" or Result in ({Result})\r\n| extend initiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)\r\n| where initiatingUserPrincipalName != \"\" \r\n| where \"{User:lable}\" == \"All\" or initiatingUserPrincipalName in ({User});\r\ndata\r\n| summarize Count = count() by Category\r\n| join kind = fullouter (datatable(Category:string)['Medium', 'high', 'low']) on Category\r\n| project Category = iff(Category == '', Category1, Category), Count = iff(Category == '', 0, Count)\r\n| join kind = inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain} by Category)\r\n on Category\r\n| project-away Category1, TimeGenerated\r\n| extend Category = Category\r\n| union (\r\n data \r\n | summarize Count = count() \r\n | extend jkey = 1\r\n | join kind=inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated from {TimeRange:start} to {TimeRange:end} step {TimeRange:grain}\r\n | extend jkey = 1) on jkey\r\n | extend Category = 'All', Categorys = '*' \r\n)\r\n| order by Count desc\r\n| take 10", 202 | "size": 4, 203 | "title": "Categories volume", 204 | "timeContextFromParameter": "TimeRange", 205 | "exportFieldName": "Category", 206 | "exportParameterName": "CategoryFIlter", 207 | "exportDefaultValue": "All", 208 | "queryType": 0, 209 | "resourceType": "microsoft.operationalinsights/workspaces", 210 | "crossComponentResources": [ 211 | "{Workspace}" 212 | ], 213 | "visualization": "tiles", 214 | "tileSettings": { 215 | "titleContent": { 216 | "columnMatch": "Category", 217 | "formatter": 1, 218 | "formatOptions": { 219 | "showIcon": true 220 | } 221 | }, 222 | "leftContent": { 223 | "columnMatch": "Count", 224 | "formatter": 12, 225 | "formatOptions": { 226 | "palette": "auto", 227 | "showIcon": true 228 | }, 229 | "numberFormat": { 230 | "unit": 17, 231 | "options": { 232 | "style": "decimal", 233 | "maximumFractionDigits": 2, 234 | "maximumSignificantDigits": 3 235 | } 236 | } 237 | }, 238 | "secondaryContent": { 239 | "columnMatch": "Trend", 240 | "formatter": 21, 241 | "formatOptions": { 242 | "palette": "purple", 243 | "showIcon": true 244 | } 245 | }, 246 | "showBorder": false 247 | } 248 | }, 249 | "name": "query - 4" 250 | }, 251 | { 252 | "type": 3, 253 | "content": { 254 | "version": "KqlItem/1.0", 255 | "query": "let data = AuditLogs\r\n| where \"{Result:lable}\" == \"All\" or Result in ({Result})\r\n| extend initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n| where \"{User:lable}\" == \"All\" or initiator in ({User})\r\n| where \"{Category:lable}\" == \"All\" or Category in ({Category})\r\n| where Category == '{CategoryFIlter}' or '{CategoryFIlter}' == \"All\";\r\nlet appData = data\r\n| summarize TotalCount = count() by OperationName, Category\r\n| join kind=inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by OperationName\r\n | project-away TimeGenerated) on OperationName\r\n| order by TotalCount desc, OperationName asc\r\n| project OperationName, TotalCount, Trend, Category\r\n| serialize Id = row_number();\r\ndata\r\n| summarize TotalCount = count() by initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\"), Category, OperationName\r\n| join kind=inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by OperationName, initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n | project-away TimeGenerated) on OperationName, initiator\r\n| order by TotalCount desc, OperationName asc\r\n| project OperationName, initiator, TotalCount, Category, Trend\r\n| serialize Id = row_number(1000000)\r\n| join kind=inner (appData) on OperationName\r\n| project Id, Name = initiator, Type = 'initiator', ['Operations Count'] = TotalCount, Trend, Category, ParentId = Id1\r\n| union (appData \r\n | project Id, Name = OperationName, Type = 'Operation', ['Operations Count'] = TotalCount, Category, Trend)\r\n| order by ['Operations Count'] desc, Name asc", 256 | "size": 0, 257 | "showAnalytics": true, 258 | "title": "User activities", 259 | "timeContextFromParameter": "TimeRange", 260 | "exportParameterName": "UserInfo", 261 | "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\"}", 262 | "showExportToExcel": true, 263 | "queryType": 0, 264 | "resourceType": "microsoft.operationalinsights/workspaces", 265 | "crossComponentResources": [ 266 | "{Workspace}" 267 | ], 268 | "gridSettings": { 269 | "formatters": [ 270 | { 271 | "columnMatch": "Id", 272 | "formatter": 5, 273 | "formatOptions": { 274 | "showIcon": true 275 | } 276 | }, 277 | { 278 | "columnMatch": "Type", 279 | "formatter": 5, 280 | "formatOptions": { 281 | "showIcon": true 282 | } 283 | }, 284 | { 285 | "columnMatch": "Operations Count", 286 | "formatter": 8, 287 | "formatOptions": { 288 | "min": 0, 289 | "palette": "blue", 290 | "showIcon": true 291 | }, 292 | "numberFormat": { 293 | "unit": 0, 294 | "options": { 295 | "style": "decimal" 296 | } 297 | } 298 | }, 299 | { 300 | "columnMatch": "Trend", 301 | "formatter": 9, 302 | "formatOptions": { 303 | "min": 0, 304 | "palette": "turquoise", 305 | "showIcon": true 306 | }, 307 | "numberFormat": { 308 | "unit": 0, 309 | "options": { 310 | "style": "decimal" 311 | } 312 | } 313 | }, 314 | { 315 | "columnMatch": "ParentId", 316 | "formatter": 5, 317 | "formatOptions": { 318 | "showIcon": true 319 | } 320 | } 321 | ], 322 | "rowLimit": 1000, 323 | "filter": true, 324 | "hierarchySettings": { 325 | "idColumn": "Id", 326 | "parentColumn": "ParentId", 327 | "treeType": 0, 328 | "expanderColumn": "Name" 329 | } 330 | } 331 | }, 332 | "customWidth": "70", 333 | "showPin": true, 334 | "name": "query - 2" 335 | }, 336 | { 337 | "type": 3, 338 | "content": { 339 | "version": "KqlItem/1.0", 340 | "query": "let details = dynamic({UserInfo});\r\nAuditLogs\r\n| where \"{Category:lable}\" == \"All\" or Category in ({Category})\r\n| where \"{Result:lable}\" == \"All\" or Result in ({Result})\r\n| extend initiatingUserPrincipalName = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n//| where initiatingUserPrincipalName != \"\" \r\n| where \"{User:lable}\" == \"All\" or initiatingUserPrincipalName in ({User})\r\n| where details.Type == '*' or (details.Type == 'initiator' and initiatingUserPrincipalName == details.Name) or (details.Type == 'Operation' and OperationName == details.Name)\r\n| summarize Activities = count() by initiatingUserPrincipalName\r\n| sort by Activities desc nulls last ", 341 | "size": 0, 342 | "title": "Top active users", 343 | "timeContextFromParameter": "TimeRange", 344 | "queryType": 0, 345 | "resourceType": "microsoft.operationalinsights/workspaces", 346 | "crossComponentResources": [ 347 | "{Workspace}" 348 | ], 349 | "visualization": "piechart" 350 | }, 351 | "customWidth": "30", 352 | "name": "query - 3" 353 | }, 354 | { 355 | "type": 3, 356 | "content": { 357 | "version": "KqlItem/1.0", 358 | "query": "let details = dynamic({UserInfo});\r\nlet data = AuditLogs\r\n| extend initiator = iif (tostring(InitiatedBy.user.userPrincipalName) != \"\", tostring(InitiatedBy.user.userPrincipalName), \"unknown\")\r\n| where details.Type == '*' or (details.Type == 'initiator' and initiator == details.Name) or (details.Type == 'Operation' and OperationName == details.Name)\r\n| where \"{Category:lable}\" == \"All\" or Category in ({Category})\r\n| where \"{Result:lable}\" == \"All\" or Result in ({Result})\r\n| where \"{User:lable}\" == \"All\" or initiator in ({User});\r\nlet appData = data\r\n| summarize TotalCount = count() by Result\r\n| join kind=inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by Result\r\n | project-away TimeGenerated) on Result\r\n| order by TotalCount desc, Result asc\r\n| project Result, TotalCount, Trend\r\n| serialize Id = row_number();\r\ndata\r\n| summarize TotalCount = count() by OperationName, Result\r\n| join kind=inner (data\r\n | make-series Trend = count() default = 0 on TimeGenerated in range({TimeRange:start}, {TimeRange:end}, {TimeRange:grain}) by Result, OperationName\r\n | project-away TimeGenerated) on Result, OperationName\r\n| order by TotalCount desc, Result asc\r\n| project Result, OperationName, TotalCount, Trend\r\n| serialize Id = row_number(1000000)\r\n| join kind=inner (appData) on Result\r\n| project Id, Name = OperationName, Type = 'Operation', ['Results Count'] = TotalCount, Trend, ParentId = Id1\r\n| union (appData \r\n | project Id, Name = Result, Type = 'Result', ['Results Count'] = TotalCount, Trend)\r\n| order by ['Results Count'] desc, Name asc", 359 | "size": 0, 360 | "title": "Result status", 361 | "timeContextFromParameter": "TimeRange", 362 | "exportParameterName": "ResultInfo", 363 | "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\"}", 364 | "queryType": 0, 365 | "resourceType": "microsoft.operationalinsights/workspaces", 366 | "crossComponentResources": [ 367 | "{Workspace}" 368 | ], 369 | "gridSettings": { 370 | "formatters": [ 371 | { 372 | "columnMatch": "Id", 373 | "formatter": 5 374 | }, 375 | { 376 | "columnMatch": "Type", 377 | "formatter": 5 378 | }, 379 | { 380 | "columnMatch": "Results Count", 381 | "formatter": 8, 382 | "formatOptions": { 383 | "min": 0, 384 | "palette": "grayBlue" 385 | } 386 | }, 387 | { 388 | "columnMatch": "Trend", 389 | "formatter": 9, 390 | "formatOptions": { 391 | "palette": "greenDark" 392 | } 393 | }, 394 | { 395 | "columnMatch": "ParentId", 396 | "formatter": 5 397 | } 398 | ], 399 | "hierarchySettings": { 400 | "idColumn": "Id", 401 | "parentColumn": "ParentId", 402 | "treeType": 0, 403 | "expanderColumn": "Name" 404 | } 405 | } 406 | }, 407 | "customWidth": "70", 408 | "name": "query - 5" 409 | } 410 | ], 411 | "fallbackResourceIds": [ 412 | "Azure Monitor" 413 | ], 414 | "fromTemplateId": "sentinel-AzureActiveDirectoryAuditLogs", 415 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 416 | } 417 | -------------------------------------------------------------------------------- /AzureADHygiene: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 1, 6 | "content": { 7 | "json": "# Azure Active Directory Hygiene" 8 | }, 9 | "name": "text - 34" 10 | }, 11 | { 12 | "type": 9, 13 | "content": { 14 | "version": "KqlParameterItem/1.0", 15 | "crossComponentResources": [ 16 | "value::all" 17 | ], 18 | "parameters": [ 19 | { 20 | "id": "8c87c98a-2ee4-4b06-9152-ae62330b3c31", 21 | "version": "KqlParameterItem/1.0", 22 | "name": "Workspace", 23 | "type": 5, 24 | "isRequired": true, 25 | "multiSelect": true, 26 | "quote": "'", 27 | "delimiter": ",", 28 | "query": "resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| project id", 29 | "crossComponentResources": [ 30 | "value::all" 31 | ], 32 | "typeSettings": { 33 | "additionalResourceOptions": [] 34 | }, 35 | "timeContext": { 36 | "durationMs": 86400000 37 | }, 38 | "queryType": 1, 39 | "resourceType": "microsoft.resourcegraph/resources", 40 | "value": [] 41 | } 42 | ], 43 | "style": "pills", 44 | "queryType": 1, 45 | "resourceType": "microsoft.resourcegraph/resources" 46 | }, 47 | "name": "parameters - 4" 48 | }, 49 | { 50 | "type": 11, 51 | "content": { 52 | "version": "LinkItem/1.0", 53 | "style": "tabs", 54 | "links": [ 55 | { 56 | "id": "b39ca7b9-0b5d-4f82-90a5-ef5c694b50e3", 57 | "cellValue": "Tab", 58 | "linkTarget": "parameter", 59 | "linkLabel": "Users and Guests", 60 | "subTarget": "ug", 61 | "style": "link" 62 | }, 63 | { 64 | "id": "411a469b-cbac-4a49-b229-9faeeeeed3ba", 65 | "cellValue": "Tab", 66 | "linkTarget": "parameter", 67 | "linkLabel": "Service Principals", 68 | "subTarget": "sp", 69 | "style": "link" 70 | }, 71 | { 72 | "id": "1ff02fa4-66ad-4ae4-b611-afb441b32951", 73 | "cellValue": "Tab", 74 | "linkTarget": "parameter", 75 | "linkLabel": "Enterprise Applications", 76 | "subTarget": "ea", 77 | "style": "link" 78 | }, 79 | { 80 | "id": "eaeab803-85b1-4755-a70b-9c0d35e066cc", 81 | "cellValue": "Tab", 82 | "linkTarget": "parameter", 83 | "linkLabel": "Privileged Access", 84 | "subTarget": "pa", 85 | "style": "link" 86 | }, 87 | { 88 | "id": "74ad5f79-b4a6-4cc9-a31e-771cb4acaf22", 89 | "cellValue": "Tab", 90 | "linkTarget": "parameter", 91 | "linkLabel": "MFA and Passwordless", 92 | "subTarget": "mfa", 93 | "style": "link" 94 | }, 95 | { 96 | "id": "4da2d8ee-7860-4165-a34c-1699313651ba", 97 | "cellValue": "Tab", 98 | "linkTarget": "parameter", 99 | "linkLabel": "Legacy Authentication", 100 | "subTarget": "la", 101 | "style": "link" 102 | }, 103 | { 104 | "id": "1e53250a-c522-4722-9949-5e0ffac99886", 105 | "cellValue": "Tab", 106 | "linkTarget": "parameter", 107 | "linkLabel": "Conditional Access", 108 | "subTarget": "ca", 109 | "style": "link" 110 | } 111 | ] 112 | }, 113 | "name": "links - 37" 114 | }, 115 | { 116 | "type": 1, 117 | "content": { 118 | "json": "User and Guests time values. Set the 'MaxTimeValue' to how far back to look (based off your log retention or parameters and set'MinTimeValue' for how many days to look back from current time." 119 | }, 120 | "conditionalVisibility": { 121 | "parameterName": "Tab", 122 | "comparison": "isEqualTo", 123 | "value": "ug" 124 | }, 125 | "name": "text - 30" 126 | }, 127 | { 128 | "type": 9, 129 | "content": { 130 | "version": "KqlParameterItem/1.0", 131 | "parameters": [ 132 | { 133 | "id": "62339408-f594-49c1-b272-e8db1f0a0ffb", 134 | "version": "KqlParameterItem/1.0", 135 | "name": "MaxTimeValue", 136 | "type": 1, 137 | "timeContext": { 138 | "durationMs": 0 139 | }, 140 | "timeContextFromParameter": "TimeRange", 141 | "value": "365" 142 | }, 143 | { 144 | "id": "b9b49b7d-f818-4ff5-b45a-6086e0af0d14", 145 | "version": "KqlParameterItem/1.0", 146 | "name": "MinTimeValue", 147 | "type": 1, 148 | "timeContext": { 149 | "durationMs": 0 150 | }, 151 | "timeContextFromParameter": "TimeRange", 152 | "value": "90" 153 | } 154 | ], 155 | "style": "pills", 156 | "queryType": 0, 157 | "resourceType": "microsoft.operationalinsights/workspaces" 158 | }, 159 | "conditionalVisibility": { 160 | "parameterName": "Tab", 161 | "comparison": "isEqualTo", 162 | "value": "ug" 163 | }, 164 | "name": "parameters - 19" 165 | }, 166 | { 167 | "type": 3, 168 | "content": { 169 | "version": "KqlItem/1.0", 170 | "query": "// Get Sign-in logs for inactive users\r\nSigninLogs\r\n| where UserType == \"Member\" or UserType == \"Guest\"\r\n| where TimeGenerated > ago({MaxTimeValue}d)\r\n| where ResultType == 0\r\n| where isnotempty(UserType)\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| where TimeGenerated < ago({MinTimeValue}d)\r\n| summarize by TimeGenerated, UserType, UserPrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\",now(),TimeGenerated), HomeTenantId, ResourceTenantId\r\n| sort by TimeGenerated desc\r\n", 171 | "size": 0, 172 | "showAnalytics": true, 173 | "title": "Member or Guest Last Logon based off Time Values", 174 | "exportParameterName": "Detail", 175 | "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\", \"Parent\":\"*\"}", 176 | "queryType": 0, 177 | "resourceType": "microsoft.operationalinsights/workspaces", 178 | "crossComponentResources": [ 179 | "{Workspace}" 180 | ], 181 | "gridSettings": { 182 | "formatters": [ 183 | { 184 | "columnMatch": "UserType", 185 | "formatter": 5 186 | }, 187 | { 188 | "columnMatch": "Days Since Last Logon", 189 | "formatter": 1 190 | } 191 | ], 192 | "hierarchySettings": { 193 | "treeType": 1, 194 | "groupBy": [ 195 | "UserType" 196 | ] 197 | } 198 | }, 199 | "tileSettings": { 200 | "showBorder": false, 201 | "titleContent": { 202 | "columnMatch": "CA Policy Name", 203 | "formatter": 1 204 | }, 205 | "leftContent": { 206 | "columnMatch": "failure", 207 | "formatter": 12, 208 | "formatOptions": { 209 | "palette": "auto" 210 | }, 211 | "numberFormat": { 212 | "unit": 17, 213 | "options": { 214 | "maximumSignificantDigits": 3, 215 | "maximumFractionDigits": 2 216 | } 217 | } 218 | } 219 | }, 220 | "mapSettings": { 221 | "locInfo": "LatLong", 222 | "sizeSettings": "failure", 223 | "sizeAggregation": "Sum", 224 | "legendMetric": "failure", 225 | "legendAggregation": "Sum", 226 | "itemColorSettings": { 227 | "type": "heatmap", 228 | "colorAggregation": "Sum", 229 | "nodeColorField": "failure", 230 | "heatmapPalette": "greenRed" 231 | } 232 | } 233 | }, 234 | "conditionalVisibility": { 235 | "parameterName": "Tab", 236 | "comparison": "isEqualTo", 237 | "value": "ug" 238 | }, 239 | "customWidth": "75", 240 | "name": "query - 10 - Copy - Copy", 241 | "styleSettings": { 242 | "margin": "50" 243 | } 244 | }, 245 | { 246 | "type": 3, 247 | "content": { 248 | "version": "KqlItem/1.0", 249 | "query": "AuditLogs\r\n| where TimeGenerated between (ago({MaxTimeValue}d) .. ago({MinTimeValue}d)) \r\n| where OperationName == \"Invite external user\"\r\n| extend GuestUPN = tolower(tostring(TargetResources[0].userPrincipalName))\r\n| summarize arg_max(TimeGenerated, *) by GuestUPN\r\n| project TimeGenerated, GuestUPN\r\n| join kind=leftanti (\r\n AuditLogs\r\n //| where TimeGenerated > ago (timerange)\r\n | where TimeGenerated > ago({MaxTimeValue}d)\r\n | where OperationName == \"Redeem external user invite\"\r\n | where CorrelationId <> \"00000000-0000-0000-0000-000000000000\"\r\n | extend d = tolower(tostring(TargetResources[0].displayName))\r\n | parse d with * \"upn: \" GuestUPN \",\" *\r\n | project TimeGenerated, GuestUPN)\r\n on GuestUPN\r\n| project TimeGenerated, GuestUPN, ['Days Since Invite Sent']=datetime_diff(\"day\", now(), TimeGenerated)", 250 | "size": 0, 251 | "title": "Expired Guest Invites based off Time Values", 252 | "queryType": 0, 253 | "resourceType": "microsoft.operationalinsights/workspaces", 254 | "crossComponentResources": [ 255 | "{Workspace}" 256 | ] 257 | }, 258 | "conditionalVisibility": { 259 | "parameterName": "Tab", 260 | "comparison": "isEqualTo", 261 | "value": "ug" 262 | }, 263 | "name": "query - 30" 264 | }, 265 | { 266 | "type": 3, 267 | "content": { 268 | "version": "KqlItem/1.0", 269 | "query": "SigninLogs\r\n| where TimeGenerated > ago (360d)\r\n| where UserType == \"Guest\"\r\n| where AADTenantId != HomeTenantId and HomeTenantId != ResourceTenantId\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| project TimeGenerated, UserPrincipalName\r\n| summarize ['Count of Last Signin']=count() by startofmonth(TimeGenerated)\r\n| render columnchart with (title=\"Guest inactivity per month\")", 270 | "size": 0, 271 | "title": "Guest inactivity per month within last 365d", 272 | "queryType": 0, 273 | "resourceType": "microsoft.operationalinsights/workspaces", 274 | "crossComponentResources": [ 275 | "{Workspace}" 276 | ], 277 | "tileSettings": { 278 | "showBorder": false 279 | }, 280 | "graphSettings": { 281 | "type": 0 282 | } 283 | }, 284 | "conditionalVisibility": { 285 | "parameterName": "Tab", 286 | "comparison": "isEqualTo", 287 | "value": "ug" 288 | }, 289 | "name": "query - 4" 290 | }, 291 | { 292 | "type": 1, 293 | "content": { 294 | "json": "Service Principal Time Value. Set the 'SPTime' to look back when a Service Principal last logged on and their relative error codes.\r\n" 295 | }, 296 | "conditionalVisibility": { 297 | "parameterName": "Tab", 298 | "comparison": "isEqualTo", 299 | "value": "sp" 300 | }, 301 | "name": "text - 31" 302 | }, 303 | { 304 | "type": 9, 305 | "content": { 306 | "version": "KqlParameterItem/1.0", 307 | "parameters": [ 308 | { 309 | "id": "9d469d3d-e539-4940-adf0-47698983b0fa", 310 | "version": "KqlParameterItem/1.0", 311 | "name": "SPTime", 312 | "type": 1, 313 | "timeContext": { 314 | "durationMs": 86400000 315 | }, 316 | "value": "90" 317 | } 318 | ], 319 | "style": "pills", 320 | "queryType": 0, 321 | "resourceType": "microsoft.operationalinsights/workspaces" 322 | }, 323 | "conditionalVisibility": { 324 | "parameterName": "Tab", 325 | "comparison": "isEqualTo", 326 | "value": "sp" 327 | }, 328 | "name": "parameters - 16" 329 | }, 330 | { 331 | "type": 3, 332 | "content": { 333 | "version": "KqlItem/1.0", 334 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n//| where TimeGenerated > ago(365d)\r\n| where ResultType == \"0\"\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project TimeGenerated, ServicePrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\", now(),TimeGenerated)\r\n| where ['Days Since Last Logon'] >= 45 | sort by ['Days Since Last Logon'] desc ", 335 | "size": 1, 336 | "title": "Inactive Service Principals based off 'SPTime'", 337 | "queryType": 0, 338 | "resourceType": "microsoft.operationalinsights/workspaces", 339 | "crossComponentResources": [ 340 | "{Workspace}" 341 | ], 342 | "gridSettings": { 343 | "formatters": [ 344 | { 345 | "columnMatch": "Days Since Last Logon", 346 | "formatter": 1 347 | } 348 | ] 349 | } 350 | }, 351 | "conditionalVisibility": { 352 | "parameterName": "Tab", 353 | "comparison": "isEqualTo", 354 | "value": "sp" 355 | }, 356 | "name": "query - 6" 357 | }, 358 | { 359 | "type": 3, 360 | "content": { 361 | "version": "KqlItem/1.0", 362 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n| where ResultType != \"0\"\r\n| extend ErrorDescription = case (\r\n ResultType == \"7000215\", strcat(\"Invalid client secret is provided\"),\r\n ResultType == \"7000222\", strcat(\"The provided client secret keys are expired\"),\r\n ResultType == \"700027\", strcat(\"Client assertion failed signature validation\"),\r\n ResultType == \"700024\", strcat(\"Client assertion is not within its valid time range\"),\r\n ResultType == \"70021\", strcat(\"No matching federated identity record found for presented assertion\"),\r\n ResultType == \"500011\", strcat(\"The resource principal named was not found in the tenant\"),\r\n ResultType == \"700082\", strcat(\"The refresh token has expired due to inactivity\"),\r\n ResultType == \"90025\", strcat(\"Request processing has exceeded gateway allowance\"),\r\n ResultType == \"500341\", strcat(\"The user account has been deleted from the directory\"),\r\n ResultType == \"100007\", strcat(\"AAD Regional ONLY supports auth either for MSIs OR for requests from MSAL using SN+I for 1P apps or 3P apps in Microsoft infrastructure tenants\"),\r\n ResultType == \"1100000\", strcat(\"Non-retryable error has occurred\"),\r\n ResultType == \"90033\", strcat(\"A transient error has occurred. Please try again\"),\r\n ResultType == \"53003\",strcat(\"Access has been blocked by Conditional Access policies. The access policy does not allow token issuance.\"),\r\n \"Unknown\"\r\n )\r\n| project TimeGenerated, ServicePrincipalName, ServicePrincipalId, ErrorDescription, ResultType, IPAddress", 363 | "size": 0, 364 | "title": "Service Principal Error Codes based off 'SPTime'", 365 | "queryType": 0, 366 | "resourceType": "microsoft.operationalinsights/workspaces", 367 | "crossComponentResources": [ 368 | "{Workspace}" 369 | ], 370 | "gridSettings": { 371 | "formatters": [ 372 | { 373 | "columnMatch": "$gen_group", 374 | "formatter": 0, 375 | "formatOptions": { 376 | "customColumnWidthSetting": "40ch" 377 | } 378 | }, 379 | { 380 | "columnMatch": "ErrorDescription", 381 | "formatter": 5 382 | }, 383 | { 384 | "columnMatch": "ResultType", 385 | "formatter": 5 386 | }, 387 | { 388 | "columnMatch": "$gen_group", 389 | "formatter": 0, 390 | "formatOptions": { 391 | "customColumnWidthSetting": "40ch" 392 | } 393 | } 394 | ], 395 | "hierarchySettings": { 396 | "treeType": 1, 397 | "groupBy": [ 398 | "ResultType", 399 | "ErrorDescription" 400 | ] 401 | } 402 | } 403 | }, 404 | "conditionalVisibility": { 405 | "parameterName": "Tab", 406 | "comparison": "isEqualTo", 407 | "value": "sp" 408 | }, 409 | "name": "query - 7" 410 | }, 411 | { 412 | "type": 1, 413 | "content": { 414 | "json": "Enterprise Applications Time Value. Set the 'EATime' to look back on the data points below regarding Enterprise Applications." 415 | }, 416 | "conditionalVisibility": { 417 | "parameterName": "Tab", 418 | "comparison": "isEqualTo", 419 | "value": "ea" 420 | }, 421 | "name": "text - 32" 422 | }, 423 | { 424 | "type": 9, 425 | "content": { 426 | "version": "KqlParameterItem/1.0", 427 | "parameters": [ 428 | { 429 | "id": "fbdaf430-0fbb-47b1-9947-4ec01ba8a883", 430 | "version": "KqlParameterItem/1.0", 431 | "name": "EATime", 432 | "type": 1, 433 | "timeContext": { 434 | "durationMs": 86400000 435 | }, 436 | "value": "90" 437 | } 438 | ], 439 | "style": "pills", 440 | "queryType": 0, 441 | "resourceType": "microsoft.operationalinsights/workspaces" 442 | }, 443 | "conditionalVisibility": { 444 | "parameterName": "Tab", 445 | "comparison": "isEqualTo", 446 | "value": "ea" 447 | }, 448 | "name": "parameters - 17" 449 | }, 450 | { 451 | "type": 3, 452 | "content": { 453 | "version": "KqlItem/1.0", 454 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago (365d)\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project\r\n AppDisplayName,\r\n ['Last Logon Time']=TimeGenerated,\r\n ['Days Since Last Logon']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Logon'] > 30 | sort by ['Days Since Last Logon'] desc ", 455 | "size": 0, 456 | "title": "Apps with no sign-ins based off 'EATime'", 457 | "queryType": 0, 458 | "resourceType": "microsoft.operationalinsights/workspaces", 459 | "crossComponentResources": [ 460 | "{Workspace}" 461 | ], 462 | "gridSettings": { 463 | "formatters": [ 464 | { 465 | "columnMatch": "Days Since Last Logon", 466 | "formatter": 1 467 | } 468 | ] 469 | } 470 | }, 471 | "conditionalVisibility": { 472 | "parameterName": "Tab", 473 | "comparison": "isEqualTo", 474 | "value": "ea" 475 | }, 476 | "name": "query - 9" 477 | }, 478 | { 479 | "type": 3, 480 | "content": { 481 | "version": "KqlItem/1.0", 482 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago(30d)\r\n| where ResultType == 0\r\n| summarize ['Total Signins']=count(), ['Distinct User Signins']=dcount(UserPrincipalName) by AppDisplayName | sort by ['Distinct User Signins'] desc ", 483 | "size": 0, 484 | "title": "Total sign-in vs distinct sign-ins based off 'EATime'", 485 | "queryType": 0, 486 | "resourceType": "microsoft.operationalinsights/workspaces", 487 | "crossComponentResources": [ 488 | "{Workspace}" 489 | ], 490 | "gridSettings": { 491 | "formatters": [ 492 | { 493 | "columnMatch": "Total Signins", 494 | "formatter": 1 495 | }, 496 | { 497 | "columnMatch": "Distinct User Signins", 498 | "formatter": 1 499 | } 500 | ], 501 | "sortBy": [ 502 | { 503 | "itemKey": "AppDisplayName", 504 | "sortOrder": 1 505 | } 506 | ] 507 | }, 508 | "sortBy": [ 509 | { 510 | "itemKey": "AppDisplayName", 511 | "sortOrder": 1 512 | } 513 | ] 514 | }, 515 | "conditionalVisibility": { 516 | "parameterName": "Tab", 517 | "comparison": "isEqualTo", 518 | "value": "ea" 519 | }, 520 | "name": "query - 10" 521 | }, 522 | { 523 | "type": 3, 524 | "content": { 525 | "version": "KqlItem/1.0", 526 | "query": "SigninLogs\r\n//| where TimeGenerated > ago(30d)\r\n| where TimeGenerated > ago({EATime}d)\r\n| where ResultType == 0\r\n| summarize ['Distinct Member Signins']=dcountif(UserPrincipalName, UserType == \"Member\"), ['Distinct Guest Signins']=dcountif(UserPrincipalName, UserType == \"Guest\") by AppDisplayName | sort by ['Distinct Guest Signins'] ", 527 | "size": 0, 528 | "title": "Member vs Guest for each app based off 'EATime'", 529 | "queryType": 0, 530 | "resourceType": "microsoft.operationalinsights/workspaces", 531 | "crossComponentResources": [ 532 | "{Workspace}" 533 | ], 534 | "gridSettings": { 535 | "formatters": [ 536 | { 537 | "columnMatch": "Distinct Member Signins", 538 | "formatter": 1 539 | }, 540 | { 541 | "columnMatch": "Distinct Guest Signins", 542 | "formatter": 1 543 | } 544 | ] 545 | } 546 | }, 547 | "conditionalVisibility": { 548 | "parameterName": "Tab", 549 | "comparison": "isEqualTo", 550 | "value": "ea" 551 | }, 552 | "name": "query - 11" 553 | }, 554 | { 555 | "type": 1, 556 | "content": { 557 | "json": "Privileged Access Time Value. Set the 'PAtime' to look back on the data points below regarding Privilege Access." 558 | }, 559 | "conditionalVisibility": { 560 | "parameterName": "Tab", 561 | "comparison": "isEqualTo", 562 | "value": "pa" 563 | }, 564 | "name": "text - 33" 565 | }, 566 | { 567 | "type": 9, 568 | "content": { 569 | "version": "KqlParameterItem/1.0", 570 | "parameters": [ 571 | { 572 | "id": "aba2622f-95e5-459a-bc69-5c4c7cf39e73", 573 | "version": "KqlParameterItem/1.0", 574 | "name": "PATime", 575 | "type": 1, 576 | "timeContext": { 577 | "durationMs": 86400000 578 | }, 579 | "value": "90" 580 | } 581 | ], 582 | "style": "pills", 583 | "queryType": 0, 584 | "resourceType": "microsoft.operationalinsights/workspaces" 585 | }, 586 | "conditionalVisibility": { 587 | "parameterName": "Tab", 588 | "comparison": "isEqualTo", 589 | "value": "pa" 590 | }, 591 | "name": "parameters - 18" 592 | }, 593 | { 594 | "type": 3, 595 | "content": { 596 | "version": "KqlItem/1.0", 597 | "query": "//Detects users who have accessed Azure AD Management interfaces who have not accessed in the previous timeframe\r\n//let timeframe = startofday(ago(1d));\r\nlet applications = dynamic([\"Azure Active Directory PowerShell\", \"Microsoft Azure PowerShell\", \"Graph Explorer\", \"ACOM Azure Website\"]);\r\nSigninLogs\r\n| where TimeGenerated > ({PATime}d) and TimeGenerated < startofday(now())\r\n| where AppDisplayName in (applications)\r\n| project UserPrincipalName, AppDisplayName\r\n| join kind=rightanti\r\n (\r\n SigninLogs\r\n | where TimeGenerated > startofday(now())\r\n | where AppDisplayName in (applications)\r\n )\r\n on UserPrincipalName, AppDisplayName\r\n| where ResultType == 0\r\n| project TimeGenerated, UserPrincipalName, ResultType, AppDisplayName, IPAddress, Location, UserAgent", 598 | "size": 0, 599 | "title": "Detects users who have accessed Azure AD Management interfaces who have not accessed based off 'PATime'", 600 | "queryType": 0, 601 | "resourceType": "microsoft.operationalinsights/workspaces", 602 | "crossComponentResources": [ 603 | "{Workspace}" 604 | ] 605 | }, 606 | "conditionalVisibility": { 607 | "parameterName": "Tab", 608 | "comparison": "isEqualTo", 609 | "value": "pa" 610 | }, 611 | "name": "query - 13" 612 | }, 613 | { 614 | "type": 3, 615 | "content": { 616 | "version": "KqlItem/1.0", 617 | "query": "AuditLogs\r\n| where TimeGenerated > ago (365d)\r\n| project TimeGenerated, OperationName, Result, TargetResources, InitiatedBy\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| where Result == \"success\"\r\n| extend ['Last Role Activated'] = tostring(TargetResources[0].displayName)\r\n| extend Actor = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\r\n| summarize arg_max(TimeGenerated, *) by Actor\r\n| project Actor, ['Last Role Activated'], ['Last Activation Time']=TimeGenerated, ['Days Since Last Activation']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Activation'] >= ({PATime})\r\n| sort by ['Days Since Last Activation'] desc", 618 | "size": 0, 619 | "title": "Users who haven't elevated to a role based off 'PATime'", 620 | "queryType": 0, 621 | "resourceType": "microsoft.operationalinsights/workspaces", 622 | "crossComponentResources": [ 623 | "{Workspace}" 624 | ] 625 | }, 626 | "conditionalVisibility": { 627 | "parameterName": "Tab", 628 | "comparison": "isEqualTo", 629 | "value": "pa" 630 | }, 631 | "name": "query - 14" 632 | }, 633 | { 634 | "type": 1, 635 | "content": { 636 | "json": "Parameters to set. PATimeRange looks how far back in time. TZ is a manual input of the TimeZone you are in. WorkDayStart and WorkDayEnd are in 24hr format, Enter the inbetween hours." 637 | }, 638 | "conditionalVisibility": { 639 | "parameterName": "Tab", 640 | "comparison": "isEqualTo", 641 | "value": "pa" 642 | }, 643 | "name": "text - 34" 644 | }, 645 | { 646 | "type": 9, 647 | "content": { 648 | "version": "KqlParameterItem/1.0", 649 | "parameters": [ 650 | { 651 | "id": "1a4b8407-431e-49cb-9232-564a4cd61c7f", 652 | "version": "KqlParameterItem/1.0", 653 | "name": "PATimeRange", 654 | "type": 1, 655 | "value": "180" 656 | }, 657 | { 658 | "id": "3b2c6aed-6af1-48fb-ad26-61bfcc9dbab7", 659 | "version": "KqlParameterItem/1.0", 660 | "name": "TZ", 661 | "type": 1, 662 | "description": "Set TimeZone with +-", 663 | "timeContext": { 664 | "durationMs": 86400000 665 | }, 666 | "value": "-5", 667 | "label": "" 668 | }, 669 | { 670 | "id": "875d5837-9ee4-4ca9-9ef6-005646cb54e6", 671 | "version": "KqlParameterItem/1.0", 672 | "name": "WorkDayStart", 673 | "type": 1, 674 | "timeContext": { 675 | "durationMs": 86400000 676 | }, 677 | "value": "6" 678 | }, 679 | { 680 | "id": "0ef92195-c347-4a58-b0a4-132e133b30ef", 681 | "version": "KqlParameterItem/1.0", 682 | "name": "WorkDayEnd", 683 | "type": 1, 684 | "timeContext": { 685 | "durationMs": 86400000 686 | }, 687 | "value": "15" 688 | } 689 | ], 690 | "style": "pills", 691 | "queryType": 0, 692 | "resourceType": "microsoft.operationalinsights/workspaces" 693 | }, 694 | "conditionalVisibility": { 695 | "parameterName": "Tab", 696 | "comparison": "isEqualTo", 697 | "value": "pa" 698 | }, 699 | "name": "parameters - 19" 700 | }, 701 | { 702 | "type": 3, 703 | "content": { 704 | "version": "KqlItem/1.0", 705 | "query": "AuditLogs\r\n| extend LocalTime = TimeGenerated, '({TZ}h)'\r\n| where LocalTime > ago({PATimeRange}d)\r\n// Change hours of the day to suit your company, i.e this would find activations between 6pm and 6am\r\n| where hourofday(LocalTime) !between (({WorkDayStart}) .. ({WorkDayEnd}))\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| extend RoleName = tostring(TargetResources[0].displayName)\r\n| project LocalTime, OperationName, Identity, RoleName, ActivationReason=ResultReason", 706 | "size": 0, 707 | "title": "PIM elevation outside of working hours ", 708 | "queryType": 0, 709 | "resourceType": "microsoft.operationalinsights/workspaces", 710 | "crossComponentResources": [ 711 | "{Workspace}" 712 | ] 713 | }, 714 | "conditionalVisibility": { 715 | "parameterName": "Tab", 716 | "comparison": "isEqualTo", 717 | "value": "pa" 718 | }, 719 | "name": "query - 15" 720 | }, 721 | { 722 | "type": 1, 723 | "content": { 724 | "json": "MFA and Passwordless Time Value. Set the 'MFAtime' to look back on the data points below regarding MFA and Passwordless." 725 | }, 726 | "conditionalVisibility": { 727 | "parameterName": "Tab", 728 | "comparison": "isEqualTo", 729 | "value": "mfa" 730 | }, 731 | "name": "text - 35" 732 | }, 733 | { 734 | "type": 9, 735 | "content": { 736 | "version": "KqlParameterItem/1.0", 737 | "parameters": [ 738 | { 739 | "id": "22ef5fd0-b8dd-49a3-9d83-c4ca40cef72d", 740 | "version": "KqlParameterItem/1.0", 741 | "name": "MFATime", 742 | "type": 1, 743 | "timeContext": { 744 | "durationMs": 86400000 745 | }, 746 | "value": "90" 747 | } 748 | ], 749 | "style": "pills", 750 | "queryType": 0, 751 | "resourceType": "microsoft.operationalinsights/workspaces" 752 | }, 753 | "conditionalVisibility": { 754 | "parameterName": "Tab", 755 | "comparison": "isEqualTo", 756 | "value": "mfa" 757 | }, 758 | "name": "parameters - 22" 759 | }, 760 | { 761 | "type": 3, 762 | "content": { 763 | "version": "KqlItem/1.0", 764 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| summarize ['Single Factor Authentication']=countif(AuthenticationRequirement == \"singleFactorAuthentication\"), ['Multi Factor Authentication']=countif(AuthenticationRequirement == \"multiFactorAuthentication\") by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\", title=\"Single vs Multifactor Authentication last 30 days\")", 765 | "size": 0, 766 | "title": "Single vs MultiFactor Authentication bas off 'MFATime'", 767 | "queryType": 0, 768 | "resourceType": "microsoft.operationalinsights/workspaces", 769 | "crossComponentResources": [ 770 | "{Workspace}" 771 | ] 772 | }, 773 | "conditionalVisibility": { 774 | "parameterName": "Tab", 775 | "comparison": "isEqualTo", 776 | "value": "mfa" 777 | }, 778 | "name": "query - 21" 779 | }, 780 | { 781 | "type": 3, 782 | "content": { 783 | "version": "KqlItem/1.0", 784 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| where ResultType == 0\r\n| summarize\r\n TotalCount=count(),\r\n MFACount=countif(AuthenticationRequirement == \"multiFactorAuthentication\"),\r\n nonMFACount=countif(AuthenticationRequirement == \"singleFactorAuthentication\")\r\n by AppDisplayName\r\n| project AppDisplayName, TotalCount, MFACount, nonMFACount, MFAPercentage=(todouble(MFACount) * 100 / todouble(TotalCount))\r\n| sort by MFAPercentage desc", 785 | "size": 0, 786 | "title": "Percentage of signins that are MFA based off 'MFATime'", 787 | "queryType": 0, 788 | "resourceType": "microsoft.operationalinsights/workspaces" 789 | }, 790 | "conditionalVisibility": { 791 | "parameterName": "Tab", 792 | "comparison": "isEqualTo", 793 | "value": "mfa" 794 | }, 795 | "name": "query - 23" 796 | }, 797 | { 798 | "type": 3, 799 | "content": { 800 | "version": "KqlItem/1.0", 801 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod != \"Previously satisfied\"\r\n| summarize\r\n Password=countif(AuthMethod == \"Password\"),\r\n Passwordless=countif(AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\"))\r\n by startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Password vs Passwordless signins per week\")", 802 | "size": 0, 803 | "title": "Password vs Passwordless based off 'MFATime'", 804 | "queryType": 0, 805 | "resourceType": "microsoft.operationalinsights/workspaces", 806 | "crossComponentResources": [ 807 | "{Workspace}" 808 | ], 809 | "tileSettings": { 810 | "showBorder": false 811 | } 812 | }, 813 | "conditionalVisibility": { 814 | "parameterName": "Tab", 815 | "comparison": "isEqualTo", 816 | "value": "mfa" 817 | }, 818 | "name": "query - 24" 819 | }, 820 | { 821 | "type": 3, 822 | "content": { 823 | "version": "KqlItem/1.0", 824 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\")\r\n| summarize ['Passwordless Method']=count()by AuthMethod, startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Passwordless methods per week\")", 825 | "size": 0, 826 | "title": "Passwordless methods per week based off 'MFATime'", 827 | "queryType": 0, 828 | "resourceType": "microsoft.operationalinsights/workspaces", 829 | "crossComponentResources": [ 830 | "{Workspace}" 831 | ] 832 | }, 833 | "conditionalVisibility": { 834 | "parameterName": "Tab", 835 | "comparison": "isEqualTo", 836 | "value": "mfa" 837 | }, 838 | "name": "query - 25" 839 | }, 840 | { 841 | "type": 1, 842 | "content": { 843 | "json": "Legacy Authentication Time Value. Set the 'LAtime' to look back on the data points below regarding Legacy Authentication." 844 | }, 845 | "conditionalVisibility": { 846 | "parameterName": "Tab", 847 | "comparison": "isEqualTo", 848 | "value": "la" 849 | }, 850 | "name": "text - 36" 851 | }, 852 | { 853 | "type": 9, 854 | "content": { 855 | "version": "KqlParameterItem/1.0", 856 | "parameters": [ 857 | { 858 | "id": "5df704aa-b05a-4430-a8d8-441544ab9857", 859 | "version": "KqlParameterItem/1.0", 860 | "name": "LATime", 861 | "type": 1, 862 | "timeContext": { 863 | "durationMs": 86400000 864 | }, 865 | "value": "90" 866 | } 867 | ], 868 | "style": "pills", 869 | "queryType": 0, 870 | "resourceType": "microsoft.operationalinsights/workspaces" 871 | }, 872 | "conditionalVisibility": { 873 | "parameterName": "Tab", 874 | "comparison": "isEqualTo", 875 | "value": "la" 876 | }, 877 | "name": "parameters - 29" 878 | }, 879 | { 880 | "type": 3, 881 | "content": { 882 | "version": "KqlItem/1.0", 883 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType == 0\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize ['Count of legacy auth attempts'] = count()by ClientAppUsed, UserPrincipalName\r\n| sort by ClientAppUsed asc, ['Count of legacy auth attempts'] desc ", 884 | "size": 0, 885 | "title": "Legacy apps being used for signin based off 'LATime'", 886 | "queryType": 0, 887 | "resourceType": "microsoft.operationalinsights/workspaces", 888 | "crossComponentResources": [ 889 | "{Workspace}" 890 | ] 891 | }, 892 | "conditionalVisibility": { 893 | "parameterName": "Tab", 894 | "comparison": "isEqualTo", 895 | "value": "la" 896 | }, 897 | "name": "query - 27" 898 | }, 899 | { 900 | "type": 3, 901 | "content": { 902 | "version": "KqlItem/1.0", 903 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType in (\"0\", \"53003\")\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize\r\n ['Legacy Auth Users Allowed']=dcountif(UserPrincipalName, ResultType == 0),\r\n ['Legacy Auth Users Blocked']=dcountif(UserPrincipalName, ResultType == 53003)\r\n by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\",title=\"Legacy auth distinct users allowed vs blocked by Conditional Access\")", 904 | "size": 0, 905 | "title": "Legacy auth distinct users allowed vs blocked by Conditional Access based off 'LATime'", 906 | "queryType": 0, 907 | "resourceType": "microsoft.operationalinsights/workspaces", 908 | "crossComponentResources": [ 909 | "{Workspace}" 910 | ] 911 | }, 912 | "conditionalVisibility": { 913 | "parameterName": "Tab", 914 | "comparison": "isEqualTo", 915 | "value": "la" 916 | }, 917 | "name": "query - 28" 918 | }, 919 | { 920 | "type": 1, 921 | "content": { 922 | "json": "Conditional Access Time Value. Set the 'CAtime' to look back on the data points below regarding Conditional Access." 923 | }, 924 | "conditionalVisibility": { 925 | "parameterName": "Tab", 926 | "comparison": "isEqualTo", 927 | "value": "ca" 928 | }, 929 | "name": "text - 37" 930 | }, 931 | { 932 | "type": 9, 933 | "content": { 934 | "version": "KqlParameterItem/1.0", 935 | "parameters": [ 936 | { 937 | "id": "c1de2781-dea2-4352-abcd-6ac9d1026d6d", 938 | "version": "KqlParameterItem/1.0", 939 | "name": "CATime", 940 | "type": 1, 941 | "timeContext": { 942 | "durationMs": 86400000 943 | }, 944 | "value": "90" 945 | } 946 | ], 947 | "style": "pills", 948 | "queryType": 0, 949 | "resourceType": "microsoft.operationalinsights/workspaces" 950 | }, 951 | "conditionalVisibility": { 952 | "parameterName": "Tab", 953 | "comparison": "isEqualTo", 954 | "value": "ca" 955 | }, 956 | "name": "parameters - 32" 957 | }, 958 | { 959 | "type": 3, 960 | "content": { 961 | "version": "KqlItem/1.0", 962 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| summarize CAResults=make_set(CAResult) by CAPolicyName\r\n| where CAResults !has \"success\" and CAResults !has \"failure\"", 963 | "size": 0, 964 | "title": "Policies with no success events (user allowed in) & no failures (user blocked) based off 'CATime'", 965 | "queryType": 0, 966 | "resourceType": "microsoft.operationalinsights/workspaces", 967 | "crossComponentResources": [ 968 | "{Workspace}" 969 | ] 970 | }, 971 | "conditionalVisibility": { 972 | "parameterName": "Tab", 973 | "comparison": "isEqualTo", 974 | "value": "ca" 975 | }, 976 | "name": "query - 31" 977 | }, 978 | { 979 | "type": 3, 980 | "content": { 981 | "version": "KqlItem/1.0", 982 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies, ResultType, ResultDescription\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| where CAResult == \"failure\"\r\n| summarize CAFailureCount=count()by CAPolicyName, ResultType, ResultDescription\r\n| sort by CAFailureCount desc ", 983 | "size": 0, 984 | "title": "Failures and the reason based off 'CATime'", 985 | "queryType": 0, 986 | "resourceType": "microsoft.operationalinsights/workspaces", 987 | "crossComponentResources": [ 988 | "{Workspace}" 989 | ] 990 | }, 991 | "conditionalVisibility": { 992 | "parameterName": "Tab", 993 | "comparison": "isEqualTo", 994 | "value": "ca" 995 | }, 996 | "name": "query - 33" 997 | } 998 | ], 999 | "fallbackResourceIds": [ 1000 | "/subscriptions/4260a1bd-84f2-4114-8197-2bbf9a9350a1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinellaw" 1001 | ], 1002 | "fromTemplateId": "sentinel-UserWorkbook", 1003 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 1004 | } 1005 | -------------------------------------------------------------------------------- /AzureADMaintenace.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 1, 6 | "content": { 7 | "json": "# Azure Active Directory Maitenance" 8 | }, 9 | "name": "text - 34" 10 | }, 11 | { 12 | "type": 9, 13 | "content": { 14 | "version": "KqlParameterItem/1.0", 15 | "crossComponentResources": [ 16 | "value::all" 17 | ], 18 | "parameters": [ 19 | { 20 | "id": "8c87c98a-2ee4-4b06-9152-ae62330b3c31", 21 | "version": "KqlParameterItem/1.0", 22 | "name": "Workspace", 23 | "type": 5, 24 | "isRequired": true, 25 | "multiSelect": true, 26 | "quote": "'", 27 | "delimiter": ",", 28 | "query": "resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| project id", 29 | "crossComponentResources": [ 30 | "value::all" 31 | ], 32 | "typeSettings": { 33 | "additionalResourceOptions": [] 34 | }, 35 | "timeContext": { 36 | "durationMs": 86400000 37 | }, 38 | "queryType": 1, 39 | "resourceType": "microsoft.resourcegraph/resources", 40 | "value": [] 41 | } 42 | ], 43 | "style": "pills", 44 | "queryType": 1, 45 | "resourceType": "microsoft.resourcegraph/resources" 46 | }, 47 | "name": "parameters - 4" 48 | }, 49 | { 50 | "type": 11, 51 | "content": { 52 | "version": "LinkItem/1.0", 53 | "style": "tabs", 54 | "links": [ 55 | { 56 | "id": "b39ca7b9-0b5d-4f82-90a5-ef5c694b50e3", 57 | "cellValue": "Tab", 58 | "linkTarget": "parameter", 59 | "linkLabel": "Users and Guests", 60 | "subTarget": "ug", 61 | "style": "link" 62 | }, 63 | { 64 | "id": "411a469b-cbac-4a49-b229-9faeeeeed3ba", 65 | "cellValue": "Tab", 66 | "linkTarget": "parameter", 67 | "linkLabel": "Service Principals", 68 | "subTarget": "sp", 69 | "style": "link" 70 | }, 71 | { 72 | "id": "1ff02fa4-66ad-4ae4-b611-afb441b32951", 73 | "cellValue": "Tab", 74 | "linkTarget": "parameter", 75 | "linkLabel": "Enterprise Applications", 76 | "subTarget": "ea", 77 | "style": "link" 78 | }, 79 | { 80 | "id": "eaeab803-85b1-4755-a70b-9c0d35e066cc", 81 | "cellValue": "Tab", 82 | "linkTarget": "parameter", 83 | "linkLabel": "Privileged Access", 84 | "subTarget": "pa", 85 | "style": "link" 86 | }, 87 | { 88 | "id": "74ad5f79-b4a6-4cc9-a31e-771cb4acaf22", 89 | "cellValue": "Tab", 90 | "linkTarget": "parameter", 91 | "linkLabel": "MFA and Passwordless", 92 | "subTarget": "mfa", 93 | "style": "link" 94 | }, 95 | { 96 | "id": "4da2d8ee-7860-4165-a34c-1699313651ba", 97 | "cellValue": "Tab", 98 | "linkTarget": "parameter", 99 | "linkLabel": "Legacy Authentication", 100 | "subTarget": "la", 101 | "style": "link" 102 | }, 103 | { 104 | "id": "1e53250a-c522-4722-9949-5e0ffac99886", 105 | "cellValue": "Tab", 106 | "linkTarget": "parameter", 107 | "linkLabel": "Conditional Access", 108 | "subTarget": "ca", 109 | "style": "link" 110 | } 111 | ] 112 | }, 113 | "name": "links - 37" 114 | }, 115 | { 116 | "type": 1, 117 | "content": { 118 | "json": "User and Guests time values. Set the 'MaxTimeValue' to how far back to look (based off your log retention or parameters and set'MinTimeValue' for how many days to look back from current time." 119 | }, 120 | "conditionalVisibility": { 121 | "parameterName": "Tab", 122 | "comparison": "isEqualTo", 123 | "value": "ug" 124 | }, 125 | "name": "text - 30" 126 | }, 127 | { 128 | "type": 9, 129 | "content": { 130 | "version": "KqlParameterItem/1.0", 131 | "parameters": [ 132 | { 133 | "id": "62339408-f594-49c1-b272-e8db1f0a0ffb", 134 | "version": "KqlParameterItem/1.0", 135 | "name": "MaxTimeValue", 136 | "type": 1, 137 | "timeContext": { 138 | "durationMs": 0 139 | }, 140 | "timeContextFromParameter": "TimeRange", 141 | "value": "365" 142 | }, 143 | { 144 | "id": "b9b49b7d-f818-4ff5-b45a-6086e0af0d14", 145 | "version": "KqlParameterItem/1.0", 146 | "name": "MinTimeValue", 147 | "type": 1, 148 | "timeContext": { 149 | "durationMs": 0 150 | }, 151 | "timeContextFromParameter": "TimeRange", 152 | "value": "90" 153 | } 154 | ], 155 | "style": "pills", 156 | "queryType": 0, 157 | "resourceType": "microsoft.operationalinsights/workspaces" 158 | }, 159 | "conditionalVisibility": { 160 | "parameterName": "Tab", 161 | "comparison": "isEqualTo", 162 | "value": "ug" 163 | }, 164 | "name": "parameters - 19" 165 | }, 166 | { 167 | "type": 3, 168 | "content": { 169 | "version": "KqlItem/1.0", 170 | "query": "// Get Sign-in logs for inactive users\r\nSigninLogs\r\n| where UserType == \"Member\" or UserType == \"Guest\"\r\n| where TimeGenerated > ago({MaxTimeValue}d)\r\n| where ResultType == 0\r\n| where isnotempty(UserType)\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| where TimeGenerated < ago({MinTimeValue}d)\r\n| summarize by TimeGenerated, UserType, UserPrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\",now(),TimeGenerated), HomeTenantId, ResourceTenantId\r\n| sort by TimeGenerated desc\r\n", 171 | "size": 0, 172 | "showAnalytics": true, 173 | "title": "Member or Guest Last Logon based off Time Values", 174 | "exportParameterName": "Detail", 175 | "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\", \"Parent\":\"*\"}", 176 | "queryType": 0, 177 | "resourceType": "microsoft.operationalinsights/workspaces", 178 | "crossComponentResources": [ 179 | "{Workspace}" 180 | ], 181 | "gridSettings": { 182 | "formatters": [ 183 | { 184 | "columnMatch": "UserType", 185 | "formatter": 5 186 | }, 187 | { 188 | "columnMatch": "Days Since Last Logon", 189 | "formatter": 1 190 | } 191 | ], 192 | "hierarchySettings": { 193 | "treeType": 1, 194 | "groupBy": [ 195 | "UserType" 196 | ] 197 | } 198 | }, 199 | "tileSettings": { 200 | "showBorder": false, 201 | "titleContent": { 202 | "columnMatch": "CA Policy Name", 203 | "formatter": 1 204 | }, 205 | "leftContent": { 206 | "columnMatch": "failure", 207 | "formatter": 12, 208 | "formatOptions": { 209 | "palette": "auto" 210 | }, 211 | "numberFormat": { 212 | "unit": 17, 213 | "options": { 214 | "maximumSignificantDigits": 3, 215 | "maximumFractionDigits": 2 216 | } 217 | } 218 | } 219 | }, 220 | "mapSettings": { 221 | "locInfo": "LatLong", 222 | "sizeSettings": "failure", 223 | "sizeAggregation": "Sum", 224 | "legendMetric": "failure", 225 | "legendAggregation": "Sum", 226 | "itemColorSettings": { 227 | "type": "heatmap", 228 | "colorAggregation": "Sum", 229 | "nodeColorField": "failure", 230 | "heatmapPalette": "greenRed" 231 | } 232 | } 233 | }, 234 | "conditionalVisibility": { 235 | "parameterName": "Tab", 236 | "comparison": "isEqualTo", 237 | "value": "ug" 238 | }, 239 | "customWidth": "75", 240 | "name": "query - 10 - Copy - Copy", 241 | "styleSettings": { 242 | "margin": "50" 243 | } 244 | }, 245 | { 246 | "type": 3, 247 | "content": { 248 | "version": "KqlItem/1.0", 249 | "query": "AuditLogs\r\n| where TimeGenerated between (ago({MaxTimeValue}d) .. ago({MinTimeValue}d)) \r\n| where OperationName == \"Invite external user\"\r\n| extend GuestUPN = tolower(tostring(TargetResources[0].userPrincipalName))\r\n| summarize arg_max(TimeGenerated, *) by GuestUPN\r\n| project TimeGenerated, GuestUPN\r\n| join kind=leftanti (\r\n AuditLogs\r\n //| where TimeGenerated > ago (timerange)\r\n | where TimeGenerated > ago({MaxTimeValue}d)\r\n | where OperationName == \"Redeem external user invite\"\r\n | where CorrelationId <> \"00000000-0000-0000-0000-000000000000\"\r\n | extend d = tolower(tostring(TargetResources[0].displayName))\r\n | parse d with * \"upn: \" GuestUPN \",\" *\r\n | project TimeGenerated, GuestUPN)\r\n on GuestUPN\r\n| project TimeGenerated, GuestUPN, ['Days Since Invite Sent']=datetime_diff(\"day\", now(), TimeGenerated)", 250 | "size": 0, 251 | "title": "Expired Guest Invites based off Time Values", 252 | "queryType": 0, 253 | "resourceType": "microsoft.operationalinsights/workspaces", 254 | "crossComponentResources": [ 255 | "{Workspace}" 256 | ] 257 | }, 258 | "conditionalVisibility": { 259 | "parameterName": "Tab", 260 | "comparison": "isEqualTo", 261 | "value": "ug" 262 | }, 263 | "name": "query - 30" 264 | }, 265 | { 266 | "type": 3, 267 | "content": { 268 | "version": "KqlItem/1.0", 269 | "query": "SigninLogs\r\n| where TimeGenerated > ago (360d)\r\n| where UserType == \"Guest\"\r\n| where AADTenantId != HomeTenantId and HomeTenantId != ResourceTenantId\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| project TimeGenerated, UserPrincipalName\r\n| summarize ['Count of Last Signin']=count() by startofmonth(TimeGenerated)\r\n| render columnchart with (title=\"Guest inactivity per month\")", 270 | "size": 0, 271 | "title": "Guest inactivity per month within last 365d", 272 | "queryType": 0, 273 | "resourceType": "microsoft.operationalinsights/workspaces", 274 | "crossComponentResources": [ 275 | "{Workspace}" 276 | ], 277 | "tileSettings": { 278 | "showBorder": false 279 | }, 280 | "graphSettings": { 281 | "type": 0 282 | } 283 | }, 284 | "conditionalVisibility": { 285 | "parameterName": "Tab", 286 | "comparison": "isEqualTo", 287 | "value": "ug" 288 | }, 289 | "name": "query - 4" 290 | }, 291 | { 292 | "type": 1, 293 | "content": { 294 | "json": "Service Principal Time Value. Set the 'SPTime' to look back when a Service Principal last logged on and their relative error codes.\r\n" 295 | }, 296 | "conditionalVisibility": { 297 | "parameterName": "Tab", 298 | "comparison": "isEqualTo", 299 | "value": "sp" 300 | }, 301 | "name": "text - 31" 302 | }, 303 | { 304 | "type": 9, 305 | "content": { 306 | "version": "KqlParameterItem/1.0", 307 | "parameters": [ 308 | { 309 | "id": "9d469d3d-e539-4940-adf0-47698983b0fa", 310 | "version": "KqlParameterItem/1.0", 311 | "name": "SPTime", 312 | "type": 1, 313 | "timeContext": { 314 | "durationMs": 86400000 315 | }, 316 | "value": "90" 317 | } 318 | ], 319 | "style": "pills", 320 | "queryType": 0, 321 | "resourceType": "microsoft.operationalinsights/workspaces" 322 | }, 323 | "conditionalVisibility": { 324 | "parameterName": "Tab", 325 | "comparison": "isEqualTo", 326 | "value": "sp" 327 | }, 328 | "name": "parameters - 16" 329 | }, 330 | { 331 | "type": 3, 332 | "content": { 333 | "version": "KqlItem/1.0", 334 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n//| where TimeGenerated > ago(365d)\r\n| where ResultType == \"0\"\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project TimeGenerated, ServicePrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\", now(),TimeGenerated)\r\n| where ['Days Since Last Logon'] >= 45 | sort by ['Days Since Last Logon'] desc ", 335 | "size": 1, 336 | "title": "Inactive Service Principals based off 'SPTime'", 337 | "queryType": 0, 338 | "resourceType": "microsoft.operationalinsights/workspaces", 339 | "crossComponentResources": [ 340 | "{Workspace}" 341 | ], 342 | "gridSettings": { 343 | "formatters": [ 344 | { 345 | "columnMatch": "Days Since Last Logon", 346 | "formatter": 1 347 | } 348 | ] 349 | } 350 | }, 351 | "conditionalVisibility": { 352 | "parameterName": "Tab", 353 | "comparison": "isEqualTo", 354 | "value": "sp" 355 | }, 356 | "name": "query - 6" 357 | }, 358 | { 359 | "type": 3, 360 | "content": { 361 | "version": "KqlItem/1.0", 362 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n| where ResultType != \"0\"\r\n| extend ErrorDescription = case (\r\n ResultType == \"7000215\", strcat(\"Invalid client secret is provided\"),\r\n ResultType == \"7000222\", strcat(\"The provided client secret keys are expired\"),\r\n ResultType == \"700027\", strcat(\"Client assertion failed signature validation\"),\r\n ResultType == \"700024\", strcat(\"Client assertion is not within its valid time range\"),\r\n ResultType == \"70021\", strcat(\"No matching federated identity record found for presented assertion\"),\r\n ResultType == \"500011\", strcat(\"The resource principal named was not found in the tenant\"),\r\n ResultType == \"700082\", strcat(\"The refresh token has expired due to inactivity\"),\r\n ResultType == \"90025\", strcat(\"Request processing has exceeded gateway allowance\"),\r\n ResultType == \"500341\", strcat(\"The user account has been deleted from the directory\"),\r\n ResultType == \"100007\", strcat(\"AAD Regional ONLY supports auth either for MSIs OR for requests from MSAL using SN+I for 1P apps or 3P apps in Microsoft infrastructure tenants\"),\r\n ResultType == \"1100000\", strcat(\"Non-retryable error has occurred\"),\r\n ResultType == \"90033\", strcat(\"A transient error has occurred. Please try again\"),\r\n ResultType == \"53003\",strcat(\"Access has been blocked by Conditional Access policies. The access policy does not allow token issuance.\"),\r\n \"Unknown\"\r\n )\r\n| project TimeGenerated, ServicePrincipalName, ServicePrincipalId, ErrorDescription, ResultType, IPAddress", 363 | "size": 0, 364 | "title": "Service Principal Error Codes based off 'SPTime'", 365 | "queryType": 0, 366 | "resourceType": "microsoft.operationalinsights/workspaces", 367 | "crossComponentResources": [ 368 | "{Workspace}" 369 | ], 370 | "gridSettings": { 371 | "formatters": [ 372 | { 373 | "columnMatch": "$gen_group", 374 | "formatter": 0, 375 | "formatOptions": { 376 | "customColumnWidthSetting": "40ch" 377 | } 378 | }, 379 | { 380 | "columnMatch": "ErrorDescription", 381 | "formatter": 5 382 | }, 383 | { 384 | "columnMatch": "ResultType", 385 | "formatter": 5 386 | }, 387 | { 388 | "columnMatch": "$gen_group", 389 | "formatter": 0, 390 | "formatOptions": { 391 | "customColumnWidthSetting": "40ch" 392 | } 393 | } 394 | ], 395 | "hierarchySettings": { 396 | "treeType": 1, 397 | "groupBy": [ 398 | "ResultType", 399 | "ErrorDescription" 400 | ] 401 | } 402 | } 403 | }, 404 | "conditionalVisibility": { 405 | "parameterName": "Tab", 406 | "comparison": "isEqualTo", 407 | "value": "sp" 408 | }, 409 | "name": "query - 7" 410 | }, 411 | { 412 | "type": 1, 413 | "content": { 414 | "json": "Enterprise Applications Time Value. Set the 'EATime' to look back on the data points below regarding Enterprise Applications." 415 | }, 416 | "conditionalVisibility": { 417 | "parameterName": "Tab", 418 | "comparison": "isEqualTo", 419 | "value": "ea" 420 | }, 421 | "name": "text - 32" 422 | }, 423 | { 424 | "type": 9, 425 | "content": { 426 | "version": "KqlParameterItem/1.0", 427 | "parameters": [ 428 | { 429 | "id": "fbdaf430-0fbb-47b1-9947-4ec01ba8a883", 430 | "version": "KqlParameterItem/1.0", 431 | "name": "EATime", 432 | "type": 1, 433 | "timeContext": { 434 | "durationMs": 86400000 435 | }, 436 | "value": "90" 437 | } 438 | ], 439 | "style": "pills", 440 | "queryType": 0, 441 | "resourceType": "microsoft.operationalinsights/workspaces" 442 | }, 443 | "conditionalVisibility": { 444 | "parameterName": "Tab", 445 | "comparison": "isEqualTo", 446 | "value": "ea" 447 | }, 448 | "name": "parameters - 17" 449 | }, 450 | { 451 | "type": 3, 452 | "content": { 453 | "version": "KqlItem/1.0", 454 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago (365d)\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project\r\n AppDisplayName,\r\n ['Last Logon Time']=TimeGenerated,\r\n ['Days Since Last Logon']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Logon'] > 30 | sort by ['Days Since Last Logon'] desc ", 455 | "size": 0, 456 | "title": "Apps with no sign-ins based off 'EATime'", 457 | "queryType": 0, 458 | "resourceType": "microsoft.operationalinsights/workspaces", 459 | "crossComponentResources": [ 460 | "{Workspace}" 461 | ], 462 | "gridSettings": { 463 | "formatters": [ 464 | { 465 | "columnMatch": "Days Since Last Logon", 466 | "formatter": 1 467 | } 468 | ] 469 | } 470 | }, 471 | "conditionalVisibility": { 472 | "parameterName": "Tab", 473 | "comparison": "isEqualTo", 474 | "value": "ea" 475 | }, 476 | "name": "query - 9" 477 | }, 478 | { 479 | "type": 3, 480 | "content": { 481 | "version": "KqlItem/1.0", 482 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago(30d)\r\n| where ResultType == 0\r\n| summarize ['Total Signins']=count(), ['Distinct User Signins']=dcount(UserPrincipalName) by AppDisplayName | sort by ['Distinct User Signins'] desc ", 483 | "size": 0, 484 | "title": "Total sign-in vs distinct sign-ins based off 'EATime'", 485 | "queryType": 0, 486 | "resourceType": "microsoft.operationalinsights/workspaces", 487 | "crossComponentResources": [ 488 | "{Workspace}" 489 | ], 490 | "gridSettings": { 491 | "formatters": [ 492 | { 493 | "columnMatch": "Total Signins", 494 | "formatter": 1 495 | }, 496 | { 497 | "columnMatch": "Distinct User Signins", 498 | "formatter": 1 499 | } 500 | ], 501 | "sortBy": [ 502 | { 503 | "itemKey": "AppDisplayName", 504 | "sortOrder": 1 505 | } 506 | ] 507 | }, 508 | "sortBy": [ 509 | { 510 | "itemKey": "AppDisplayName", 511 | "sortOrder": 1 512 | } 513 | ] 514 | }, 515 | "conditionalVisibility": { 516 | "parameterName": "Tab", 517 | "comparison": "isEqualTo", 518 | "value": "ea" 519 | }, 520 | "name": "query - 10" 521 | }, 522 | { 523 | "type": 3, 524 | "content": { 525 | "version": "KqlItem/1.0", 526 | "query": "SigninLogs\r\n//| where TimeGenerated > ago(30d)\r\n| where TimeGenerated > ago({EATime}d)\r\n| where ResultType == 0\r\n| summarize ['Distinct Member Signins']=dcountif(UserPrincipalName, UserType == \"Member\"), ['Distinct Guest Signins']=dcountif(UserPrincipalName, UserType == \"Guest\") by AppDisplayName | sort by ['Distinct Guest Signins'] ", 527 | "size": 0, 528 | "title": "Member vs Guest for each app based off 'EATime'", 529 | "queryType": 0, 530 | "resourceType": "microsoft.operationalinsights/workspaces", 531 | "crossComponentResources": [ 532 | "{Workspace}" 533 | ], 534 | "gridSettings": { 535 | "formatters": [ 536 | { 537 | "columnMatch": "Distinct Member Signins", 538 | "formatter": 1 539 | }, 540 | { 541 | "columnMatch": "Distinct Guest Signins", 542 | "formatter": 1 543 | } 544 | ] 545 | } 546 | }, 547 | "conditionalVisibility": { 548 | "parameterName": "Tab", 549 | "comparison": "isEqualTo", 550 | "value": "ea" 551 | }, 552 | "name": "query - 11" 553 | }, 554 | { 555 | "type": 1, 556 | "content": { 557 | "json": "Privileged Access Time Value. Set the 'PAtime' to look back on the data points below regarding Privilege Access." 558 | }, 559 | "conditionalVisibility": { 560 | "parameterName": "Tab", 561 | "comparison": "isEqualTo", 562 | "value": "pa" 563 | }, 564 | "name": "text - 33" 565 | }, 566 | { 567 | "type": 9, 568 | "content": { 569 | "version": "KqlParameterItem/1.0", 570 | "parameters": [ 571 | { 572 | "id": "aba2622f-95e5-459a-bc69-5c4c7cf39e73", 573 | "version": "KqlParameterItem/1.0", 574 | "name": "PATime", 575 | "type": 1, 576 | "timeContext": { 577 | "durationMs": 86400000 578 | }, 579 | "value": "90" 580 | } 581 | ], 582 | "style": "pills", 583 | "queryType": 0, 584 | "resourceType": "microsoft.operationalinsights/workspaces" 585 | }, 586 | "conditionalVisibility": { 587 | "parameterName": "Tab", 588 | "comparison": "isEqualTo", 589 | "value": "pa" 590 | }, 591 | "name": "parameters - 18" 592 | }, 593 | { 594 | "type": 3, 595 | "content": { 596 | "version": "KqlItem/1.0", 597 | "query": "//Detects users who have accessed Azure AD Management interfaces who have not accessed in the previous timeframe\r\n//let timeframe = startofday(ago(1d));\r\nlet applications = dynamic([\"Azure Active Directory PowerShell\", \"Microsoft Azure PowerShell\", \"Graph Explorer\", \"ACOM Azure Website\"]);\r\nSigninLogs\r\n| where TimeGenerated > ({PATime}d) and TimeGenerated < startofday(now())\r\n| where AppDisplayName in (applications)\r\n| project UserPrincipalName, AppDisplayName\r\n| join kind=rightanti\r\n (\r\n SigninLogs\r\n | where TimeGenerated > startofday(now())\r\n | where AppDisplayName in (applications)\r\n )\r\n on UserPrincipalName, AppDisplayName\r\n| where ResultType == 0\r\n| project TimeGenerated, UserPrincipalName, ResultType, AppDisplayName, IPAddress, Location, UserAgent", 598 | "size": 0, 599 | "title": "Detects users who have accessed Azure AD Management interfaces who have not accessed based off 'PATime'", 600 | "queryType": 0, 601 | "resourceType": "microsoft.operationalinsights/workspaces", 602 | "crossComponentResources": [ 603 | "{Workspace}" 604 | ] 605 | }, 606 | "conditionalVisibility": { 607 | "parameterName": "Tab", 608 | "comparison": "isEqualTo", 609 | "value": "pa" 610 | }, 611 | "name": "query - 13" 612 | }, 613 | { 614 | "type": 3, 615 | "content": { 616 | "version": "KqlItem/1.0", 617 | "query": "AuditLogs\r\n| where TimeGenerated > ago (365d)\r\n| project TimeGenerated, OperationName, Result, TargetResources, InitiatedBy\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| where Result == \"success\"\r\n| extend ['Last Role Activated'] = tostring(TargetResources[0].displayName)\r\n| extend Actor = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\r\n| summarize arg_max(TimeGenerated, *) by Actor\r\n| project Actor, ['Last Role Activated'], ['Last Activation Time']=TimeGenerated, ['Days Since Last Activation']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Activation'] >= ({PATime})\r\n| sort by ['Days Since Last Activation'] desc", 618 | "size": 0, 619 | "title": "Users who haven't elevated to a role based off 'PATime'", 620 | "queryType": 0, 621 | "resourceType": "microsoft.operationalinsights/workspaces", 622 | "crossComponentResources": [ 623 | "{Workspace}" 624 | ] 625 | }, 626 | "conditionalVisibility": { 627 | "parameterName": "Tab", 628 | "comparison": "isEqualTo", 629 | "value": "pa" 630 | }, 631 | "name": "query - 14" 632 | }, 633 | { 634 | "type": 1, 635 | "content": { 636 | "json": "Parameters to set. PATimeRange looks how far back in time. TZ is a manual input of the TimeZone you are in. WorkDayStart and WorkDayEnd are in 24hr format, Enter the inbetween hours." 637 | }, 638 | "conditionalVisibility": { 639 | "parameterName": "Tab", 640 | "comparison": "isEqualTo", 641 | "value": "pa" 642 | }, 643 | "name": "text - 34" 644 | }, 645 | { 646 | "type": 9, 647 | "content": { 648 | "version": "KqlParameterItem/1.0", 649 | "parameters": [ 650 | { 651 | "id": "1a4b8407-431e-49cb-9232-564a4cd61c7f", 652 | "version": "KqlParameterItem/1.0", 653 | "name": "PATimeRange", 654 | "type": 1, 655 | "value": "180" 656 | }, 657 | { 658 | "id": "3b2c6aed-6af1-48fb-ad26-61bfcc9dbab7", 659 | "version": "KqlParameterItem/1.0", 660 | "name": "TZ", 661 | "type": 1, 662 | "description": "Set TimeZone with +-", 663 | "timeContext": { 664 | "durationMs": 86400000 665 | }, 666 | "value": "-5", 667 | "label": "" 668 | }, 669 | { 670 | "id": "875d5837-9ee4-4ca9-9ef6-005646cb54e6", 671 | "version": "KqlParameterItem/1.0", 672 | "name": "WorkDayStart", 673 | "type": 1, 674 | "timeContext": { 675 | "durationMs": 86400000 676 | }, 677 | "value": "6" 678 | }, 679 | { 680 | "id": "0ef92195-c347-4a58-b0a4-132e133b30ef", 681 | "version": "KqlParameterItem/1.0", 682 | "name": "WorkDayEnd", 683 | "type": 1, 684 | "timeContext": { 685 | "durationMs": 86400000 686 | }, 687 | "value": "15" 688 | } 689 | ], 690 | "style": "pills", 691 | "queryType": 0, 692 | "resourceType": "microsoft.operationalinsights/workspaces" 693 | }, 694 | "conditionalVisibility": { 695 | "parameterName": "Tab", 696 | "comparison": "isEqualTo", 697 | "value": "pa" 698 | }, 699 | "name": "parameters - 19" 700 | }, 701 | { 702 | "type": 3, 703 | "content": { 704 | "version": "KqlItem/1.0", 705 | "query": "AuditLogs\r\n| extend LocalTime = TimeGenerated, '({TZ}h)'\r\n| where LocalTime > ago({PATimeRange}d)\r\n// Change hours of the day to suit your company, i.e this would find activations between 6pm and 6am\r\n| where hourofday(LocalTime) !between (({WorkDayStart}) .. ({WorkDayEnd}))\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| extend RoleName = tostring(TargetResources[0].displayName)\r\n| project LocalTime, OperationName, Identity, RoleName, ActivationReason=ResultReason", 706 | "size": 0, 707 | "title": "PIM elevation outside of working hours ", 708 | "queryType": 0, 709 | "resourceType": "microsoft.operationalinsights/workspaces", 710 | "crossComponentResources": [ 711 | "{Workspace}" 712 | ] 713 | }, 714 | "conditionalVisibility": { 715 | "parameterName": "Tab", 716 | "comparison": "isEqualTo", 717 | "value": "pa" 718 | }, 719 | "name": "query - 15" 720 | }, 721 | { 722 | "type": 1, 723 | "content": { 724 | "json": "MFA and Passwordless Time Value. Set the 'MFAtime' to look back on the data points below regarding MFA and Passwordless." 725 | }, 726 | "conditionalVisibility": { 727 | "parameterName": "Tab", 728 | "comparison": "isEqualTo", 729 | "value": "mfa" 730 | }, 731 | "name": "text - 35" 732 | }, 733 | { 734 | "type": 9, 735 | "content": { 736 | "version": "KqlParameterItem/1.0", 737 | "parameters": [ 738 | { 739 | "id": "22ef5fd0-b8dd-49a3-9d83-c4ca40cef72d", 740 | "version": "KqlParameterItem/1.0", 741 | "name": "MFATime", 742 | "type": 1, 743 | "timeContext": { 744 | "durationMs": 86400000 745 | }, 746 | "value": "90" 747 | } 748 | ], 749 | "style": "pills", 750 | "queryType": 0, 751 | "resourceType": "microsoft.operationalinsights/workspaces" 752 | }, 753 | "conditionalVisibility": { 754 | "parameterName": "Tab", 755 | "comparison": "isEqualTo", 756 | "value": "mfa" 757 | }, 758 | "name": "parameters - 22" 759 | }, 760 | { 761 | "type": 3, 762 | "content": { 763 | "version": "KqlItem/1.0", 764 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| summarize ['Single Factor Authentication']=countif(AuthenticationRequirement == \"singleFactorAuthentication\"), ['Multi Factor Authentication']=countif(AuthenticationRequirement == \"multiFactorAuthentication\") by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\", title=\"Single vs Multifactor Authentication last 30 days\")", 765 | "size": 0, 766 | "title": "Single vs MultiFactor Authentication bas off 'MFATime'", 767 | "queryType": 0, 768 | "resourceType": "microsoft.operationalinsights/workspaces", 769 | "crossComponentResources": [ 770 | "{Workspace}" 771 | ] 772 | }, 773 | "conditionalVisibility": { 774 | "parameterName": "Tab", 775 | "comparison": "isEqualTo", 776 | "value": "mfa" 777 | }, 778 | "name": "query - 21" 779 | }, 780 | { 781 | "type": 3, 782 | "content": { 783 | "version": "KqlItem/1.0", 784 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| where ResultType == 0\r\n| summarize\r\n TotalCount=count(),\r\n MFACount=countif(AuthenticationRequirement == \"multiFactorAuthentication\"),\r\n nonMFACount=countif(AuthenticationRequirement == \"singleFactorAuthentication\")\r\n by AppDisplayName\r\n| project AppDisplayName, TotalCount, MFACount, nonMFACount, MFAPercentage=(todouble(MFACount) * 100 / todouble(TotalCount))\r\n| sort by MFAPercentage desc", 785 | "size": 0, 786 | "title": "Percentage of signins that are MFA based off 'MFATime'", 787 | "queryType": 0, 788 | "resourceType": "microsoft.operationalinsights/workspaces" 789 | }, 790 | "conditionalVisibility": { 791 | "parameterName": "Tab", 792 | "comparison": "isEqualTo", 793 | "value": "mfa" 794 | }, 795 | "name": "query - 23" 796 | }, 797 | { 798 | "type": 3, 799 | "content": { 800 | "version": "KqlItem/1.0", 801 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod != \"Previously satisfied\"\r\n| summarize\r\n Password=countif(AuthMethod == \"Password\"),\r\n Passwordless=countif(AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\"))\r\n by startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Password vs Passwordless signins per week\")", 802 | "size": 0, 803 | "title": "Password vs Passwordless based off 'MFATime'", 804 | "queryType": 0, 805 | "resourceType": "microsoft.operationalinsights/workspaces", 806 | "crossComponentResources": [ 807 | "{Workspace}" 808 | ], 809 | "tileSettings": { 810 | "showBorder": false 811 | } 812 | }, 813 | "conditionalVisibility": { 814 | "parameterName": "Tab", 815 | "comparison": "isEqualTo", 816 | "value": "mfa" 817 | }, 818 | "name": "query - 24" 819 | }, 820 | { 821 | "type": 3, 822 | "content": { 823 | "version": "KqlItem/1.0", 824 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\")\r\n| summarize ['Passwordless Method']=count()by AuthMethod, startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Passwordless methods per week\")", 825 | "size": 0, 826 | "title": "Passwordless methods per week based off 'MFATime'", 827 | "queryType": 0, 828 | "resourceType": "microsoft.operationalinsights/workspaces", 829 | "crossComponentResources": [ 830 | "{Workspace}" 831 | ] 832 | }, 833 | "conditionalVisibility": { 834 | "parameterName": "Tab", 835 | "comparison": "isEqualTo", 836 | "value": "mfa" 837 | }, 838 | "name": "query - 25" 839 | }, 840 | { 841 | "type": 1, 842 | "content": { 843 | "json": "Legacy Authentication Time Value. Set the 'LAtime' to look back on the data points below regarding Legacy Authentication." 844 | }, 845 | "conditionalVisibility": { 846 | "parameterName": "Tab", 847 | "comparison": "isEqualTo", 848 | "value": "la" 849 | }, 850 | "name": "text - 36" 851 | }, 852 | { 853 | "type": 9, 854 | "content": { 855 | "version": "KqlParameterItem/1.0", 856 | "parameters": [ 857 | { 858 | "id": "5df704aa-b05a-4430-a8d8-441544ab9857", 859 | "version": "KqlParameterItem/1.0", 860 | "name": "LATime", 861 | "type": 1, 862 | "timeContext": { 863 | "durationMs": 86400000 864 | }, 865 | "value": "90" 866 | } 867 | ], 868 | "style": "pills", 869 | "queryType": 0, 870 | "resourceType": "microsoft.operationalinsights/workspaces" 871 | }, 872 | "conditionalVisibility": { 873 | "parameterName": "Tab", 874 | "comparison": "isEqualTo", 875 | "value": "la" 876 | }, 877 | "name": "parameters - 29" 878 | }, 879 | { 880 | "type": 3, 881 | "content": { 882 | "version": "KqlItem/1.0", 883 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType == 0\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize ['Count of legacy auth attempts'] = count()by ClientAppUsed, UserPrincipalName\r\n| sort by ClientAppUsed asc, ['Count of legacy auth attempts'] desc ", 884 | "size": 0, 885 | "title": "Legacy apps being used for signin based off 'LATime'", 886 | "queryType": 0, 887 | "resourceType": "microsoft.operationalinsights/workspaces", 888 | "crossComponentResources": [ 889 | "{Workspace}" 890 | ] 891 | }, 892 | "conditionalVisibility": { 893 | "parameterName": "Tab", 894 | "comparison": "isEqualTo", 895 | "value": "la" 896 | }, 897 | "name": "query - 27" 898 | }, 899 | { 900 | "type": 3, 901 | "content": { 902 | "version": "KqlItem/1.0", 903 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType in (\"0\", \"53003\")\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize\r\n ['Legacy Auth Users Allowed']=dcountif(UserPrincipalName, ResultType == 0),\r\n ['Legacy Auth Users Blocked']=dcountif(UserPrincipalName, ResultType == 53003)\r\n by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\",title=\"Legacy auth distinct users allowed vs blocked by Conditional Access\")", 904 | "size": 0, 905 | "title": "Legacy auth distinct users allowed vs blocked by Conditional Access based off 'LATime'", 906 | "queryType": 0, 907 | "resourceType": "microsoft.operationalinsights/workspaces", 908 | "crossComponentResources": [ 909 | "{Workspace}" 910 | ] 911 | }, 912 | "conditionalVisibility": { 913 | "parameterName": "Tab", 914 | "comparison": "isEqualTo", 915 | "value": "la" 916 | }, 917 | "name": "query - 28" 918 | }, 919 | { 920 | "type": 1, 921 | "content": { 922 | "json": "Conditional Access Time Value. Set the 'CAtime' to look back on the data points below regarding Conditional Access." 923 | }, 924 | "conditionalVisibility": { 925 | "parameterName": "Tab", 926 | "comparison": "isEqualTo", 927 | "value": "ca" 928 | }, 929 | "name": "text - 37" 930 | }, 931 | { 932 | "type": 9, 933 | "content": { 934 | "version": "KqlParameterItem/1.0", 935 | "parameters": [ 936 | { 937 | "id": "c1de2781-dea2-4352-abcd-6ac9d1026d6d", 938 | "version": "KqlParameterItem/1.0", 939 | "name": "CATime", 940 | "type": 1, 941 | "timeContext": { 942 | "durationMs": 86400000 943 | }, 944 | "value": "90" 945 | } 946 | ], 947 | "style": "pills", 948 | "queryType": 0, 949 | "resourceType": "microsoft.operationalinsights/workspaces" 950 | }, 951 | "conditionalVisibility": { 952 | "parameterName": "Tab", 953 | "comparison": "isEqualTo", 954 | "value": "ca" 955 | }, 956 | "name": "parameters - 32" 957 | }, 958 | { 959 | "type": 3, 960 | "content": { 961 | "version": "KqlItem/1.0", 962 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| summarize CAResults=make_set(CAResult) by CAPolicyName\r\n| where CAResults !has \"success\" and CAResults !has \"failure\"", 963 | "size": 0, 964 | "title": "Policies with no success events (user allowed in) & no failures (user blocked) based off 'CATime'", 965 | "queryType": 0, 966 | "resourceType": "microsoft.operationalinsights/workspaces", 967 | "crossComponentResources": [ 968 | "{Workspace}" 969 | ] 970 | }, 971 | "conditionalVisibility": { 972 | "parameterName": "Tab", 973 | "comparison": "isEqualTo", 974 | "value": "ca" 975 | }, 976 | "name": "query - 31" 977 | }, 978 | { 979 | "type": 3, 980 | "content": { 981 | "version": "KqlItem/1.0", 982 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies, ResultType, ResultDescription\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| where CAResult == \"failure\"\r\n| summarize CAFailureCount=count()by CAPolicyName, ResultType, ResultDescription\r\n| sort by CAFailureCount desc ", 983 | "size": 0, 984 | "title": "Failures and the reason based off 'CATime'", 985 | "queryType": 0, 986 | "resourceType": "microsoft.operationalinsights/workspaces", 987 | "crossComponentResources": [ 988 | "{Workspace}" 989 | ] 990 | }, 991 | "conditionalVisibility": { 992 | "parameterName": "Tab", 993 | "comparison": "isEqualTo", 994 | "value": "ca" 995 | }, 996 | "name": "query - 33" 997 | } 998 | ], 999 | "fallbackResourceIds": [ 1000 | "/subscriptions/d75e3576-9a3a-4f5b-b112-b5e0088cd2e1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinel-cyberlorians" 1001 | ], 1002 | "fromTemplateId": "sentinel-UserWorkbook", 1003 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 1004 | } 1005 | -------------------------------------------------------------------------------- /B2BFramework.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 1, 6 | "content": { 7 | "json": "## YELLER PAGES\n---\n\nWelcome to your new workbook. This area will display text formatted as markdown.\n\n\nWe've included a basic analytics query to get you started. Use the `Edit` button below each section to configure it or add more sections." 8 | }, 9 | "name": "text - 2" 10 | }, 11 | { 12 | "type": 9, 13 | "content": { 14 | "version": "KqlParameterItem/1.0", 15 | "crossComponentResources": [ 16 | "value::all" 17 | ], 18 | "parameters": [ 19 | { 20 | "id": "18302244-0cfb-46d8-92e2-554fa9974c38", 21 | "version": "KqlParameterItem/1.0", 22 | "name": "Workspace", 23 | "type": 5, 24 | "description": "Select at least one workspace that contains continuous export data based on the selected subscriptions", 25 | "isRequired": true, 26 | "multiSelect": true, 27 | "quote": "'", 28 | "delimiter": ",", 29 | "query": "", 30 | "crossComponentResources": [ 31 | "value::all" 32 | ], 33 | "typeSettings": { 34 | "additionalResourceOptions": [], 35 | "showDefault": false 36 | }, 37 | "timeContext": { 38 | "durationMs": 0 39 | }, 40 | "timeContextFromParameter": "CAPTime", 41 | "queryType": 1, 42 | "resourceType": "microsoft.resourcegraph/resources", 43 | "value": [ 44 | "/subscriptions/d75e3576-9a3a-4f5b-b112-b5e0088cd2e1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinel-cyberlorians" 45 | ] 46 | }, 47 | { 48 | "id": "9943b4a1-371e-4e50-8cbe-749a6dd87d76", 49 | "version": "KqlParameterItem/1.0", 50 | "name": "TimeRange", 51 | "type": 4, 52 | "isRequired": true, 53 | "typeSettings": { 54 | "selectableValues": [ 55 | { 56 | "durationMs": 300000 57 | }, 58 | { 59 | "durationMs": 900000 60 | }, 61 | { 62 | "durationMs": 1800000 63 | }, 64 | { 65 | "durationMs": 3600000 66 | }, 67 | { 68 | "durationMs": 14400000 69 | }, 70 | { 71 | "durationMs": 43200000 72 | }, 73 | { 74 | "durationMs": 86400000 75 | }, 76 | { 77 | "durationMs": 172800000 78 | }, 79 | { 80 | "durationMs": 259200000 81 | }, 82 | { 83 | "durationMs": 604800000 84 | }, 85 | { 86 | "durationMs": 1209600000 87 | }, 88 | { 89 | "durationMs": 2419200000 90 | }, 91 | { 92 | "durationMs": 2592000000 93 | }, 94 | { 95 | "durationMs": 5184000000 96 | }, 97 | { 98 | "durationMs": 7776000000 99 | } 100 | ], 101 | "allowCustom": true 102 | }, 103 | "value": { 104 | "durationMs": 7776000000 105 | } 106 | } 107 | ], 108 | "style": "pills", 109 | "queryType": 1, 110 | "resourceType": "microsoft.resourcegraph/resources" 111 | }, 112 | "name": "parameters - 22 - Copy" 113 | }, 114 | { 115 | "type": 12, 116 | "content": { 117 | "version": "NotebookGroup/1.0", 118 | "groupType": "editable", 119 | "items": [ 120 | { 121 | "type": 1, 122 | "content": { 123 | "json": "A Federated domain in Entra ID is a domain that is configured to use federation technologies, such as Active Directory Federation Services (AD FS), to authenticate users. A Managed domain, on the other hand, is a domain that is managed by Entra ID and uses Entra ID for authentication.", 124 | "style": "info" 125 | }, 126 | "customWidth": "40", 127 | "name": "Domains-Text" 128 | }, 129 | { 130 | "type": 1, 131 | "content": { 132 | "json": "List SKUs purchased for Tenant.", 133 | "style": "info" 134 | }, 135 | "customWidth": "22", 136 | "name": "TenantSKU-Text" 137 | }, 138 | { 139 | "type": 1, 140 | "content": { 141 | "json": "When you deploy features like Microsoft Entra multifactor authentication in your organization, review the available authentication methods. Choose the methods that meet or exceed your requirements in terms of security, usability, and availability. Where possible, use authentication methods with the highest level of security.\r\nFurther information, see [here](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-methods).\r\n\r\nPlease migrate to new Authenticatin Methods listed [here](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-methods-manage).", 142 | "style": "info" 143 | }, 144 | "customWidth": "38", 145 | "name": "AuthNMethods-Text" 146 | } 147 | ] 148 | }, 149 | "name": "Group01" 150 | }, 151 | { 152 | "type": 3, 153 | "content": { 154 | "version": "KqlItem/1.0", 155 | "query": "B2BFramework_CL\n| where _odata_context_s has \"domains\"\n| mv-apply todynamic(value_s) on\n(\nwhere isnotempty(value_s.id)\n| extend domainName=tostring(value_s.id)\n| extend authenticationType=tostring(value_s.authenticationType)\n| extend isDefault=tostring(value_s.isDefault)\n| extend isVerified_ = tostring(value_s.isVerified)\n)\n| distinct ['Registered Domains'] = domainName, ['AuthenticationType'] = authenticationType, ['Default Domain'] = isDefault, ['Verified Domain'] = isVerified_", 156 | "size": 1, 157 | "showAnalytics": true, 158 | "title": "Register Domains & Federation Type", 159 | "timeContextFromParameter": "TimeRange", 160 | "queryType": 0, 161 | "resourceType": "microsoft.operationalinsights/workspaces", 162 | "gridSettings": { 163 | "formatters": [ 164 | { 165 | "columnMatch": "Default Domain", 166 | "formatter": 18, 167 | "formatOptions": { 168 | "thresholdsOptions": "icons", 169 | "thresholdsGrid": [ 170 | { 171 | "operator": "==", 172 | "thresholdValue": "true", 173 | "representation": "Check", 174 | "text": "DEFAULT" 175 | }, 176 | { 177 | "operator": "Default", 178 | "thresholdValue": null, 179 | "representation": "Close", 180 | "text": "" 181 | } 182 | ] 183 | } 184 | } 185 | ], 186 | "rowLimit": 1000 187 | }, 188 | "sortBy": [] 189 | }, 190 | "customWidth": "40", 191 | "showPin": true, 192 | "name": "Register Domains & Federation Type" 193 | }, 194 | { 195 | "type": 3, 196 | "content": { 197 | "version": "KqlItem/1.0", 198 | "query": "B2BFramework_CL\r\n| where _odata_context_s has \"subscribedSkus\"\r\n| mv-apply todynamic(value_s) on ( extend value_s)\r\n//| extend tenant = tostring(value_s.tenantId)\r\n| extend SKU = tostring(value_s.skuPartNumber)\r\n| extend Units = tostring(parse_json(tostring(value_s.prepaidUnits)).enabled)\r\n| distinct SKU, Units", 199 | "size": 0, 200 | "showAnalytics": true, 201 | "title": "Tenant SKUs", 202 | "timeContextFromParameter": "TimeRange", 203 | "queryType": 0, 204 | "resourceType": "microsoft.operationalinsights/workspaces", 205 | "crossComponentResources": [ 206 | "{Workspace}" 207 | ] 208 | }, 209 | "customWidth": "22", 210 | "showPin": true, 211 | "name": "Tenant SKUs" 212 | }, 213 | { 214 | "type": 3, 215 | "content": { 216 | "version": "KqlItem/1.0", 217 | "query": "B2BFramework_CL\r\n| where _odata_context_s contains \"authenticationMethods\"\r\n| mv-apply todynamic(authenticationMethodConfigurations_s) on (extend id_s)\r\n| extend id_ = tostring(authenticationMethodConfigurations_s.id)\r\n| extend state_ = tostring(authenticationMethodConfigurations_s.state)\r\n| extend mig = policyMigrationState_s\r\n| extend IncludedTarget = tostring(parse_json(tostring(authenticationMethodConfigurations_s.includeTargets))[0].targetType)\r\n| extend Target = tostring(parse_json(tostring(authenticationMethodConfigurations_s.includeTargets))[0].id)\r\n| distinct\r\n ['Authentication Methods'] = id_,\r\n ['Authentication State'] = state_,\r\n Target\r\n| sort by ['Authentication State'] desc\r\n\r\n", 218 | "size": 0, 219 | "showAnalytics": true, 220 | "title": "Supported Authentication Methods", 221 | "timeContextFromParameter": "TimeRange", 222 | "queryType": 0, 223 | "resourceType": "microsoft.operationalinsights/workspaces", 224 | "gridSettings": { 225 | "formatters": [ 226 | { 227 | "columnMatch": "Target", 228 | "formatter": 18, 229 | "formatOptions": { 230 | "thresholdsOptions": "icons", 231 | "thresholdsGrid": [ 232 | { 233 | "operator": "==", 234 | "thresholdValue": "all_users", 235 | "text": "{0}{1}" 236 | }, 237 | { 238 | "operator": "Default", 239 | "thresholdValue": null, 240 | "representation": "resource", 241 | "text": "Scoped Group" 242 | } 243 | ], 244 | "compositeBarSettings": { 245 | "labelText": "", 246 | "columnSettings": [] 247 | } 248 | } 249 | } 250 | ] 251 | }, 252 | "sortBy": [], 253 | "tileSettings": { 254 | "titleContent": { 255 | "columnMatch": "Authentication Methods", 256 | "formatter": 1, 257 | "numberFormat": { 258 | "unit": 0, 259 | "options": { 260 | "style": "percent" 261 | } 262 | } 263 | }, 264 | "showBorder": false, 265 | "size": "auto" 266 | } 267 | }, 268 | "customWidth": "38", 269 | "showPin": true, 270 | "name": "Supported Authentication Methods" 271 | }, 272 | { 273 | "type": 1, 274 | "content": { 275 | "json": "Select TenantID to view the coorelation and Sign-In logs with that Tenant. ", 276 | "style": "info" 277 | }, 278 | "name": "text - 8" 279 | }, 280 | { 281 | "type": 3, 282 | "content": { 283 | "version": "KqlItem/1.0", 284 | "query": "B2BFramework_CL\r\n| where _odata_context_s has \"partners\"\r\n| mv-apply todynamic(value_s) on ( extend value_s)\r\n| extend tenant = tostring(value_s.tenantId)\r\n| extend inboundAllowed_ = tostring(parse_json(tostring(value_s.automaticUserConsentSettings)).inboundAllowed)\r\n| extend outboundAllowed_ = tostring(parse_json(tostring(value_s.automaticUserConsentSettings)).outboundAllowed)\r\n| extend b2bCollaborationInbound_ = tostring(value_s.b2bCollaborationInbound)\r\n| extend b2bCollaborationOutbound_ = tostring(value_s.b2bCollaborationOutbound)\r\n| extend b2bDirectConnectInbound_ = tostring(value_s.b2bDirectConnectInbound)\r\n| extend b2bDirectConnectOutbound_ = tostring(value_s.b2bDirectConnectOutbound)\r\n| extend inboundTrust_ = tostring(value_s.inboundTrust)\r\n| extend isServiceProvider_ = tostring(value_s.isServiceProvider)\r\n| distinct ['Tenant'] = tenant, ['Inbound User Consent'] = inboundAllowed_, ['Outbound User Consent'] = outboundAllowed_, ['B2B-Collab-In'] =b2bCollaborationInbound_, ['B2B-Collab-Out'] = b2bCollaborationOutbound_, ['B2B-Direct-In'] = b2bDirectConnectInbound_, ['B2B-Direct-Out'] = b2bDirectConnectOutbound_, ['Inbound Trust'] = inboundTrust_", 285 | "size": 0, 286 | "title": "B2B Collaboration Settings", 287 | "timeContextFromParameter": "TimeRange", 288 | "exportFieldName": "Tenant", 289 | "exportParameterName": "tenant", 290 | "queryType": 0, 291 | "resourceType": "microsoft.operationalinsights/workspaces", 292 | "crossComponentResources": [ 293 | "{Workspace}" 294 | ] 295 | }, 296 | "name": "B2B Collaboration Settings" 297 | }, 298 | { 299 | "type": 3, 300 | "content": { 301 | "version": "KqlItem/1.0", 302 | "query": "SigninLogs\r\n| where HomeTenantId == \"{tenant}\"\r\n| extend detail_ = tostring(parse_json(AuthenticationContextClassReferences)[0].detail)\r\n| extend additionalDetails_ = tostring(Status.additionalDetails)\r\n| project TimeGenerated, HomeTenantId, UserPrincipalName, UserType, CrossTenantAccessType, AppDisplayName, additionalDetails_\r\n", 303 | "size": 0, 304 | "title": "Coorelated B2B Collaboration Settings", 305 | "timeContextFromParameter": "TimeRange", 306 | "queryType": 0, 307 | "resourceType": "microsoft.operationalinsights/workspaces", 308 | "gridSettings": { 309 | "formatters": [ 310 | { 311 | "columnMatch": "HomeTenantId", 312 | "formatter": 5 313 | } 314 | ], 315 | "hierarchySettings": { 316 | "treeType": 1, 317 | "groupBy": [ 318 | "HomeTenantId" 319 | ] 320 | } 321 | } 322 | }, 323 | "conditionalVisibility": { 324 | "parameterName": "SelectedTenant", 325 | "comparison": "isEqualTo" 326 | }, 327 | "name": "Coorelated B2B Collaboration Settings" 328 | } 329 | ], 330 | "fallbackResourceIds": [ 331 | "/subscriptions/d75e3576-9a3a-4f5b-b112-b5e0088cd2e1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinel-cyberlorians" 332 | ], 333 | "fromTemplateId": "https://sentinelus.hosting.portal.azure.net/sentinelus/Content/1.0.02435.3113-230901-161733/Scenarios/Ecosystem/Content/Workbooks/CustomWorkbook.json", 334 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 335 | } 336 | -------------------------------------------------------------------------------- /CISAZT.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "GraphEndpoint": "domains", 4 | "GraphUri": "https://graph.microsoft.com/v1.0/domains" 5 | }, 6 | { 7 | "GraphEndpoint": "partners", 8 | "GraphUri": "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners" 9 | }, 10 | { 11 | "GraphEndpoint": "authenitcationMethodsPolicy", 12 | "GraphUri": "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy" 13 | }, 14 | { 15 | "GraphEndpoint": "authenticationStrengthPolicies", 16 | "GraphUri": "https://graph.microsoft.com/v1.0/policies/authenticationStrengthPolicies" 17 | }, 18 | { 19 | "GraphEndpoint": "deviceConfigurations", 20 | "GraphUri": "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations" 21 | }, 22 | { 23 | "GraphEndpoint": "devices", 24 | "GraphUri": "https://graph.microsoft.com/v1.0/devices?$select=displayName,deviceId,operatingSystemVersion,operatingSystem,profileType,trustType,isManaged,accountEnabled,approximateLastSignInDateTime,registrationDateTime" 25 | }, 26 | { 27 | "GraphEndpoint": "accessPackages", 28 | "GraphUri": "https://graph.microsoft.com/v1.0/identityGovernance/entitlementManagement/accessPackages?$expand=catalog" 29 | }, 30 | { 31 | "GraphEndpoint": "authenticationContextClassReferences", 32 | "GraphUri": "https://graph.microsoft.com/v1.0/identity/conditionalAccess/authenticationContextClassReferences" 33 | }, 34 | { 35 | "GraphEndpoint": "policies", 36 | "GraphUri": "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" 37 | }, 38 | { 39 | "GraphEndpoint": "subscribedSkus", 40 | "GraphUri": "https://graph.microsoft.com/v1.0/subscribedSkus" 41 | } 42 | 43 | 44 | ] 45 | -------------------------------------------------------------------------------- /EntraIDHygiene.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 1, 6 | "content": { 7 | "json": "# Entra ID Hygiene\r\n\r\nPROTOTYPE", 8 | "style": "info" 9 | }, 10 | "name": "text - 34" 11 | }, 12 | { 13 | "type": 9, 14 | "content": { 15 | "version": "KqlParameterItem/1.0", 16 | "crossComponentResources": [ 17 | "value::all" 18 | ], 19 | "parameters": [ 20 | { 21 | "id": "8c87c98a-2ee4-4b06-9152-ae62330b3c31", 22 | "version": "KqlParameterItem/1.0", 23 | "name": "Workspace", 24 | "type": 5, 25 | "isRequired": true, 26 | "multiSelect": true, 27 | "quote": "'", 28 | "delimiter": ",", 29 | "query": "resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| project id", 30 | "crossComponentResources": [ 31 | "value::all" 32 | ], 33 | "typeSettings": { 34 | "additionalResourceOptions": [] 35 | }, 36 | "timeContext": { 37 | "durationMs": 86400000 38 | }, 39 | "queryType": 1, 40 | "resourceType": "microsoft.resourcegraph/resources", 41 | "value": [ 42 | "/subscriptions/d75e3576-9a3a-4f5b-b112-b5e0088cd2e1/resourceGroups/Sentinel/providers/Microsoft.OperationalInsights/workspaces/Sentinel-Cyberlorians" 43 | ] 44 | } 45 | ], 46 | "style": "pills", 47 | "queryType": 1, 48 | "resourceType": "microsoft.resourcegraph/resources" 49 | }, 50 | "name": "parameters - 4" 51 | }, 52 | { 53 | "type": 11, 54 | "content": { 55 | "version": "LinkItem/1.0", 56 | "style": "toolbar", 57 | "links": [ 58 | { 59 | "id": "b39ca7b9-0b5d-4f82-90a5-ef5c694b50e3", 60 | "cellValue": "Tab", 61 | "linkTarget": "parameter", 62 | "linkLabel": "Users and Guests", 63 | "subTarget": "ug", 64 | "style": "link", 65 | "icon": "PersonWithFriend" 66 | }, 67 | { 68 | "id": "411a469b-cbac-4a49-b229-9faeeeeed3ba", 69 | "cellValue": "Tab", 70 | "linkTarget": "parameter", 71 | "linkLabel": "Service Principals", 72 | "subTarget": "sp", 73 | "style": "link", 74 | "icon": "Support" 75 | }, 76 | { 77 | "id": "1ff02fa4-66ad-4ae4-b611-afb441b32951", 78 | "cellValue": "Tab", 79 | "linkTarget": "parameter", 80 | "linkLabel": "Enterprise Applications", 81 | "subTarget": "ea", 82 | "style": "link", 83 | "icon": "Customize" 84 | }, 85 | { 86 | "id": "eaeab803-85b1-4755-a70b-9c0d35e066cc", 87 | "cellValue": "Tab", 88 | "linkTarget": "parameter", 89 | "linkLabel": "Privileged Access", 90 | "subTarget": "pa", 91 | "style": "link" 92 | }, 93 | { 94 | "id": "74ad5f79-b4a6-4cc9-a31e-771cb4acaf22", 95 | "cellValue": "Tab", 96 | "linkTarget": "parameter", 97 | "linkLabel": "MFA and Passwordless", 98 | "subTarget": "mfa", 99 | "style": "link" 100 | }, 101 | { 102 | "id": "4da2d8ee-7860-4165-a34c-1699313651ba", 103 | "cellValue": "Tab", 104 | "linkTarget": "parameter", 105 | "linkLabel": "Legacy Authentication", 106 | "subTarget": "la", 107 | "style": "link" 108 | }, 109 | { 110 | "id": "1e53250a-c522-4722-9949-5e0ffac99886", 111 | "cellValue": "Tab", 112 | "linkTarget": "parameter", 113 | "linkLabel": "Conditional Access", 114 | "subTarget": "ca", 115 | "style": "link" 116 | } 117 | ] 118 | }, 119 | "name": "links - 37" 120 | }, 121 | { 122 | "type": 1, 123 | "content": { 124 | "json": "User and Guests time values. Set the 'MaxTimeValue' to how far back to look (based off your log retention or parameters and set'MinTimeValue' for how many days to look back from current time." 125 | }, 126 | "conditionalVisibility": { 127 | "parameterName": "Tab", 128 | "comparison": "isEqualTo", 129 | "value": "ug" 130 | }, 131 | "name": "text - 30" 132 | }, 133 | { 134 | "type": 9, 135 | "content": { 136 | "version": "KqlParameterItem/1.0", 137 | "parameters": [ 138 | { 139 | "id": "62339408-f594-49c1-b272-e8db1f0a0ffb", 140 | "version": "KqlParameterItem/1.0", 141 | "name": "MaxTimeValue", 142 | "type": 1, 143 | "timeContext": { 144 | "durationMs": 0 145 | }, 146 | "timeContextFromParameter": "TimeRange", 147 | "value": "365" 148 | }, 149 | { 150 | "id": "b9b49b7d-f818-4ff5-b45a-6086e0af0d14", 151 | "version": "KqlParameterItem/1.0", 152 | "name": "MinTimeValue", 153 | "type": 1, 154 | "timeContext": { 155 | "durationMs": 0 156 | }, 157 | "timeContextFromParameter": "TimeRange", 158 | "value": "1" 159 | } 160 | ], 161 | "style": "pills", 162 | "queryType": 0, 163 | "resourceType": "microsoft.operationalinsights/workspaces" 164 | }, 165 | "conditionalVisibility": { 166 | "parameterName": "Tab", 167 | "comparison": "isEqualTo", 168 | "value": "ug" 169 | }, 170 | "name": "parameters - 19" 171 | }, 172 | { 173 | "type": 3, 174 | "content": { 175 | "version": "KqlItem/1.0", 176 | "query": "// Get Sign-in logs for inactive users\r\nSigninLogs\r\n| where UserType == \"Member\" or UserType == \"Guest\"\r\n| where TimeGenerated > ago({MaxTimeValue}d)\r\n| where ResultType == 0\r\n| where isnotempty(UserType)\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| where TimeGenerated < ago({MinTimeValue}d)\r\n| summarize by TimeGenerated, UserType, UserPrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\",now(),TimeGenerated), HomeTenantId, ResourceTenantId\r\n| sort by TimeGenerated desc\r\n", 177 | "size": 0, 178 | "showAnalytics": true, 179 | "title": "Member or Guest Last Logon based off Time Values", 180 | "exportParameterName": "Detail", 181 | "exportDefaultValue": "{ \"Name\":\"\", \"Type\":\"*\", \"Parent\":\"*\"}", 182 | "queryType": 0, 183 | "resourceType": "microsoft.operationalinsights/workspaces", 184 | "crossComponentResources": [ 185 | "{Workspace}" 186 | ], 187 | "gridSettings": { 188 | "formatters": [ 189 | { 190 | "columnMatch": "UserType", 191 | "formatter": 5 192 | }, 193 | { 194 | "columnMatch": "Days Since Last Logon", 195 | "formatter": 1 196 | } 197 | ], 198 | "hierarchySettings": { 199 | "treeType": 1, 200 | "groupBy": [ 201 | "UserType" 202 | ] 203 | } 204 | }, 205 | "tileSettings": { 206 | "showBorder": false, 207 | "titleContent": { 208 | "columnMatch": "CA Policy Name", 209 | "formatter": 1 210 | }, 211 | "leftContent": { 212 | "columnMatch": "failure", 213 | "formatter": 12, 214 | "formatOptions": { 215 | "palette": "auto" 216 | }, 217 | "numberFormat": { 218 | "unit": 17, 219 | "options": { 220 | "maximumSignificantDigits": 3, 221 | "maximumFractionDigits": 2 222 | } 223 | } 224 | } 225 | }, 226 | "mapSettings": { 227 | "locInfo": "LatLong", 228 | "sizeSettings": "failure", 229 | "sizeAggregation": "Sum", 230 | "legendMetric": "failure", 231 | "legendAggregation": "Sum", 232 | "itemColorSettings": { 233 | "type": "heatmap", 234 | "colorAggregation": "Sum", 235 | "nodeColorField": "failure", 236 | "heatmapPalette": "greenRed" 237 | } 238 | } 239 | }, 240 | "conditionalVisibility": { 241 | "parameterName": "Tab", 242 | "comparison": "isEqualTo", 243 | "value": "ug" 244 | }, 245 | "customWidth": "75", 246 | "name": "query - 10 - Copy - Copy", 247 | "styleSettings": { 248 | "margin": "50" 249 | } 250 | }, 251 | { 252 | "type": 3, 253 | "content": { 254 | "version": "KqlItem/1.0", 255 | "query": "AuditLogs\r\n| where TimeGenerated between (ago({MaxTimeValue}d) .. ago({MinTimeValue}d)) \r\n| where OperationName == \"Invite external user\"\r\n| extend GuestUPN = tolower(tostring(TargetResources[0].userPrincipalName))\r\n| summarize arg_max(TimeGenerated, *) by GuestUPN\r\n| project TimeGenerated, GuestUPN\r\n| join kind=leftanti (\r\n AuditLogs\r\n //| where TimeGenerated > ago (timerange)\r\n | where TimeGenerated > ago({MaxTimeValue}d)\r\n | where OperationName == \"Redeem external user invite\"\r\n | where CorrelationId <> \"00000000-0000-0000-0000-000000000000\"\r\n | extend d = tolower(tostring(TargetResources[0].displayName))\r\n | parse d with * \"upn: \" GuestUPN \",\" *\r\n | project TimeGenerated, GuestUPN)\r\n on GuestUPN\r\n| project TimeGenerated, GuestUPN, ['Days Since Invite Sent']=datetime_diff(\"day\", now(), TimeGenerated)", 256 | "size": 0, 257 | "title": "Expired Guest Invites based off Time Values", 258 | "queryType": 0, 259 | "resourceType": "microsoft.operationalinsights/workspaces", 260 | "crossComponentResources": [ 261 | "{Workspace}" 262 | ] 263 | }, 264 | "conditionalVisibility": { 265 | "parameterName": "Tab", 266 | "comparison": "isEqualTo", 267 | "value": "ug" 268 | }, 269 | "name": "query - 30" 270 | }, 271 | { 272 | "type": 3, 273 | "content": { 274 | "version": "KqlItem/1.0", 275 | "query": "SigninLogs\r\n| where TimeGenerated > ago (360d)\r\n| where UserType == \"Guest\"\r\n| where AADTenantId != HomeTenantId and HomeTenantId != ResourceTenantId\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by UserPrincipalName\r\n| project TimeGenerated, UserPrincipalName\r\n| summarize ['Count of Last Signin']=count() by startofmonth(TimeGenerated)\r\n| render columnchart with (title=\"Guest inactivity per month\")", 276 | "size": 0, 277 | "title": "Guest inactivity per month within last 365d", 278 | "queryType": 0, 279 | "resourceType": "microsoft.operationalinsights/workspaces", 280 | "crossComponentResources": [ 281 | "{Workspace}" 282 | ], 283 | "tileSettings": { 284 | "showBorder": false 285 | }, 286 | "graphSettings": { 287 | "type": 0 288 | } 289 | }, 290 | "conditionalVisibility": { 291 | "parameterName": "Tab", 292 | "comparison": "isEqualTo", 293 | "value": "ug" 294 | }, 295 | "name": "query - 4" 296 | }, 297 | { 298 | "type": 1, 299 | "content": { 300 | "json": "Service Principal Time Value. Set the 'SPTime' to look back when a Service Principal last logged on and their relative error codes.\r\n" 301 | }, 302 | "conditionalVisibility": { 303 | "parameterName": "Tab", 304 | "comparison": "isEqualTo", 305 | "value": "sp" 306 | }, 307 | "name": "text - 31" 308 | }, 309 | { 310 | "type": 9, 311 | "content": { 312 | "version": "KqlParameterItem/1.0", 313 | "parameters": [ 314 | { 315 | "id": "9d469d3d-e539-4940-adf0-47698983b0fa", 316 | "version": "KqlParameterItem/1.0", 317 | "name": "SPTime", 318 | "type": 1, 319 | "timeContext": { 320 | "durationMs": 86400000 321 | }, 322 | "value": "90" 323 | } 324 | ], 325 | "style": "pills", 326 | "queryType": 0, 327 | "resourceType": "microsoft.operationalinsights/workspaces" 328 | }, 329 | "conditionalVisibility": { 330 | "parameterName": "Tab", 331 | "comparison": "isEqualTo", 332 | "value": "sp" 333 | }, 334 | "name": "parameters - 16" 335 | }, 336 | { 337 | "type": 3, 338 | "content": { 339 | "version": "KqlItem/1.0", 340 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n//| where TimeGenerated > ago(365d)\r\n| where ResultType == \"0\"\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project TimeGenerated, ServicePrincipalName, ['Days Since Last Logon']=datetime_diff(\"day\", now(),TimeGenerated)\r\n| where ['Days Since Last Logon'] >= 45 | sort by ['Days Since Last Logon'] desc ", 341 | "size": 1, 342 | "title": "Inactive Service Principals based off 'SPTime'", 343 | "queryType": 0, 344 | "resourceType": "microsoft.operationalinsights/workspaces", 345 | "crossComponentResources": [ 346 | "{Workspace}" 347 | ], 348 | "gridSettings": { 349 | "formatters": [ 350 | { 351 | "columnMatch": "Days Since Last Logon", 352 | "formatter": 1 353 | } 354 | ] 355 | } 356 | }, 357 | "conditionalVisibility": { 358 | "parameterName": "Tab", 359 | "comparison": "isEqualTo", 360 | "value": "sp" 361 | }, 362 | "name": "query - 6" 363 | }, 364 | { 365 | "type": 3, 366 | "content": { 367 | "version": "KqlItem/1.0", 368 | "query": "AADServicePrincipalSignInLogs\r\n| where TimeGenerated > ago({SPTime}d)\r\n| where ResultType != \"0\"\r\n| extend ErrorDescription = case (\r\n ResultType == \"7000215\", strcat(\"Invalid client secret is provided\"),\r\n ResultType == \"7000222\", strcat(\"The provided client secret keys are expired\"),\r\n ResultType == \"700027\", strcat(\"Client assertion failed signature validation\"),\r\n ResultType == \"700024\", strcat(\"Client assertion is not within its valid time range\"),\r\n ResultType == \"70021\", strcat(\"No matching federated identity record found for presented assertion\"),\r\n ResultType == \"500011\", strcat(\"The resource principal named was not found in the tenant\"),\r\n ResultType == \"700082\", strcat(\"The refresh token has expired due to inactivity\"),\r\n ResultType == \"90025\", strcat(\"Request processing has exceeded gateway allowance\"),\r\n ResultType == \"500341\", strcat(\"The user account has been deleted from the directory\"),\r\n ResultType == \"100007\", strcat(\"AAD Regional ONLY supports auth either for MSIs OR for requests from MSAL using SN+I for 1P apps or 3P apps in Microsoft infrastructure tenants\"),\r\n ResultType == \"1100000\", strcat(\"Non-retryable error has occurred\"),\r\n ResultType == \"90033\", strcat(\"A transient error has occurred. Please try again\"),\r\n ResultType == \"53003\",strcat(\"Access has been blocked by Conditional Access policies. The access policy does not allow token issuance.\"),\r\n \"Unknown\"\r\n )\r\n| project TimeGenerated, ServicePrincipalName, ServicePrincipalId, ErrorDescription, ResultType, IPAddress", 369 | "size": 0, 370 | "title": "Service Principal Error Codes based off 'SPTime'", 371 | "queryType": 0, 372 | "resourceType": "microsoft.operationalinsights/workspaces", 373 | "crossComponentResources": [ 374 | "{Workspace}" 375 | ], 376 | "gridSettings": { 377 | "formatters": [ 378 | { 379 | "columnMatch": "$gen_group", 380 | "formatter": 0, 381 | "formatOptions": { 382 | "customColumnWidthSetting": "40ch" 383 | } 384 | }, 385 | { 386 | "columnMatch": "ErrorDescription", 387 | "formatter": 5 388 | }, 389 | { 390 | "columnMatch": "ResultType", 391 | "formatter": 5 392 | }, 393 | { 394 | "columnMatch": "$gen_group", 395 | "formatter": 0, 396 | "formatOptions": { 397 | "customColumnWidthSetting": "40ch" 398 | } 399 | } 400 | ], 401 | "hierarchySettings": { 402 | "treeType": 1, 403 | "groupBy": [ 404 | "ResultType", 405 | "ErrorDescription" 406 | ] 407 | } 408 | } 409 | }, 410 | "conditionalVisibility": { 411 | "parameterName": "Tab", 412 | "comparison": "isEqualTo", 413 | "value": "sp" 414 | }, 415 | "name": "query - 7" 416 | }, 417 | { 418 | "type": 3, 419 | "content": { 420 | "version": "KqlItem/1.0", 421 | "query": "AuditLogs\r\n| where OperationName == \"Add application\" or OperationName == \"Add app role assignment to service principal\"\r\n| extend Actor = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\r\n| extend ['Actor IP Address'] = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)\r\n| extend ['Service Principal Name'] = tostring(TargetResources[0].displayName)\r\n| extend ['Service Principal ObjectId'] = tostring(TargetResources[0].id)\r\n| extend ['Perm Added'] = case(\r\n parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue) contains 'Read' or parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue) contains 'Write',\r\n parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue),\r\n \"\"\r\n )\r\n| extend ['Is MTA?'] = case(\r\n parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[1]).displayName == 'AvailableToOtherTenants',\r\n tostring(parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[1]).displayName),\r\n ''\r\n )\r\n | extend ['Granted Perms To SP'] = case(\r\n parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[6].newValue) != '\"AppId, AvailableToOtherTenants, DisplayName, RequiredResourceAccess, PublisherDomain, ServicePrincipalLockConfiguration\"',\r\n parse_json(parse_json(tostring(TargetResources[0].modifiedProperties))[6].newValue),\r\n \"\"\r\n )\r\n | project TimeGenerated, OperationName, Actor, ['Actor IP Address'], ['Service Principal Name'], ['Is MTA?'],['Service Principal ObjectId'], ['Perm Added'], ['Granted Perms To SP']\r\n| sort by TimeGenerated desc", 422 | "size": 0, 423 | "queryType": 0, 424 | "resourceType": "microsoft.operationalinsights/workspaces", 425 | "crossComponentResources": [ 426 | "{Workspace}" 427 | ] 428 | }, 429 | "conditionalVisibility": { 430 | "parameterName": "Tab", 431 | "comparison": "isEqualTo", 432 | "value": "sp" 433 | }, 434 | "name": "query - 38" 435 | }, 436 | { 437 | "type": 1, 438 | "content": { 439 | "json": "Enterprise Applications Time Value. Set the 'EATime' to look back on the data points below regarding Enterprise Applications." 440 | }, 441 | "conditionalVisibility": { 442 | "parameterName": "Tab", 443 | "comparison": "isEqualTo", 444 | "value": "ea" 445 | }, 446 | "name": "text - 32" 447 | }, 448 | { 449 | "type": 9, 450 | "content": { 451 | "version": "KqlParameterItem/1.0", 452 | "parameters": [ 453 | { 454 | "id": "fbdaf430-0fbb-47b1-9947-4ec01ba8a883", 455 | "version": "KqlParameterItem/1.0", 456 | "name": "EATime", 457 | "type": 1, 458 | "timeContext": { 459 | "durationMs": 86400000 460 | }, 461 | "value": "90" 462 | } 463 | ], 464 | "style": "pills", 465 | "queryType": 0, 466 | "resourceType": "microsoft.operationalinsights/workspaces" 467 | }, 468 | "conditionalVisibility": { 469 | "parameterName": "Tab", 470 | "comparison": "isEqualTo", 471 | "value": "ea" 472 | }, 473 | "name": "parameters - 17" 474 | }, 475 | { 476 | "type": 3, 477 | "content": { 478 | "version": "KqlItem/1.0", 479 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago (365d)\r\n| where ResultType == 0\r\n| summarize arg_max(TimeGenerated, *) by AppId\r\n| project\r\n AppDisplayName,\r\n ['Last Logon Time']=TimeGenerated,\r\n ['Days Since Last Logon']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Logon'] > 30 | sort by ['Days Since Last Logon'] desc ", 480 | "size": 0, 481 | "title": "Apps with no sign-ins based off 'EATime'", 482 | "queryType": 0, 483 | "resourceType": "microsoft.operationalinsights/workspaces", 484 | "crossComponentResources": [ 485 | "{Workspace}" 486 | ], 487 | "gridSettings": { 488 | "formatters": [ 489 | { 490 | "columnMatch": "Days Since Last Logon", 491 | "formatter": 1 492 | } 493 | ] 494 | } 495 | }, 496 | "conditionalVisibility": { 497 | "parameterName": "Tab", 498 | "comparison": "isEqualTo", 499 | "value": "ea" 500 | }, 501 | "name": "query - 9" 502 | }, 503 | { 504 | "type": 3, 505 | "content": { 506 | "version": "KqlItem/1.0", 507 | "query": "SigninLogs\r\n| where TimeGenerated > ago({EATime}d)\r\n//| where TimeGenerated > ago(30d)\r\n| where ResultType == 0\r\n| summarize ['Total Signins']=count(), ['Distinct User Signins']=dcount(UserPrincipalName) by AppDisplayName | sort by ['Distinct User Signins'] desc ", 508 | "size": 0, 509 | "title": "Total sign-in vs distinct sign-ins based off 'EATime'", 510 | "queryType": 0, 511 | "resourceType": "microsoft.operationalinsights/workspaces", 512 | "crossComponentResources": [ 513 | "{Workspace}" 514 | ], 515 | "gridSettings": { 516 | "formatters": [ 517 | { 518 | "columnMatch": "Total Signins", 519 | "formatter": 1 520 | }, 521 | { 522 | "columnMatch": "Distinct User Signins", 523 | "formatter": 1 524 | } 525 | ], 526 | "sortBy": [ 527 | { 528 | "itemKey": "AppDisplayName", 529 | "sortOrder": 1 530 | } 531 | ] 532 | }, 533 | "sortBy": [ 534 | { 535 | "itemKey": "AppDisplayName", 536 | "sortOrder": 1 537 | } 538 | ] 539 | }, 540 | "conditionalVisibility": { 541 | "parameterName": "Tab", 542 | "comparison": "isEqualTo", 543 | "value": "ea" 544 | }, 545 | "name": "query - 10" 546 | }, 547 | { 548 | "type": 3, 549 | "content": { 550 | "version": "KqlItem/1.0", 551 | "query": "SigninLogs\r\n//| where TimeGenerated > ago(30d)\r\n| where TimeGenerated > ago({EATime}d)\r\n| where ResultType == 0\r\n| summarize ['Distinct Member Signins']=dcountif(UserPrincipalName, UserType == \"Member\"), ['Distinct Guest Signins']=dcountif(UserPrincipalName, UserType == \"Guest\") by AppDisplayName | sort by ['Distinct Guest Signins'] ", 552 | "size": 0, 553 | "title": "Member vs Guest for each app based off 'EATime'", 554 | "queryType": 0, 555 | "resourceType": "microsoft.operationalinsights/workspaces", 556 | "crossComponentResources": [ 557 | "{Workspace}" 558 | ], 559 | "gridSettings": { 560 | "formatters": [ 561 | { 562 | "columnMatch": "Distinct Member Signins", 563 | "formatter": 1 564 | }, 565 | { 566 | "columnMatch": "Distinct Guest Signins", 567 | "formatter": 1 568 | } 569 | ], 570 | "sortBy": [ 571 | { 572 | "itemKey": "AppDisplayName", 573 | "sortOrder": 1 574 | } 575 | ] 576 | }, 577 | "sortBy": [ 578 | { 579 | "itemKey": "AppDisplayName", 580 | "sortOrder": 1 581 | } 582 | ] 583 | }, 584 | "conditionalVisibility": { 585 | "parameterName": "Tab", 586 | "comparison": "isEqualTo", 587 | "value": "ea" 588 | }, 589 | "name": "query - 11" 590 | }, 591 | { 592 | "type": 1, 593 | "content": { 594 | "json": "Privileged Access Time Value. Set the 'PAtime' to look back on the data points below regarding Privilege Access." 595 | }, 596 | "conditionalVisibility": { 597 | "parameterName": "Tab", 598 | "comparison": "isEqualTo", 599 | "value": "pa" 600 | }, 601 | "name": "text - 33" 602 | }, 603 | { 604 | "type": 9, 605 | "content": { 606 | "version": "KqlParameterItem/1.0", 607 | "parameters": [ 608 | { 609 | "id": "aba2622f-95e5-459a-bc69-5c4c7cf39e73", 610 | "version": "KqlParameterItem/1.0", 611 | "name": "PATime", 612 | "type": 1, 613 | "timeContext": { 614 | "durationMs": 86400000 615 | }, 616 | "value": "90" 617 | } 618 | ], 619 | "style": "pills", 620 | "queryType": 0, 621 | "resourceType": "microsoft.operationalinsights/workspaces" 622 | }, 623 | "conditionalVisibility": { 624 | "parameterName": "Tab", 625 | "comparison": "isEqualTo", 626 | "value": "pa" 627 | }, 628 | "name": "parameters - 18" 629 | }, 630 | { 631 | "type": 3, 632 | "content": { 633 | "version": "KqlItem/1.0", 634 | "query": "//Detects users who have accessed Azure AD Management interfaces who have not accessed in the previous timeframe\r\n//let timeframe = startofday(ago(1d));\r\nlet applications = dynamic([\"Azure Active Directory PowerShell\", \"Microsoft Azure PowerShell\", \"Graph Explorer\", \"ACOM Azure Website\"]);\r\nSigninLogs\r\n| where TimeGenerated > ({PATime}d) and TimeGenerated < startofday(now())\r\n| where AppDisplayName in (applications)\r\n| project UserPrincipalName, AppDisplayName\r\n| join kind=rightanti\r\n (\r\n SigninLogs\r\n | where TimeGenerated > startofday(now())\r\n | where AppDisplayName in (applications)\r\n )\r\n on UserPrincipalName, AppDisplayName\r\n| where ResultType == 0\r\n| project TimeGenerated, UserPrincipalName, ResultType, AppDisplayName, IPAddress, Location, UserAgent", 635 | "size": 0, 636 | "title": "Detects users who have accessed Azure AD Management interfaces who have not accessed based off 'PATime'", 637 | "queryType": 0, 638 | "resourceType": "microsoft.operationalinsights/workspaces", 639 | "crossComponentResources": [ 640 | "{Workspace}" 641 | ] 642 | }, 643 | "conditionalVisibility": { 644 | "parameterName": "Tab", 645 | "comparison": "isEqualTo", 646 | "value": "pa" 647 | }, 648 | "name": "query - 13" 649 | }, 650 | { 651 | "type": 3, 652 | "content": { 653 | "version": "KqlItem/1.0", 654 | "query": "AuditLogs\r\n| where TimeGenerated > ago (365d)\r\n| project TimeGenerated, OperationName, Result, TargetResources, InitiatedBy\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| where Result == \"success\"\r\n| extend ['Last Role Activated'] = tostring(TargetResources[0].displayName)\r\n| extend Actor = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\r\n| summarize arg_max(TimeGenerated, *) by Actor\r\n| project Actor, ['Last Role Activated'], ['Last Activation Time']=TimeGenerated, ['Days Since Last Activation']=datetime_diff(\"day\", now(), TimeGenerated)\r\n| where ['Days Since Last Activation'] >= ({PATime})\r\n| sort by ['Days Since Last Activation'] desc", 655 | "size": 0, 656 | "title": "Users who haven't elevated to a role based off 'PATime'", 657 | "queryType": 0, 658 | "resourceType": "microsoft.operationalinsights/workspaces", 659 | "crossComponentResources": [ 660 | "{Workspace}" 661 | ] 662 | }, 663 | "conditionalVisibility": { 664 | "parameterName": "Tab", 665 | "comparison": "isEqualTo", 666 | "value": "pa" 667 | }, 668 | "name": "query - 14" 669 | }, 670 | { 671 | "type": 1, 672 | "content": { 673 | "json": "Parameters to set. PATimeRange looks how far back in time. TZ is a manual input of the TimeZone you are in. WorkDayStart and WorkDayEnd are in 24hr format, Enter the inbetween hours." 674 | }, 675 | "conditionalVisibility": { 676 | "parameterName": "Tab", 677 | "comparison": "isEqualTo", 678 | "value": "pa" 679 | }, 680 | "name": "text - 34" 681 | }, 682 | { 683 | "type": 9, 684 | "content": { 685 | "version": "KqlParameterItem/1.0", 686 | "parameters": [ 687 | { 688 | "id": "1a4b8407-431e-49cb-9232-564a4cd61c7f", 689 | "version": "KqlParameterItem/1.0", 690 | "name": "PATimeRange", 691 | "type": 1, 692 | "value": "30" 693 | }, 694 | { 695 | "id": "3b2c6aed-6af1-48fb-ad26-61bfcc9dbab7", 696 | "version": "KqlParameterItem/1.0", 697 | "name": "TZ", 698 | "type": 1, 699 | "description": "Set TimeZone with +-", 700 | "timeContext": { 701 | "durationMs": 86400000 702 | }, 703 | "value": "-4", 704 | "label": "" 705 | }, 706 | { 707 | "id": "875d5837-9ee4-4ca9-9ef6-005646cb54e6", 708 | "version": "KqlParameterItem/1.0", 709 | "name": "WorkDayStart", 710 | "type": 1, 711 | "timeContext": { 712 | "durationMs": 86400000 713 | }, 714 | "value": "6" 715 | }, 716 | { 717 | "id": "0ef92195-c347-4a58-b0a4-132e133b30ef", 718 | "version": "KqlParameterItem/1.0", 719 | "name": "WorkDayEnd", 720 | "type": 1, 721 | "timeContext": { 722 | "durationMs": 86400000 723 | }, 724 | "value": "20" 725 | } 726 | ], 727 | "style": "pills", 728 | "queryType": 0, 729 | "resourceType": "microsoft.operationalinsights/workspaces" 730 | }, 731 | "conditionalVisibility": { 732 | "parameterName": "Tab", 733 | "comparison": "isEqualTo", 734 | "value": "pa" 735 | }, 736 | "name": "parameters - 19" 737 | }, 738 | { 739 | "type": 3, 740 | "content": { 741 | "version": "KqlItem/1.0", 742 | "query": "AuditLogs\r\n| extend LocalTime = TimeGenerated, '({TZ}h)'\r\n| where LocalTime > ago({PATimeRange}d)\r\n// Change hours of the day to suit your company, i.e this would find activations between 6pm and 6am\r\n| where hourofday(LocalTime) !between (({WorkDayStart}) .. ({WorkDayEnd}))\r\n| where OperationName == \"Add member to role completed (PIM activation)\"\r\n| extend RoleName = tostring(TargetResources[0].displayName)\r\n| extend UPN = tostring(TargetResources[2].userPrincipalName)\r\n| project LocalTime, OperationName, Identity, UPN, RoleName, ActivationReason=ResultReason", 743 | "size": 0, 744 | "title": "PIM elevation outside of working hours ", 745 | "queryType": 0, 746 | "resourceType": "microsoft.operationalinsights/workspaces", 747 | "crossComponentResources": [ 748 | "{Workspace}" 749 | ], 750 | "gridSettings": { 751 | "formatters": [ 752 | { 753 | "columnMatch": "Identity", 754 | "formatter": 5 755 | } 756 | ], 757 | "hierarchySettings": { 758 | "treeType": 1, 759 | "groupBy": [ 760 | "Identity" 761 | ] 762 | }, 763 | "sortBy": [ 764 | { 765 | "itemKey": "LocalTime", 766 | "sortOrder": 1 767 | } 768 | ] 769 | }, 770 | "sortBy": [ 771 | { 772 | "itemKey": "LocalTime", 773 | "sortOrder": 1 774 | } 775 | ] 776 | }, 777 | "conditionalVisibility": { 778 | "parameterName": "Tab", 779 | "comparison": "isEqualTo", 780 | "value": "pa" 781 | }, 782 | "name": "query - 15" 783 | }, 784 | { 785 | "type": 1, 786 | "content": { 787 | "json": "MFA and Passwordless Time Value. Set the 'MFAtime' to look back on the data points below regarding MFA and Passwordless." 788 | }, 789 | "conditionalVisibility": { 790 | "parameterName": "Tab", 791 | "comparison": "isEqualTo", 792 | "value": "mfa" 793 | }, 794 | "name": "text - 35" 795 | }, 796 | { 797 | "type": 9, 798 | "content": { 799 | "version": "KqlParameterItem/1.0", 800 | "parameters": [ 801 | { 802 | "id": "22ef5fd0-b8dd-49a3-9d83-c4ca40cef72d", 803 | "version": "KqlParameterItem/1.0", 804 | "name": "MFATime", 805 | "type": 1, 806 | "timeContext": { 807 | "durationMs": 86400000 808 | }, 809 | "value": "90" 810 | } 811 | ], 812 | "style": "pills", 813 | "queryType": 0, 814 | "resourceType": "microsoft.operationalinsights/workspaces" 815 | }, 816 | "conditionalVisibility": { 817 | "parameterName": "Tab", 818 | "comparison": "isEqualTo", 819 | "value": "mfa" 820 | }, 821 | "name": "parameters - 22" 822 | }, 823 | { 824 | "type": 3, 825 | "content": { 826 | "version": "KqlItem/1.0", 827 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| summarize ['Single Factor Authentication']=countif(AuthenticationRequirement == \"singleFactorAuthentication\"), ['Multi Factor Authentication']=countif(AuthenticationRequirement == \"multiFactorAuthentication\") by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\", title=\"Single vs Multifactor Authentication last 30 days\")", 828 | "size": 0, 829 | "title": "Single vs MultiFactor Authentication bas off 'MFATime'", 830 | "queryType": 0, 831 | "resourceType": "microsoft.operationalinsights/workspaces", 832 | "crossComponentResources": [ 833 | "{Workspace}" 834 | ] 835 | }, 836 | "conditionalVisibility": { 837 | "parameterName": "Tab", 838 | "comparison": "isEqualTo", 839 | "value": "mfa" 840 | }, 841 | "name": "query - 21" 842 | }, 843 | { 844 | "type": 3, 845 | "content": { 846 | "version": "KqlItem/1.0", 847 | "query": "SigninLogs\r\n| where TimeGenerated > ago({MFATime}d)\r\n| where ResultType == 0\r\n| summarize\r\n TotalCount=count(),\r\n MFACount=countif(AuthenticationRequirement == \"multiFactorAuthentication\"),\r\n nonMFACount=countif(AuthenticationRequirement == \"singleFactorAuthentication\")\r\n by AppDisplayName\r\n| project AppDisplayName, TotalCount, MFACount, nonMFACount, MFAPercentage=(todouble(MFACount) * 100 / todouble(TotalCount))\r\n| sort by MFAPercentage desc", 848 | "size": 0, 849 | "title": "Percentage of signins that are MFA based off 'MFATime'", 850 | "queryType": 0, 851 | "resourceType": "microsoft.operationalinsights/workspaces", 852 | "gridSettings": { 853 | "sortBy": [ 854 | { 855 | "itemKey": "AppDisplayName", 856 | "sortOrder": 1 857 | } 858 | ] 859 | }, 860 | "sortBy": [ 861 | { 862 | "itemKey": "AppDisplayName", 863 | "sortOrder": 1 864 | } 865 | ] 866 | }, 867 | "conditionalVisibility": { 868 | "parameterName": "Tab", 869 | "comparison": "isEqualTo", 870 | "value": "mfa" 871 | }, 872 | "name": "query - 23" 873 | }, 874 | { 875 | "type": 3, 876 | "content": { 877 | "version": "KqlItem/1.0", 878 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod != \"Previously satisfied\"\r\n| summarize\r\n Password=countif(AuthMethod == \"Password\"),\r\n Passwordless=countif(AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\"))\r\n by startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Password vs Passwordless signins per week\")", 879 | "size": 0, 880 | "title": "Password vs Passwordless based off 'MFATime'", 881 | "queryType": 0, 882 | "resourceType": "microsoft.operationalinsights/workspaces", 883 | "crossComponentResources": [ 884 | "{Workspace}" 885 | ], 886 | "tileSettings": { 887 | "showBorder": false 888 | } 889 | }, 890 | "conditionalVisibility": { 891 | "parameterName": "Tab", 892 | "comparison": "isEqualTo", 893 | "value": "mfa" 894 | }, 895 | "name": "query - 24" 896 | }, 897 | { 898 | "type": 3, 899 | "content": { 900 | "version": "KqlItem/1.0", 901 | "query": "SigninLogs\r\n| project TimeGenerated, AuthenticationDetails\r\n| where TimeGenerated > ago({MFATime}d)\r\n| extend AuthMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)\r\n| where AuthMethod in (\"FIDO2 security key\", \"Passwordless phone sign-in\", \"Windows Hello for Business\", \"Mobile app notification\",\"X.509 Certificate\")\r\n| summarize ['Passwordless Method']=count()by AuthMethod, startofweek(TimeGenerated)\r\n| render timechart with ( xtitle=\"Week\", ytitle=\"Signin Count\", title=\"Passwordless methods per week\")", 902 | "size": 0, 903 | "title": "Passwordless methods per week based off 'MFATime'", 904 | "queryType": 0, 905 | "resourceType": "microsoft.operationalinsights/workspaces", 906 | "crossComponentResources": [ 907 | "{Workspace}" 908 | ] 909 | }, 910 | "conditionalVisibility": { 911 | "parameterName": "Tab", 912 | "comparison": "isEqualTo", 913 | "value": "mfa" 914 | }, 915 | "name": "query - 25" 916 | }, 917 | { 918 | "type": 1, 919 | "content": { 920 | "json": "Legacy Authentication Time Value. Set the 'LAtime' to look back on the data points below regarding Legacy Authentication." 921 | }, 922 | "conditionalVisibility": { 923 | "parameterName": "Tab", 924 | "comparison": "isEqualTo", 925 | "value": "la" 926 | }, 927 | "name": "text - 36" 928 | }, 929 | { 930 | "type": 9, 931 | "content": { 932 | "version": "KqlParameterItem/1.0", 933 | "parameters": [ 934 | { 935 | "id": "5df704aa-b05a-4430-a8d8-441544ab9857", 936 | "version": "KqlParameterItem/1.0", 937 | "name": "LATime", 938 | "type": 1, 939 | "timeContext": { 940 | "durationMs": 86400000 941 | }, 942 | "value": "90" 943 | } 944 | ], 945 | "style": "pills", 946 | "queryType": 0, 947 | "resourceType": "microsoft.operationalinsights/workspaces" 948 | }, 949 | "conditionalVisibility": { 950 | "parameterName": "Tab", 951 | "comparison": "isEqualTo", 952 | "value": "la" 953 | }, 954 | "name": "parameters - 29" 955 | }, 956 | { 957 | "type": 3, 958 | "content": { 959 | "version": "KqlItem/1.0", 960 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType == 0\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize ['Count of legacy auth attempts'] = count()by ClientAppUsed, UserPrincipalName\r\n| sort by ClientAppUsed asc, ['Count of legacy auth attempts'] desc ", 961 | "size": 0, 962 | "title": "Legacy apps being used for signin based off 'LATime'", 963 | "queryType": 0, 964 | "resourceType": "microsoft.operationalinsights/workspaces", 965 | "crossComponentResources": [ 966 | "{Workspace}" 967 | ] 968 | }, 969 | "conditionalVisibility": { 970 | "parameterName": "Tab", 971 | "comparison": "isEqualTo", 972 | "value": "la" 973 | }, 974 | "name": "query - 27" 975 | }, 976 | { 977 | "type": 3, 978 | "content": { 979 | "version": "KqlItem/1.0", 980 | "query": "SigninLogs\r\n| where TimeGenerated > ago({LATime}d)\r\n| where ResultType in (\"0\", \"53003\")\r\n| where ClientAppUsed in (\"Exchange ActiveSync\", \"Exchange Web Services\", \"AutoDiscover\", \"Unknown\", \"POP3\", \"IMAP4\", \"Other clients\", \"Authenticated SMTP\", \"MAPI Over HTTP\", \"Offline Address Book\")\r\n| summarize\r\n ['Legacy Auth Users Allowed']=dcountif(UserPrincipalName, ResultType == 0),\r\n ['Legacy Auth Users Blocked']=dcountif(UserPrincipalName, ResultType == 53003)\r\n by bin(TimeGenerated, 1d)\r\n| render timechart with (ytitle=\"Count\",title=\"Legacy auth distinct users allowed vs blocked by Conditional Access\")", 981 | "size": 0, 982 | "title": "Legacy auth distinct users allowed vs blocked by Conditional Access based off 'LATime'", 983 | "queryType": 0, 984 | "resourceType": "microsoft.operationalinsights/workspaces", 985 | "crossComponentResources": [ 986 | "{Workspace}" 987 | ] 988 | }, 989 | "conditionalVisibility": { 990 | "parameterName": "Tab", 991 | "comparison": "isEqualTo", 992 | "value": "la" 993 | }, 994 | "name": "query - 28" 995 | }, 996 | { 997 | "type": 1, 998 | "content": { 999 | "json": "Conditional Access Time Value. Set the 'CAtime' to look back on the data points below regarding Conditional Access." 1000 | }, 1001 | "conditionalVisibility": { 1002 | "parameterName": "Tab", 1003 | "comparison": "isEqualTo", 1004 | "value": "ca" 1005 | }, 1006 | "name": "text - 37" 1007 | }, 1008 | { 1009 | "type": 9, 1010 | "content": { 1011 | "version": "KqlParameterItem/1.0", 1012 | "parameters": [ 1013 | { 1014 | "id": "c1de2781-dea2-4352-abcd-6ac9d1026d6d", 1015 | "version": "KqlParameterItem/1.0", 1016 | "name": "CATime", 1017 | "type": 1, 1018 | "timeContext": { 1019 | "durationMs": 86400000 1020 | }, 1021 | "value": "90" 1022 | } 1023 | ], 1024 | "style": "pills", 1025 | "queryType": 0, 1026 | "resourceType": "microsoft.operationalinsights/workspaces" 1027 | }, 1028 | "conditionalVisibility": { 1029 | "parameterName": "Tab", 1030 | "comparison": "isEqualTo", 1031 | "value": "ca" 1032 | }, 1033 | "name": "parameters - 32" 1034 | }, 1035 | { 1036 | "type": 3, 1037 | "content": { 1038 | "version": "KqlItem/1.0", 1039 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| summarize CAResults=make_set(CAResult) by CAPolicyName\r\n| where CAResults !has \"success\" and CAResults !has \"failure\"", 1040 | "size": 0, 1041 | "title": "Policies with no success events (user allowed in) & no failures (user blocked) based off 'CATime'", 1042 | "queryType": 0, 1043 | "resourceType": "microsoft.operationalinsights/workspaces", 1044 | "crossComponentResources": [ 1045 | "{Workspace}" 1046 | ] 1047 | }, 1048 | "conditionalVisibility": { 1049 | "parameterName": "Tab", 1050 | "comparison": "isEqualTo", 1051 | "value": "ca" 1052 | }, 1053 | "name": "query - 31" 1054 | }, 1055 | { 1056 | "type": 3, 1057 | "content": { 1058 | "version": "KqlItem/1.0", 1059 | "query": "SigninLogs\r\n| where TimeGenerated > ago ({CATime}d)\r\n| project TimeGenerated, ConditionalAccessPolicies, ResultType, ResultDescription\r\n| mv-expand ConditionalAccessPolicies\r\n| extend CAResult = tostring(ConditionalAccessPolicies.result)\r\n| extend CAPolicyName = tostring(ConditionalAccessPolicies.displayName)\r\n| where CAResult == \"failure\"\r\n| summarize CAFailureCount=count()by CAPolicyName, ResultType, ResultDescription\r\n| sort by CAFailureCount desc ", 1060 | "size": 0, 1061 | "title": "Failures and the reason based off 'CATime'", 1062 | "queryType": 0, 1063 | "resourceType": "microsoft.operationalinsights/workspaces", 1064 | "crossComponentResources": [ 1065 | "{Workspace}" 1066 | ] 1067 | }, 1068 | "conditionalVisibility": { 1069 | "parameterName": "Tab", 1070 | "comparison": "isEqualTo", 1071 | "value": "ca" 1072 | }, 1073 | "name": "query - 33" 1074 | } 1075 | ], 1076 | "fallbackResourceIds": [ 1077 | "/subscriptions/d75e3576-9a3a-4f5b-b112-b5e0088cd2e1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinel-cyberlorians" 1078 | ], 1079 | "fromTemplateId": "sentinel-UserWorkbook", 1080 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 1081 | } 1082 | -------------------------------------------------------------------------------- /M2131-EL-Validation.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "Notebook/1.0", 3 | "items": [ 4 | { 5 | "type": 12, 6 | "content": { 7 | "version": "NotebookGroup/1.0", 8 | "groupType": "editable", 9 | "items": [ 10 | { 11 | "type": 12, 12 | "content": { 13 | "version": "NotebookGroup/1.0", 14 | "groupType": "editable", 15 | "items": [ 16 | { 17 | "type": 1, 18 | "content": { 19 | "json": "# [🧾 Event-to-Control Mapping – M-21-31 Alignment](https://github.com/Cyberlorians/M-21-31/blob/main/ExecutiveSummary.md)\n---\n\nThis solution is designed to enable Cloud Architects, Security Engineers, and Governance Risk Compliance Professionals to increase visibility before, during, and after a cybersecurity incident. Information from logs on information systems (for both on-premises systems and connections \nhosted by third parties, such as cloud services providers (CSPs) is invaluable in the detection, \ninvestigation, and remediation of cyber threats. \"Executive Order 14028, Improving the Nation's Cybersecurity, directs decisive action to improve the Federal Government’s investigative and remediation capabilities. This memorandum was developed in accordance with and addresses the requirements in section 8 of the Executive Order for logging, log retention, and log management, with a focus on ensuring centralized access and visibility for the highest-level enterprise security operations center (SOC) of each agency.\" For more information, see the💡[M-21-31 Memorandum](https://www.whitehouse.gov/wp-content/uploads/2021/08/M-21-31-Improving-the-Federal-Governments-Investigative-and-Remediation-Capabilities-Related-to-Cybersecurity-Incidents.pdf)\n\n\n**Instructions: Select ELO > Select Identity > Drill down into each category and SELECT a corresponding \"Criticality ID\" that aligns w/ the M21-31 PowerApp > Event Queries will be shown as the logic used and Event Validation will be displayed if an event is logged. If needed, please click the log analytics icon on the Event Validation to adjust any KQL logic.**" 20 | }, 21 | "name": "Workbook Overview" 22 | } 23 | ] 24 | }, 25 | "customWidth": "79", 26 | "name": "group - 2" 27 | }, 28 | { 29 | "type": 1, 30 | "content": { 31 | "json": "![Image Name](https://azure.microsoft.com/svghandler/azure-sentinel?width=600&height=315) " 32 | }, 33 | "customWidth": "21", 34 | "name": "Microsoft Sentinel Logo" 35 | } 36 | ] 37 | }, 38 | "name": "group - 14" 39 | }, 40 | { 41 | "type": 9, 42 | "content": { 43 | "version": "KqlParameterItem/1.0", 44 | "crossComponentResources": [ 45 | "value::all" 46 | ], 47 | "parameters": [ 48 | { 49 | "id": "55d3ab63-6e1f-4d02-8d9e-2225526689c7", 50 | "version": "KqlParameterItem/1.0", 51 | "name": "Subscription", 52 | "type": 6, 53 | "isRequired": true, 54 | "multiSelect": true, 55 | "quote": "'", 56 | "delimiter": ",", 57 | "query": "summarize by subscriptionId\r\n| project value = strcat(\"/subscriptions/\", subscriptionId)", 58 | "crossComponentResources": [ 59 | "value::all" 60 | ], 61 | "typeSettings": { 62 | "additionalResourceOptions": [ 63 | "value::all" 64 | ], 65 | "showDefault": false 66 | }, 67 | "timeContext": { 68 | "durationMs": 0 69 | }, 70 | "timeContextFromParameter": "TimeRange", 71 | "queryType": 1, 72 | "resourceType": "microsoft.resourcegraph/resources", 73 | "value": [ 74 | "value::all" 75 | ] 76 | }, 77 | { 78 | "id": "95a45501-31b5-4ea2-bcb3-eb208e0080e2", 79 | "version": "KqlParameterItem/1.0", 80 | "name": "Workspace", 81 | "type": 5, 82 | "multiSelect": true, 83 | "quote": "'", 84 | "delimiter": ",", 85 | "query": "resources\r\n| where type =~ 'microsoft.operationsmanagement/solutions'\r\n| where name contains 'SecurityInsights'\r\n| project id = tolower(tostring(properties.workspaceResourceId))\r\n| join (resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| extend id=tolower(id)\r\n) on id\r\n| project id", 86 | "crossComponentResources": [ 87 | "{Subscription}" 88 | ], 89 | "typeSettings": { 90 | "additionalResourceOptions": [ 91 | "value::all" 92 | ], 93 | "showDefault": false 94 | }, 95 | "timeContextFromParameter": "TimeRange", 96 | "defaultValue": "value::all", 97 | "queryType": 1, 98 | "resourceType": "microsoft.resourcegraph/resources" 99 | } 100 | ], 101 | "style": "pills", 102 | "queryType": 1, 103 | "resourceType": "microsoft.resourcegraph/resources" 104 | }, 105 | "customWidth": "100", 106 | "name": "parameters - 6" 107 | }, 108 | { 109 | "type": 12, 110 | "content": { 111 | "version": "NotebookGroup/1.0", 112 | "groupType": "editable", 113 | "items": [ 114 | { 115 | "type": 3, 116 | "content": { 117 | "version": "KqlItem/1.0", 118 | "query": "{\"version\":\"1.0.0\",\"content\":\"[\\r\\n\\t\\t{ \\\"Event Logging Level\\\": \\\"EL0 - Not Effective - IN BETA (Select Here)\\\", \\\"tab\\\": \\\"EL0\\\" },\\r\\n\\t\\t{ \\\"Event Logging Level\\\": \\\"EL1 - Basic - To Be Mapped\\\", \\\"tab\\\": \\\"EL1\\\" },\\r\\n\\t\\t{ \\\"Event Logging Level\\\": \\\"EL2 - Intermediate - To Be Mapped\\\", \\\"tab\\\": \\\"EL2\\\" },\\r\\n\\t\\t{ \\\"Event Logging Level\\\": \\\"EL3 - Advanced - To Be Mapped\\\", \\\"tab\\\": \\\"EL3\\\" }\\r\\n\\t\\t]\",\"transformers\":null}", 119 | "size": 1, 120 | "exportMultipleValues": true, 121 | "exportedParameters": [ 122 | { 123 | "fieldName": "tab", 124 | "parameterName": "Tab", 125 | "parameterType": 1 126 | } 127 | ], 128 | "queryType": 8, 129 | "gridSettings": { 130 | "formatters": [ 131 | { 132 | "columnMatch": "tab", 133 | "formatter": 5 134 | } 135 | ] 136 | } 137 | }, 138 | "customWidth": "90", 139 | "name": "EL-JSON" 140 | }, 141 | { 142 | "type": 9, 143 | "content": { 144 | "version": "KqlParameterItem/1.0", 145 | "parameters": [ 146 | { 147 | "id": "8f836776-6a60-46a6-8d25-be73bf045494", 148 | "version": "KqlParameterItem/1.0", 149 | "name": "isEL0Visible", 150 | "type": 1, 151 | "isHiddenWhenLocked": true, 152 | "criteriaData": [ 153 | { 154 | "criteriaContext": { 155 | "leftOperand": "Tab", 156 | "operator": "contains", 157 | "rightValType": "static", 158 | "rightVal": "EL0", 159 | "resultValType": "static", 160 | "resultVal": "true" 161 | } 162 | }, 163 | { 164 | "criteriaContext": { 165 | "operator": "Default", 166 | "resultValType": "static", 167 | "resultVal": "false" 168 | } 169 | } 170 | ], 171 | "timeContext": { 172 | "durationMs": 86400000 173 | } 174 | }, 175 | { 176 | "id": "3758b348-e74f-437f-abd4-4e6e66b1be7e", 177 | "version": "KqlParameterItem/1.0", 178 | "name": "isEL1Visible", 179 | "type": 1, 180 | "isHiddenWhenLocked": true, 181 | "criteriaData": [ 182 | { 183 | "criteriaContext": { 184 | "leftOperand": "Tab", 185 | "operator": "contains", 186 | "rightValType": "static", 187 | "rightVal": "EL1", 188 | "resultValType": "static", 189 | "resultVal": "true" 190 | } 191 | }, 192 | { 193 | "criteriaContext": { 194 | "operator": "Default", 195 | "resultValType": "static", 196 | "resultVal": "false" 197 | } 198 | } 199 | ], 200 | "timeContext": { 201 | "durationMs": 86400000 202 | } 203 | }, 204 | { 205 | "id": "aa7ebd19-042f-46e5-a510-cf22deda0491", 206 | "version": "KqlParameterItem/1.0", 207 | "name": "isEL2Visible", 208 | "type": 1, 209 | "isHiddenWhenLocked": true, 210 | "criteriaData": [ 211 | { 212 | "criteriaContext": { 213 | "leftOperand": "Tab", 214 | "operator": "contains", 215 | "rightValType": "static", 216 | "rightVal": "EL2", 217 | "resultValType": "static", 218 | "resultVal": "true" 219 | } 220 | }, 221 | { 222 | "criteriaContext": { 223 | "operator": "Default", 224 | "resultValType": "static", 225 | "resultVal": "false" 226 | } 227 | } 228 | ], 229 | "timeContext": { 230 | "durationMs": 86400000 231 | } 232 | }, 233 | { 234 | "id": "03b0ef89-0638-4acc-a4db-2428fea9a844", 235 | "version": "KqlParameterItem/1.0", 236 | "name": "isEL3Visible", 237 | "type": 1, 238 | "isHiddenWhenLocked": true, 239 | "criteriaData": [ 240 | { 241 | "criteriaContext": { 242 | "leftOperand": "Tab", 243 | "operator": "contains", 244 | "rightValType": "static", 245 | "rightVal": "EL3", 246 | "resultValType": "static", 247 | "resultVal": "true" 248 | } 249 | }, 250 | { 251 | "criteriaContext": { 252 | "operator": "Default", 253 | "resultValType": "static", 254 | "resultVal": "false" 255 | } 256 | } 257 | ], 258 | "timeContext": { 259 | "durationMs": 86400000 260 | } 261 | } 262 | ], 263 | "style": "pills", 264 | "queryType": 0, 265 | "resourceType": "microsoft.operationalinsights/workspaces" 266 | }, 267 | "customWidth": "5", 268 | "name": "EL-JSON-Params" 269 | } 270 | ], 271 | "exportParameters": true 272 | }, 273 | "customWidth": "50", 274 | "name": "Event-Selection" 275 | }, 276 | { 277 | "type": 12, 278 | "content": { 279 | "version": "NotebookGroup/1.0", 280 | "groupType": "editable", 281 | "items": [ 282 | { 283 | "type": 3, 284 | "content": { 285 | "version": "KqlItem/1.0", 286 | "query": "{\"version\":\"1.0.0\",\"content\":\"[\\r\\n\\t\\t{ \\\"Function\\\": \\\"Identity - PRODUCTION (Select Here)\\\", \\\"tab\\\": \\\"EL01\\\" },\\r\\n\\t\\t{ \\\"Function\\\": \\\"Network - To Be Mapped\\\", \\\"tab\\\": \\\"EL02\\\" },\\r\\n\\t\\t{ \\\"Function\\\": \\\"Email - To Be Mapped\\\", \\\"tab\\\": \\\"EL03\\\" },\\r\\n\\t\\t{ \\\"Function\\\": \\\"Opearting Systems - IN BETA (Select Here)\\\", \\\"tab\\\": \\\"EL04\\\" },\\r\\n\\t\\t{ \\\"Function\\\": \\\"Cloud - To Be Mapped\\\", \\\"tab\\\": \\\"EL05\\\" }\\r\\n\\t\\t]\",\"transformers\":null}", 287 | "size": 1, 288 | "exportMultipleValues": true, 289 | "exportedParameters": [ 290 | { 291 | "fieldName": "tab", 292 | "parameterName": "Tab", 293 | "parameterType": 1 294 | } 295 | ], 296 | "queryType": 8, 297 | "gridSettings": { 298 | "formatters": [ 299 | { 300 | "columnMatch": "tab", 301 | "formatter": 5 302 | } 303 | ] 304 | } 305 | }, 306 | "customWidth": "90", 307 | "name": "EL0-JSON" 308 | }, 309 | { 310 | "type": 9, 311 | "content": { 312 | "version": "KqlParameterItem/1.0", 313 | "parameters": [ 314 | { 315 | "id": "8f836776-6a60-46a6-8d25-be73bf045494", 316 | "version": "KqlParameterItem/1.0", 317 | "name": "isEL01Visible", 318 | "type": 1, 319 | "isHiddenWhenLocked": true, 320 | "criteriaData": [ 321 | { 322 | "criteriaContext": { 323 | "leftOperand": "Tab", 324 | "operator": "contains", 325 | "rightValType": "static", 326 | "rightVal": "EL01", 327 | "resultValType": "static", 328 | "resultVal": "true" 329 | } 330 | }, 331 | { 332 | "criteriaContext": { 333 | "operator": "Default", 334 | "resultValType": "static", 335 | "resultVal": "false" 336 | } 337 | } 338 | ], 339 | "timeContext": { 340 | "durationMs": 86400000 341 | } 342 | }, 343 | { 344 | "id": "3758b348-e74f-437f-abd4-4e6e66b1be7e", 345 | "version": "KqlParameterItem/1.0", 346 | "name": "isEL02Visible", 347 | "type": 1, 348 | "isHiddenWhenLocked": true, 349 | "criteriaData": [ 350 | { 351 | "criteriaContext": { 352 | "leftOperand": "Tab", 353 | "operator": "contains", 354 | "rightValType": "static", 355 | "rightVal": "EL02", 356 | "resultValType": "static", 357 | "resultVal": "true" 358 | } 359 | }, 360 | { 361 | "criteriaContext": { 362 | "operator": "Default", 363 | "resultValType": "static", 364 | "resultVal": "false" 365 | } 366 | } 367 | ], 368 | "timeContext": { 369 | "durationMs": 86400000 370 | } 371 | }, 372 | { 373 | "id": "aa7ebd19-042f-46e5-a510-cf22deda0491", 374 | "version": "KqlParameterItem/1.0", 375 | "name": "isEL03Visible", 376 | "type": 1, 377 | "isHiddenWhenLocked": true, 378 | "criteriaData": [ 379 | { 380 | "criteriaContext": { 381 | "leftOperand": "Tab", 382 | "operator": "contains", 383 | "rightValType": "static", 384 | "rightVal": "EL03", 385 | "resultValType": "static", 386 | "resultVal": "true" 387 | } 388 | }, 389 | { 390 | "criteriaContext": { 391 | "operator": "Default", 392 | "resultValType": "static", 393 | "resultVal": "false" 394 | } 395 | } 396 | ], 397 | "timeContext": { 398 | "durationMs": 86400000 399 | } 400 | }, 401 | { 402 | "id": "03b0ef89-0638-4acc-a4db-2428fea9a844", 403 | "version": "KqlParameterItem/1.0", 404 | "name": "isEL04Visible", 405 | "type": 1, 406 | "isHiddenWhenLocked": true, 407 | "criteriaData": [ 408 | { 409 | "criteriaContext": { 410 | "leftOperand": "Tab", 411 | "operator": "contains", 412 | "rightValType": "static", 413 | "rightVal": "EL04", 414 | "resultValType": "static", 415 | "resultVal": "true" 416 | } 417 | }, 418 | { 419 | "criteriaContext": { 420 | "operator": "Default", 421 | "resultValType": "static", 422 | "resultVal": "false" 423 | } 424 | } 425 | ], 426 | "timeContext": { 427 | "durationMs": 86400000 428 | } 429 | }, 430 | { 431 | "id": "ebe7944a-82bc-46c1-b377-0415f108cf95", 432 | "version": "KqlParameterItem/1.0", 433 | "name": "isEL05Visible", 434 | "type": 1, 435 | "isHiddenWhenLocked": true, 436 | "criteriaData": [ 437 | { 438 | "criteriaContext": { 439 | "leftOperand": "Tab", 440 | "operator": "contains", 441 | "rightValType": "static", 442 | "rightVal": "EL05", 443 | "resultValType": "static", 444 | "resultVal": "true" 445 | } 446 | }, 447 | { 448 | "criteriaContext": { 449 | "operator": "Default", 450 | "resultValType": "static", 451 | "resultVal": "false" 452 | } 453 | } 454 | ], 455 | "timeContext": { 456 | "durationMs": 86400000 457 | } 458 | } 459 | ], 460 | "style": "pills", 461 | "queryType": 0, 462 | "resourceType": "microsoft.operationalinsights/workspaces" 463 | }, 464 | "customWidth": "1", 465 | "name": "EL0-Params" 466 | } 467 | ], 468 | "exportParameters": true 469 | }, 470 | "conditionalVisibility": { 471 | "parameterName": "isEL0Visible", 472 | "comparison": "isEqualTo", 473 | "value": "true" 474 | }, 475 | "customWidth": "50", 476 | "name": "EL0-Functions" 477 | }, 478 | { 479 | "type": 12, 480 | "content": { 481 | "version": "NotebookGroup/1.0", 482 | "groupType": "editable", 483 | "items": [ 484 | { 485 | "type": 3, 486 | "content": { 487 | "version": "KqlItem/1.0", 488 | "query": "externaldata (Criticality:string, CSL1:string, CSL2:string, CSL3:string, CSL4:string, Function:string, Category:string, ['Sub-Category']:string, ['Required Data']:string, Workload:string, Table:string, Schema:string, ['Schema-Value']:string, ['Workload Integration']:string, ['Event Reference']:string, ['Microsoft Unified SecOps Event']:string )[@\"https://raw.githubusercontent.com/Cyberlorians/Workbooks/refs/heads/main/M2131v0.2.0.csv\"] with (format=\"csv\",ignoreFirstRecord=true)\r\n| extend ID = strcat(Criticality, \"-\", CSL1, \"-\", CSL2, \"-\", CSL3, \"-\", CSL4)\r\n| where Function == 'Identity'\r\n| project ID, Criticality, CSL1, CSL2, CSL3, Function, Category, ['Sub-Category'], ['Required Data'], Workload, Table, Schema, ['Schema-Value'], ['Microsoft Unified SecOps Event'], ['Event Reference']\r\n| where isnotempty(Category)\r\n| sort by ID asc\r\n", 489 | "size": 0, 490 | "title": "🧑‍💼 Identity", 491 | "exportedParameters": [ 492 | { 493 | "fieldName": "Microsoft Unified SecOps Event", 494 | "parameterName": "kql", 495 | "parameterType": 1 496 | }, 497 | { 498 | "fieldName": "Event Reference", 499 | "parameterName": "er", 500 | "parameterType": 1 501 | } 502 | ], 503 | "queryType": 0, 504 | "resourceType": "microsoft.operationalinsights/workspaces", 505 | "crossComponentResources": [ 506 | "{Workspace}" 507 | ], 508 | "gridSettings": { 509 | "formatters": [ 510 | { 511 | "columnMatch": "Criticality", 512 | "formatter": 5 513 | }, 514 | { 515 | "columnMatch": "CSL1", 516 | "formatter": 5 517 | }, 518 | { 519 | "columnMatch": "CSL2", 520 | "formatter": 5 521 | }, 522 | { 523 | "columnMatch": "CSL3", 524 | "formatter": 5 525 | }, 526 | { 527 | "columnMatch": "Function", 528 | "formatter": 5 529 | }, 530 | { 531 | "columnMatch": "Category", 532 | "formatter": 5 533 | }, 534 | { 535 | "columnMatch": "Required Data", 536 | "formatter": 5 537 | }, 538 | { 539 | "columnMatch": "Microsoft Unified SecOps Event", 540 | "formatter": 5 541 | }, 542 | { 543 | "columnMatch": "Event Reference", 544 | "formatter": 5, 545 | "formatOptions": { 546 | "linkTarget": "Url" 547 | } 548 | }, 549 | { 550 | "columnMatch": "Microsoft Sentinel Event", 551 | "formatter": 5, 552 | "formatOptions": { 553 | "linkTarget": "CellDetails", 554 | "linkIsContextBlade": true 555 | } 556 | }, 557 | { 558 | "columnMatch": "Microsoft XDR Event", 559 | "formatter": 5 560 | }, 561 | { 562 | "columnMatch": "Workload Integration", 563 | "formatter": 5, 564 | "formatOptions": { 565 | "linkTarget": "Url" 566 | } 567 | } 568 | ], 569 | "filter": true, 570 | "hierarchySettings": { 571 | "treeType": 1, 572 | "groupBy": [ 573 | "Category", 574 | "Required Data" 575 | ], 576 | "expandTopLevel": false 577 | } 578 | }, 579 | "sortBy": [] 580 | }, 581 | "conditionalVisibility": { 582 | "parameterName": "isEL01Visible", 583 | "comparison": "isEqualTo", 584 | "value": "true" 585 | }, 586 | "name": "EL01-Identity" 587 | }, 588 | { 589 | "type": 3, 590 | "content": { 591 | "version": "KqlItem/1.0", 592 | "query": "externaldata (Criticality:string, CSL1:string, CSL2:string, CSL3:string, CSL4:string, Function:string, Category:string, ['Sub-Category']:string, ['Required Data']:string, Workload:string, Table:string, Schema:string, ['Schema-Value']:string, ['Workload Integration']:string, ['Event Reference']:string,['Microsoft Unified SecOps Event']:string )[@\"https://raw.githubusercontent.com/Cyberlorians/Workbooks/refs/heads/main/M2131v0.2.0.csv\"] with (format=\"csv\",ignoreFirstRecord=true)\r\n| extend ID = strcat(Criticality, \"-\", CSL1, \"-\", CSL2, \"-\", CSL3, \"-\", CSL4)\r\n| where Function == 'Operating Systems'\r\n| project ID, Criticality, CSL1, CSL2, CSL3, Function, Category, ['Sub-Category'], ['Required Data'], Workload, Table, Schema, ['Schema-Value'], ['Microsoft Unified SecOps Event'], ['Event Reference']\r\n| where isnotempty(Category)\r\n| sort by ID asc\r\n", 593 | "size": 0, 594 | "title": "💻 Operating Systems", 595 | "exportedParameters": [ 596 | { 597 | "fieldName": "Microsoft Unified SecOps Event", 598 | "parameterName": "kql", 599 | "parameterType": 1 600 | }, 601 | { 602 | "fieldName": "Event Reference", 603 | "parameterName": "er", 604 | "parameterType": 1 605 | } 606 | ], 607 | "queryType": 0, 608 | "resourceType": "microsoft.operationalinsights/workspaces", 609 | "crossComponentResources": [ 610 | "{Workspace}" 611 | ], 612 | "gridSettings": { 613 | "formatters": [ 614 | { 615 | "columnMatch": "$gen_group", 616 | "formatter": 0, 617 | "formatOptions": { 618 | "customColumnWidthSetting": "100ch" 619 | } 620 | }, 621 | { 622 | "columnMatch": "Criticality", 623 | "formatter": 5 624 | }, 625 | { 626 | "columnMatch": "CSL1", 627 | "formatter": 5 628 | }, 629 | { 630 | "columnMatch": "CSL2", 631 | "formatter": 5 632 | }, 633 | { 634 | "columnMatch": "CSL3", 635 | "formatter": 5 636 | }, 637 | { 638 | "columnMatch": "Function", 639 | "formatter": 5 640 | }, 641 | { 642 | "columnMatch": "Category", 643 | "formatter": 5 644 | }, 645 | { 646 | "columnMatch": "Sub-Category", 647 | "formatter": 5 648 | }, 649 | { 650 | "columnMatch": "Required Data", 651 | "formatter": 5 652 | }, 653 | { 654 | "columnMatch": "Microsoft Unified SecOps Event", 655 | "formatter": 5 656 | }, 657 | { 658 | "columnMatch": "Event Reference", 659 | "formatter": 5, 660 | "formatOptions": { 661 | "linkTarget": "Url" 662 | } 663 | }, 664 | { 665 | "columnMatch": "Microsoft Unified Secops Event", 666 | "formatter": 5 667 | }, 668 | { 669 | "columnMatch": "Microsoft Sentinel Event", 670 | "formatter": 5, 671 | "formatOptions": { 672 | "linkTarget": "CellDetails", 673 | "linkIsContextBlade": true 674 | } 675 | }, 676 | { 677 | "columnMatch": "Microsoft XDR Event", 678 | "formatter": 5 679 | }, 680 | { 681 | "columnMatch": "Workload Integration", 682 | "formatter": 5, 683 | "formatOptions": { 684 | "linkTarget": "Url" 685 | } 686 | } 687 | ], 688 | "filter": true, 689 | "hierarchySettings": { 690 | "treeType": 1, 691 | "groupBy": [ 692 | "Category", 693 | "Required Data" 694 | ], 695 | "expandTopLevel": false 696 | }, 697 | "labelSettings": [ 698 | { 699 | "columnId": "Category", 700 | "label": "Required Data" 701 | } 702 | ] 703 | } 704 | }, 705 | "conditionalVisibility": { 706 | "parameterName": "isEL04Visible", 707 | "comparison": "isEqualTo", 708 | "value": "true" 709 | }, 710 | "showPin": false, 711 | "name": "EL01-Windows" 712 | } 713 | ], 714 | "exportParameters": true 715 | }, 716 | "name": "EL0-Function-Group-Master" 717 | }, 718 | { 719 | "type": 12, 720 | "content": { 721 | "version": "NotebookGroup/1.0", 722 | "groupType": "editable", 723 | "title": "🕵️‍♂️ Event Queries – Expand to View!", 724 | "expandable": true, 725 | "items": [ 726 | { 727 | "type": 1, 728 | "content": { 729 | "json": " 🔎 **Microsoft Unified SecOps Event**
\r\n 📎 **Reference**: {er}\r\n\r\n```\r\n{kql}\r\n```" 730 | }, 731 | "name": "Sentinel-KQL", 732 | "styleSettings": { 733 | "showBorder": true 734 | } 735 | } 736 | ] 737 | }, 738 | "conditionalVisibility": { 739 | "parameterName": "kql", 740 | "comparison": "isNotEqualTo" 741 | }, 742 | "customWidth": "50", 743 | "name": "KQL-Group-Text" 744 | }, 745 | { 746 | "type": 3, 747 | "content": { 748 | "version": "KqlItem/1.0", 749 | "query": "{kql}", 750 | "size": 3, 751 | "showAnalytics": true, 752 | "title": "📊 Event Validation", 753 | "showRefreshButton": true, 754 | "exportFieldName": "Value", 755 | "exportParameterName": "try", 756 | "exportToExcelOptions": "all", 757 | "queryType": 0, 758 | "resourceType": "microsoft.operationalinsights/workspaces", 759 | "crossComponentResources": [ 760 | "{Workspace}" 761 | ], 762 | "gridSettings": { 763 | "formatters": [ 764 | { 765 | "columnMatch": "Parameter name", 766 | "formatter": 5 767 | }, 768 | { 769 | "columnMatch": "Display name", 770 | "formatter": 5 771 | }, 772 | { 773 | "columnMatch": "Parameter type", 774 | "formatter": 5 775 | }, 776 | { 777 | "columnMatch": "Value", 778 | "formatter": 1 779 | }, 780 | { 781 | "columnMatch": "Formatted", 782 | "formatter": 5 783 | }, 784 | { 785 | "columnMatch": "Label", 786 | "formatter": 5 787 | }, 788 | { 789 | "columnMatch": "Pending", 790 | "formatter": 5 791 | }, 792 | { 793 | "columnMatch": "Failed", 794 | "formatter": 5 795 | } 796 | ], 797 | "rowLimit": 1000, 798 | "filter": true 799 | }, 800 | "sortBy": [], 801 | "mapSettings": { 802 | "locInfo": "LatLong" 803 | } 804 | }, 805 | "conditionalVisibility": { 806 | "parameterName": "kql", 807 | "comparison": "isNotEqualTo" 808 | }, 809 | "showPin": true, 810 | "name": "Event Results" 811 | } 812 | ], 813 | "fallbackResourceIds": [ 814 | "/subscriptions/4260a1bd-84f2-4114-8197-2bbf9a9350a1/resourcegroups/sentinel/providers/microsoft.operationalinsights/workspaces/sentinellaw" 815 | ], 816 | "fromTemplateId": "sentinel-UserWorkbook", 817 | "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" 818 | } 819 | -------------------------------------------------------------------------------- /M2131v0.1.0-COPY.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cyberlorians/Workbooks/f4274e99d6409d90ba9791366d7445f05be851e7/M2131v0.1.0-COPY.csv -------------------------------------------------------------------------------- /XDRSizing.kql: -------------------------------------------------------------------------------- 1 | // Objective: Show estimated data size in GB and record count per table over the last 7 days 2 | let TimeRange = ago(7d); 3 | union isfuzzy=true 4 | (DeviceInfo | where Timestamp > TimeRange | extend Table = "DeviceInfo"), 5 | (DeviceProcessEvents | where Timestamp > TimeRange | extend Table = "DeviceProcessEvents"), 6 | (DeviceNetworkEvents | where Timestamp > TimeRange | extend Table = "DeviceNetworkEvents"), 7 | (DeviceFileEvents | where Timestamp > TimeRange | extend Table = "DeviceFileEvents"), 8 | (DeviceLogonEvents | where Timestamp > TimeRange | extend Table = "DeviceLogonEvents"), 9 | (DeviceEvents | where Timestamp > TimeRange | extend Table = "DeviceEvents"), 10 | (EmailEvents | where Timestamp > TimeRange | extend Table = "EmailEvents"), 11 | (EmailUrlInfo | where Timestamp > TimeRange | extend Table = "EmailUrlInfo"), 12 | (EmailAttachmentInfo | where Timestamp > TimeRange | extend Table = "EmailAttachmentInfo"), 13 | (EmailPostDeliveryEvents | where Timestamp > TimeRange | extend Table = "EmailPostDeliveryEvents"), 14 | (UrlClickEvents | where Timestamp > TimeRange | extend Table = "UrlClickEvents") 15 | | summarize 16 | RecordCount = count(), 17 | TotalSizeGB = round(sum(estimate_data_size(*)) / pow(1024, 3), 2) 18 | by Table 19 | | order by TotalSizeGB desc 20 | -------------------------------------------------------------------------------- /cisaMAG.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "GraphEndpoint": "domains", 4 | "GraphUri": "https://graph.microsoft.us/v1.0/domains" 5 | }, 6 | { 7 | "GraphEndpoint": "partners", 8 | "GraphUri": "https://graph.microsoft.us/v1.0/policies/crossTenantAccessPolicy/partners" 9 | }, 10 | { 11 | "GraphEndpoint": "authenitcationMethodsPolicy", 12 | "GraphUri": "https://graph.microsoft.us/v1.0/policies/authenticationMethodsPolicy" 13 | }, 14 | { 15 | "GraphEndpoint": "authenticationStrengthPolicies", 16 | "GraphUri": "https://graph.microsoft.us/v1.0/policies/authenticationStrengthPolicies" 17 | }, 18 | { 19 | "GraphEndpoint": "deviceConfigurations", 20 | "GraphUri": "https://graph.microsoft.us/v1.0/deviceManagement/deviceConfigurations" 21 | }, 22 | { 23 | "GraphEndpoint": "devices", 24 | "GraphUri": "https://graph.microsoft.us/v1.0/devices?$select=displayName,deviceId,operatingSystemVersion,operatingSystem,profileType,trustType,isManaged,accountEnabled,approximateLastSignInDateTime,registrationDateTime" 25 | }, 26 | { 27 | "GraphEndpoint": "accessPackages", 28 | "GraphUri": "https://graph.microsoft.us/v1.0/identityGovernance/entitlementManagement/accessPackages?$expand=catalog" 29 | } 30 | 31 | 32 | ] 33 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | * Conditional-Access-Change-Dashboard-MAG - Workbook please review the original authors doc [here](https://danielchronlund.com/category/conditional-access/). Again, this has been modified by Cyberlorians to work in AzureUSGovernment. Thank you Daniel Chronlund for the original content. Change comparison is still in works since MAG is not 1:1 with tables/schema against its commercial counterpart. 2 | --------------------------------------------------------------------------------