{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 9,
      "content": {
        "version": "KqlParameterItem/1.0",
        "parameters": [
          {
            "id": "743317e2-ebcf-4958-861d-4ff97fc7cce1",
            "version": "KqlParameterItem/1.0",
            "name": "EnvironmentList",
            "label": "Environment",
            "type": 2,
            "isRequired": true,
            "multiSelect": true,
            "quote": "'",
            "delimiter": ",",
            "query": "ExchangeEnvironmentList(Target=\"On-Premises\") | where ESIEnvironment != \"\"",
            "typeSettings": {
              "limitSelectTo": 1,
              "showDefault": false
            },
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          },
          {
            "id": "a88b4e41-eb2f-41bf-92d8-27c83650a4b8",
            "version": "KqlParameterItem/1.0",
            "name": "DateOfConfiguration",
            "label": "Collection time",
            "type": 2,
            "isRequired": true,
            "query": "let _configurationEnv = split(iff(isnull({EnvironmentList}) or isempty({EnvironmentList}) or tolower({EnvironmentList}) == \"all\",\"All\",tostring({EnvironmentList})),',');\r\nESIExchangeConfig_CL\r\n| extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \r\n| where ScopedEnvironment in (_configurationEnv)\r\n| extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\r\n| summarize Collection = max(Collection)\r\n| project Collection = \"lastdate\", Selected = true\r\n| join kind= fullouter  ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \r\n    | where ScopedEnvironment in (_configurationEnv)\r\n    | where TimeGenerated > ago(90d)\r\n    | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\r\n    | summarize by Collection \r\n    | join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \r\n        | where ScopedEnvironment in (_configurationEnv)\r\n        | where TimeGenerated > ago(90d)\r\n        | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\r\n        | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm ')\r\n        | summarize by PreciseCollection, Collection \r\n        | join kind=leftouter (\r\n            ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \"All\", \"All\",ESIEnvironment_s) \r\n            | where ScopedEnvironment in (_configurationEnv)\r\n            | where TimeGenerated > ago(90d)\r\n            | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\r\n            | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm')\r\n            | summarize by PreciseCollection, Collection \r\n            | summarize count() by Collection\r\n        ) on Collection\r\n    ) on Collection\r\n) on Collection\r\n| project Value = iif(Selected,Collection,iif(count_ > 1,PreciseCollection,Collection1)), Label = iif(Selected,\"Last Known date\",iif(count_ > 1,PreciseCollection,Collection1)), Selected\r\n| sort by Selected, Value desc",
            "typeSettings": {
              "showDefault": false
            },
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          },
          {
            "id": "8ac96eb3-918b-4a36-bcc4-df50d8f46175",
            "version": "KqlParameterItem/1.0",
            "name": "Help",
            "label": "Show Help",
            "type": 10,
            "isRequired": true,
            "query": "{\"version\":\"1.0.0\",\"content\":\"[\\r\\n { \\\"value\\\": \\\"Yes\\\", \\\"label\\\": \\\"Yes\\\"},\\r\\n {\\\"value\\\": \\\"No\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\\r\\n\"}",
            "timeContext": {
              "durationMs": 2592000000
            },
            "queryType": 8
          }
        ],
        "style": "above",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "TimeRange"
    },
    {
      "type": 1,
      "content": {
        "json": "This workbook displayed the custom RBAC delegations: on default groups, on Custom Roles groups, Using custom roles.</BR>\r\nSelect your Exchange Organization and adjust the time range.\r\nBy default, the Help won't be displayed. To display the help, choose Yes on the toogle buttom \"Show Help\"",
        "style": "info"
      },
      "name": "text - 8"
    },
    {
      "type": 11,
      "content": {
        "version": "LinkItem/1.0",
        "style": "tabs",
        "links": [
          {
            "id": "e59f0f7f-fd05-4ec8-9f59-e4d9c3b589f2",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Current RBAC Delegation",
            "subTarget": "RBACDelegation",
            "preText": "RBAC Delegation",
            "postText": "",
            "style": "link"
          },
          {
            "id": "67739913-b364-4071-864d-faf4d94c9ad6",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Custom Roles",
            "subTarget": "CustomRole",
            "style": "link"
          },
          {
            "id": "8def944a-53fe-4544-bc8f-5b3ca66eda34",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Default Groups content",
            "subTarget": "DefaultGroup",
            "preText": "Default Group",
            "style": "link"
          },
          {
            "id": "5eeebe10-be67-4f8a-9d91-4bc6c70c3e16",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Workbook Help",
            "subTarget": "start",
            "style": "link"
          }
        ]
      },
      "name": "links - 3"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Custom Delegations",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "The current delegations are compared to an export of default delegations done on Exchange 2019.\r\nTo find which is used for the comparaison please follow this link.\r\nThe export is located on the public GitHub of the project.\r\n\r\ncheck this link : <a href=\"https://aka.ms/esiwatchlist\" target=\"_blank\\\">https://aka.ms/esiwatchlist</a>\r\n\r\nIt will be updated by the team project.\r\n",
              "style": "info"
            },
            "name": "text - 2"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Custom Delegations on User Accounts",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays custom delegations set directly on User Accounts."
                  },
                  "name": "text - 2 - Copy"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays all the nonstandard delegations done directly to a user account.\r\n\r\nDetailed information for the user accounts will be displayed.\r\n\r\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\r\n\r\nThese types of delegations are not visible on the Exchange Admin Center.\r\n\r\nUsual results :\r\n\r\n  - Delegations done directly to service account. Being able to see this delegation will help to sanityze the environment as some delegations may be no more necessary\r\n\r\n  - Delegation done by mistake directly to Administrator Accounts\r\n\r\n  - Suspicious delegations\r\n\r\nDetailed information for the user accounts will be displayed in the sections below.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/view-effective-permissions-exchange-2013-help\" target=\"_blank\">View RBAC effective permissions</a>\r\n\r\n<a href=\"https://learn.microsoft.com/powershell/module/exchange/get-managementroleassignment?view=exchange-ps\" target=\"_blank\">Get-ManagementRoleAssignment</a>\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/understanding-role-based-access-control-exchange-2013-help \" target=\"_blank\">Understanding Role Based Access Control</a>\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "d9d4e0a2-b75d-4825-9f4e-7606516500e1",
                        "version": "KqlParameterItem/1.0",
                        "name": "RoleAssignee",
                        "type": 2,
                        "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"0\"\r\n| project CmdletResultValue\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| distinct RoleAssigneeName\r\n",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      },
                      {
                        "id": "46c608de-033d-4c4f-99e6-2784439cfa18",
                        "version": "KqlParameterItem/1.0",
                        "name": "Role",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n|extend Role=tostring (CmdletResultValue.Role.Name)\r\n| distinct Role\r\n| sort by Role asc",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 5"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where  CmdletResultValue.RoleAssigneeName endswith  \"{RoleAssignee}\" \r\n| where  CmdletResultValue.Role.Name contains \"{Role}\"\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"0\" and CmdletResultValue.Name !contains \"Deleg\"\r\n| extend Name = tostring(CmdletResultValue.Name)\r\n| extend Role = tostring(CmdletResultValue.Role.Name)\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\r\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\r\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\"0\",\"None\",CmdletResultValue.RecipientWriteScope==\"2\",\"Organization\",CmdletResultValue.RecipientWriteScope==\"3\",\"MyGAL\", CmdletResultValue.RecipientWriteScope==\"4\",\"Self\",CmdletResultValue.RecipientWriteScope==\"7\", \"CustomRecipientScope\",CmdletResultValue.RecipientWriteScope==\"8\",\"MyDistributionGroups\",\"NotApplicable\")\r\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\r\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \"0\" , \"None\", \"OrganizationConfig\")\r\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\"2\",\"Organization\",CmdletResultValue.RecipientReadScope==\"3\",\"MyGAL\",CmdletResultValue.RecipientReadScope==\"4\",\"Self\",\"NotApplicable\")\r\n| extend Status= tostring(CmdletResultValue.Enabled)\r\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\"6\" , \"Delegating\", \"Regular\")\r\n| project Name,Role,RoleAssigneeName, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\r\n| sort by RoleAssigneeName asc\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "CmdletName",
                          "formatter": 0,
                          "formatOptions": {
                            "customColumnWidthSetting": "31.5ch"
                          }
                        },
                        {
                          "columnMatch": "Total",
                          "formatter": 0,
                          "formatOptions": {
                            "customColumnWidthSetting": "9.3ch"
                          }
                        },
                        {
                          "columnMatch": "Count",
                          "formatter": 21,
                          "formatOptions": {
                            "palette": "blue",
                            "customColumnWidthSetting": "330px"
                          }
                        },
                        {
                          "columnMatch": "Anomalies",
                          "formatter": 10,
                          "formatOptions": {
                            "palette": "redBright",
                            "customColumnWidthSetting": "330px"
                          }
                        }
                      ],
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "RoleAssigneeName",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "RoleAssigneeName",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Custom Delegations on User Accounts"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Custom Delegation on Groups",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays custom delegations set  on groups."
                  },
                  "name": "text - 2"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays all the nonstandard delegations done for standard and nonstandard groups. Indeed, default groups have a list of default delegations but an Exchange administrators can add also new roles to the default groups.\r\n\r\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\r\n\r\n\r\nUsual results :\r\n\r\n  - Delegations done for role group Organization Management to role like Mailbox Import Export or Mailbox Search (by default this delegation is not configured)\r\n\r\n  - Delegation done by mistake\r\n\r\n  - Suspicious delegations\r\n\r\nDetailed information for the user accounts present in the groups will be displayed in the sections below.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/view-effective-permissions-exchange-2013-help\" target=\"_blank\">View RBAC effective permissions</a>\r\n\r\n<a href=\"https://learn.microsoft.com/powershell/module/exchange/get-managementroleassignment?view=exchange-ps\" target=\"_blank\">Get-ManagementRoleAssignment</a>\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/understanding-role-based-access-control-exchange-2013-help \" target=\"_blank\">Understanding Role Based Access Control </a>\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "c548eb09-54e3-41bf-a99d-be3534f7018b",
                        "version": "KqlParameterItem/1.0",
                        "name": "RoleAssignee",
                        "type": 2,
                        "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"10\" or CmdletResultValue.RoleAssigneeType == \"2\" or CmdletResultValue.RoleAssigneeType == \"12\"\r\n| project CmdletResultValue\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| distinct RoleAssigneeName",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "rowLimit": 10000
                      },
                      {
                        "id": "4194717a-4a09-4c73-b02d-b1ac8587619d",
                        "version": "KqlParameterItem/1.0",
                        "name": "Role",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n|extend Role=tostring (CmdletResultValue.Role.Name)\r\n| distinct Role\r\n| sort by Role asc",
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 4"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nlet RoleG = ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| project RoleAssigneeName=tostring(CmdletResultValue.Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where  CmdletResultValue.RoleAssigneeName endswith  \"{RoleAssignee}\" \r\n| where  CmdletResultValue.Role.Name contains \"{Role}\"\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"10\" or CmdletResultValue.RoleAssigneeType == \"2\" or CmdletResultValue.RoleAssigneeType == \"12\"\r\n| extend Name = tostring(CmdletResultValue.Name)\r\n| extend Role = tostring(CmdletResultValue.Role.Name)\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\"12\", \"Yes\",\"No\")\r\n|lookup RoleG on RoleAssigneeName \r\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\"12\", \"Yes\",\"No\")\r\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\"6\" , \"Delegating\", \"Regular\")\r\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\r\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\r\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\"0\",\"None\",CmdletResultValue.RecipientWriteScope==\"2\",\"Organization\",CmdletResultValue.RecipientWriteScope==\"3\",\"MyGAL\", CmdletResultValue.RecipientWriteScope==\"4\",\"Self\",CmdletResultValue.RecipientWriteScope==\"7\", \"CustomRecipientScope\",CmdletResultValue.RecipientWriteScope==\"8\",\"MyDistributionGroups\",\"NotApplicable\")\r\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\r\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \"0\" , \"None\", \"OrganizationConfig\")\r\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\"2\",\"Organization\",CmdletResultValue.RecipientReadScope==\"3\",\"MyGAL\",CmdletResultValue.RecipientReadScope==\"4\",\"Self\",\"NotApplicable\")\r\n| extend Status= tostring(CmdletResultValue.Enabled)\r\n| project Name,Role,RoleAssigneeName,LinkedGroup, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\r\n| sort by RoleAssigneeName asc",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Custom Delegation on Groups"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "RBACDelegation"
      },
      "name": "Custom Delegation"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Information for Role Assignee",
        "items": [
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Information for Role Assignee User account",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "In the previous section, custom delegations for user have been displayed.\r\n\r\nThis section display detailed information for the accounts found in the previous. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\r\n\r\nSelect a user un the dropdown list.\r\n\r\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 366 days"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays details information for user accounts found with non standard delegations :\r\n  - Last logon\r\n  - Last Password changed\r\n  - Account enabled\r\n\r\nYou may find old service accounts that are no more used, or with a last password set very old...",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "27e4c2e9-d113-4bf9-808f-0f8f68b5152e",
                        "version": "KqlParameterItem/1.0",
                        "name": "RoleAssignee",
                        "type": 2,
                        "isRequired": true,
                        "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"0\"\r\n| project CmdletResultValue\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| distinct RoleAssigneeName",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      },
                      {
                        "id": "10c2eb2f-2cf2-4650-a9f1-3ee646acaebb",
                        "version": "KqlParameterItem/1.0",
                        "name": "LastLogon",
                        "label": "Last Logon",
                        "type": 10,
                        "isRequired": true,
                        "jsonData": "[ {\"value\": \"0d\", \"label\": \"No filter\",\"selected\":true},\r\n{ \"value\": \"90d\", \"label\": \"90d\" },\r\n    { \"value\": \"180d\", \"label\": \"6m\" },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1085d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]"
                      },
                      {
                        "id": "6f7128ee-2f2c-421d-bc9f-37aee85fb214",
                        "version": "KqlParameterItem/1.0",
                        "name": "PasswordLast",
                        "label": "Password Last Set",
                        "type": 10,
                        "isRequired": true,
                        "jsonData": "[{ \"value\": \"0d\", \"label\": \"No filter\",\"selected\":true },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1095d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 1"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"DirectRoleAssignments\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.SamAccountName contains \"{RoleAssignee}\"\r\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \"\"\r\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \"\"\r\n| project CmdletResultValue\r\n| extend ManagementRoleAssignment = tostring(CmdletResultValue.Parentgroup)\r\n| extend Account = tostring(CmdletResultValue.SamAccountName)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastLogon = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\"\", \"❌ Never logged\",strcat(\"❌\",LastLogon))))\r\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\r\n| extend LastPwdSet = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\",iif ( todatetime (CmdletResultValue.LastPwdSetString) >  ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\"\", \"❌ Password never set\",strcat(\"❌\",LastPwdSet))))\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| project-away  CmdletResultValue\r\n| sort by Account asc",
                    "size": 1,
                    "showAnalytics": true,
                    "color": "green",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "ManagementRoleAssignment",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "ManagementRoleAssignment",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Information for Role Assignee User account"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Information for Role Assignee group",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "Details information for Group delegation\r\nIn the previous section, custom delegations for groups have been displayed.\r\n\r\nThis section display detailed information for the accounts found in the group displayed in the previuos section. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\r\n\r\nSelect a group un the dropdown list.\r\n\r\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 366 days"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays details information for user accounts included in the found groups with non standard delegation : \r\n\r\n  - Last logon\r\n  - Last Password changed\r\n  - Account enabled\r\n\r\nYou may find old service accounts that are no more used, or with a last password set very old...",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "75c3cdf3-d0c3-46c3-83ae-429979774234",
                        "version": "KqlParameterItem/1.0",
                        "name": "RoleAssignee",
                        "type": 2,
                        "isRequired": true,
                        "query": "let DefMRA = externaldata (Name:string)[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/StandardMRA.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| summarize make_list(Name);\r\nExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \"10\" or CmdletResultValue.RoleAssigneeType == \"2\"\r\n| project CmdletResultValue\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| distinct RoleAssigneeName",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      },
                      {
                        "id": "1a3b374c-0467-4fd9-b2fc-edebd0a97302",
                        "version": "KqlParameterItem/1.0",
                        "name": "LastLogon",
                        "label": "Last Logon",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "jsonData": "[ {\"value\": \"0d\", \"label\": \"No filter\",\"selected\":true},\r\n{ \"value\": \"90d\", \"label\": \"90d\" },\r\n    { \"value\": \"180d\", \"label\": \"6m\" },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1085d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]"
                      },
                      {
                        "id": "170db194-195f-4991-b726-6c0658562616",
                        "version": "KqlParameterItem/1.0",
                        "name": "PasswordLast",
                        "type": 10,
                        "isRequired": true,
                        "jsonData": "[{ \"value\": \"0d\", \"label\": \"No filter\",\"selected\":true },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1095d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 1"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Parentgroup contains \"{RoleAssignee}\"\r\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \"\"\r\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \"\"\r\n| where CmdletResultValue.Level != 0\r\n| project CmdletResultValue\r\n| extend Level_ = tostring(CmdletResultValue.Level)\r\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastLogon = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\"\", \"❌ Never logged\",strcat(\"❌\",LastLogon))))\r\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\r\n| extend LastPwdSet = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\",iif ( todatetime (CmdletResultValue.LastPwdSetString) >  ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\"\", \"❌ Password never set\",strcat(\"❌\",LastPwdSet))))\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| project-away  CmdletResultValue, Level_,Parentgroup\r\n| sort by MemberPath asc",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Information for Role Assignee group"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "RBACDelegation"
      },
      "name": "Information for Role Assignee"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Linked Groups information",
        "items": [
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Information for Linked Groups",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "Display associated remote forest's  group for Linked Group"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"RoleGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where  CmdletResultValue.RoleGroupType == \"1\"\r\n//| extend ManagementRoleAssignment = tostring(CmdletResultValue.Name)\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.Name)\r\n| extend LinkedGroup = tostring(CmdletResultValue.LinkedGroup)\r\n//| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\"12\", \"Yes\",\"No\")\r\n//|lookup RoleG on RoleAssigneeName \r\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\"12\", \"Yes\",\"No\")\r\n| project RoleAssigneeName, LinkedGroup, WhenCreated, WhenChanged\r\n| sort by RoleAssigneeName asc",
                    "size": 1,
                    "showAnalytics": true,
                    "color": "green",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Information for Linked Groups"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "RBACDelegation"
      },
      "name": "Linked Groups information",
      "styleSettings": {
        "showBorder": true
      }
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "items": [
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let StandardGroup = dynamic([\"Compliance Management\", \"Delegated Setup\",\"Discovery Management\",\"Help Desk\",\"Hygiene Management\",\"Organization Management\",\"Public Folder Management\",\"Recipient Management\",\"Records Management\",\"Security Administrator\",\"Security Reader\",\"Server Management\",\"UM Management\",\"View-Only Organization Management\"]);\r\nExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Parentgroup in (StandardGroup)\r\n| project CmdletResultValue\r\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| summarize Total = count()-1 by Parentgroup\r\n| extend Comment = case (Total>0 and Parentgroup contains \"Discovery Management\", \"❌ This group should be empty Just in time should be used\", Total>5 and Parentgroup contains \"Organization Management\", \"❌ The content of this group should limited to only Level 3 Administrators\", Total>0 and Parentgroup contains \"Hygiene Management\", \"❌ This group should be empty or only contains Exchange server and/or Exchange antivirus Spam accounts\", \"Remember to regularly review the content of the group\")\r\n| sort by Parentgroup asc",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Numbers of members for high privileges groups",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "Explanations",
                    "expandable": true,
                    "items": [
                      {
                        "type": 1,
                        "content": {
                          "json": "All the default Exchange groups located in the default Exchange OU : Microsoft Exchange Security Groups are displayed with their number of members.\r\n\r\nIt is very important to monitor the content of Exchange groups and raise an alert when a new member is added.\r\n\r\nFor critical groups, a warning is display if the number exceeded a define thresold :\r\n  - Discovery Management: This group should be empty, so a warning is displayed when the group is not empty\r\n\r\n  - Organization Management : This group should only contain only Exchange expert. No service account should be member of this groupe. A warning is display when the total numer of member exceeded 5\r\n  - Hygiene Management : This group can acces and moidify the content of all mailboxes using EWS. A warning is display when the group is not empty. This warning can be ignored if the accounts are the Antispam service account or Exchange servers Computer accounts"
                        },
                        "name": "text - 0"
                      }
                    ]
                  },
                  "name": "group - 1"
                }
              ]
            },
            "name": "Summarize Number of Member Per Group"
          },
          {
            "type": 1,
            "content": {
              "json": "❌ : for last logon displayed when user logged or the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 366 days"
            },
            "name": "text - 3"
          },
          {
            "type": 9,
            "content": {
              "version": "KqlParameterItem/1.0",
              "parameters": [
                {
                  "id": "7c281d60-8434-4636-b85e-aef6296f1107",
                  "version": "KqlParameterItem/1.0",
                  "name": "LastLogon",
                  "label": "Last Logon",
                  "type": 10,
                  "isRequired": true,
                  "jsonData": "[ {\"value\": \"0d\", \"label\": \"No filter\",\"selected\":true},\r\n{ \"value\": \"90d\", \"label\": \"90d\" },\r\n    { \"value\": \"180d\", \"label\": \"6m\" },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1085d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]",
                  "timeContext": {
                    "durationMs": 86400000
                  }
                },
                {
                  "id": "e122a0de-1395-4002-96f9-cc057c257518",
                  "version": "KqlParameterItem/1.0",
                  "name": "PasswordLast",
                  "label": "Password Last Set",
                  "type": 10,
                  "isRequired": true,
                  "jsonData": "[{ \"value\": \"0d\", \"label\": \"No filter\",\"selected\":true },\r\n    { \"value\": \"365d\", \"label\": \"1y\" },\r\n{ \"value\": \"730d\", \"label\": \"2y\" },\r\n{ \"value\": \"1095d\", \"label\": \"3y\" },\r\n{ \"value\": \"1097d\", \"label\": \"more than 3y\"},\r\n{ \"value\": \"3650d\", \"label\": \"more than 10y\"}\r\n]",
                  "timeContext": {
                    "durationMs": 86400000
                  }
                }
              ],
              "style": "pills",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces"
            },
            "name": "parameters - 4"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let StandardGroup = dynamic([\"Compliance Management\", \"Delegated Setup\",\"Discovery Management\",\"Help Desk\",\"Hygiene Management\",\"Organization Management\",\"Public Folder Management\",\"Recipient Management\",\"Records Management\",\"Security Administrator\",\"Security Reader\",\"Server Management\",\"UM Management\",\"View-Only Organization Management\"]);\r\nExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Parentgroup in (StandardGroup)\r\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \"\"\r\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \"\"\r\n| project CmdletResultValue\r\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\r\n| where Level !=0\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastLogon = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\"\", \"❌ Never logged\",strcat(\"❌\",LastLogon))))\r\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\r\n| extend LastPwdSet = iif(ObjectClass==\"group\" or ObjectClass==\"computer\" or ObjectClass==\"Local User\" or ObjectClass==\"computer\",\"N/A\",iif ( todatetime (CmdletResultValue.LastPwdSetString) >  ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\"\", \"❌ Password never set\",strcat(\"❌\",LastPwdSet))))\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| project-away  CmdletResultValue\r\n| sort by MemberPath asc",
              "size": 3,
              "showAnalytics": true,
              "title": "Default Exchange groups content",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "$gen_group",
                    "formatter": 1
                  },
                  {
                    "columnMatch": "ParentGroup",
                    "formatter": 1
                  },
                  {
                    "columnMatch": "Parentgroup",
                    "formatter": 5
                  },
                  {
                    "columnMatch": "Group",
                    "formatter": 1
                  }
                ],
                "rowLimit": 10000,
                "filter": true,
                "hierarchySettings": {
                  "treeType": 1,
                  "groupBy": [
                    "Parentgroup"
                  ],
                  "finalBy": "Parentgroup"
                },
                "labelSettings": [
                  {
                    "columnId": "Parentgroup",
                    "label": "ParentGroup"
                  }
                ]
              }
            },
            "name": "query - 1",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Explanations",
              "expandable": true,
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section the content of the groups with details informations.\r\n\r\nIt is recommended to check the Last logon and last password change informations."
                  },
                  "name": "text - 0"
                }
              ]
            },
            "name": "group - 2"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "DefaultGroup"
      },
      "name": "group - 4"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Let start with Least Privileges with RBAC",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "# Workbook goals\r\nThe goals of this workbook is to show you the current RBAC delegation\r\n\r\n\r\nThis workbook will display :\r\n\r\n  - NonStandrd RBAC delegation\r\n\r\n  - Exchange default group content\r\n\r\n  - Analysis of the actions performed by Organization Management members to remove them from the groups\r\n\r\n----\r\n\r\n## Tabs\r\n\r\n### Current RBAC Delegation\r\n\r\nThis tab will show all the nonstandard RBAC delegation.\r\n\r\n**Most of the time RBAC are done and forgotten... This tab will provide a clear statut of the delegation and help with the remediation.**\r\n\r\nBy nonstandard, it means that the current delegation are compared to the delegation from Exchange 2019 CU11.\r\n\r\nNonstandard delegation for standard groups like Organization Management will also be displayed.\r\n\r\nDetail information for  found will be displayed : Last logon, last password changed...\r\n\r\n### Default Group content\r\n\r\nThis tab will show the number of members for default Exchange groups and their content.\r\n\r\nMost of the time, the content of common Exchange groups but Exchange is shipped with many groups that have very high privileges and its interesting to see that they are not empty as expected."
            },
            "name": "text - 0"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "start"
      },
      "name": "group - 6"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Custom Role details",
        "items": [
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "List of Custom Roles",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section shows the Custom management roles that exist in your environnment and the name of the parent's role"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Liste of existing Custom roles"
                  },
                  "customWidth": "50",
                  "name": "text - 5"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "List of Custom with a Management Role Assignement (associated with a group or a user). Display the target account and scope if set"
                  },
                  "customWidth": "50",
                  "name": "text - 6"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRCustom\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = CmdletResultValue.Name\r\n| extend ParentRole = CmdletResultValue.Parent.Name\r\n| extend WhenCreated = WhenCreated\r\n| project Identity, ParentRole, WhenCreated, WhenChanged",
                    "size": 0,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "customWidth": "50",
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Parent.Parent == \"Roles\"\r\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| extend Role = tostring(CmdletResultValue.Role.Name)\r\n//| extend Scope = tostring(CmdletResultValue.RecipientWriteScope)\r\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\r\n//| project Role = tostring(CmdletResultValue.Role.Name)\r\n| distinct Role,RoleAssigneeName,Scope\r\n| project Role,RoleAssigneeName,Scope",
                    "size": 1,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "customWidth": "50",
                  "name": "query - 4",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\"MRCustom\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project Role = tostring(CmdletResultValue.Name));\r\nExchangeConfiguration(SpecificSectionList=\"MRA\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Parent.Parent == \"Roles\"\r\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\r\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\r\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\r\n| project Role = tostring(CmdletResultValue.Role.Name), Scope, RoleAssigneeName\r\n| join  kind=fullouter (MRcustomRoles) on Role\r\n| project Role = Role1, Scope, RoleAssigneeName,Comment = iff(Role == \"\", \"⚠️ No existing delegation for this role\", \"✅ This role is delegated with a Management Role Assignment\")",
                    "size": 0,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "customWidth": "50",
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\"MRCustom\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n    | project Role = tostring(CmdletResultValue.Name));\r\nExchangeConfiguration(SpecificSectionList=\"MRA\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Parent.Parent == \"Roles\"\r\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\r\n| project Role = tostring(CmdletResultValue.Role.Name)\r\n| join  kind=fullouter (MRcustomRoles) on Role\r\n| summarize acount = count() by iff( Role==\"\",\"Number of non assigned roles\", Role)",
                    "size": 0,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "piechart"
                  },
                  "customWidth": "50",
                  "name": "query - 3"
                }
              ]
            },
            "name": "List of Custom Roles"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Custom Roles delegation on group",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section shows delegation associated with the Custom Roles"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Parent.Parent == \"Roles\"\r\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\r\n| extend Role = tostring(CmdletResultValue.Role.Name)\r\n| extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\r\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\r\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\r\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\"0\",\"None\",CmdletResultValue.RecipientWriteScope==\"2\",\"Organization\",CmdletResultValue.RecipientWriteScope==\"3\",\"MyGAL\", CmdletResultValue.RecipientWriteScope==\"4\",\"Self\",CmdletResultValue.RecipientWriteScope==\"7\", \"CustomRecipientScope\",CmdletResultValue.RecipientWriteScope==\"8\",\"MyDistributionGroups\",\"NotApplicable\")\r\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\r\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \"0\" , \"None\", \"OrganizationConfig\")\r\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\"2\",\"Organization\",CmdletResultValue.RecipientReadScope==\"3\",\"MyGAL\",CmdletResultValue.RecipientReadScope==\"4\",\"Self\",\"NotApplicable\")\r\n| extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\r\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\"6\" , \"Delegating\", \"Regular\") \r\n| extend RoleAssigneeName = iff( RoleAssigneeType == \"User\", strcat(\"🧑‍🦰 \",tostring(CmdletResultValue.RoleAssigneeName)), strcat(\"👪 \", tostring(CmdletResultValue.RoleAssigneeName)) )\r\n| project RoleAssigneeName, Role, RoleAssigneeType, CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 1"
                }
              ]
            },
            "name": "group - 2"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Details for Custom Roles Cmdlets ",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section displays for the chosen custom management roles all Cmdlets and their parameters associated with this custom role.\r\nRemember that for a cmdlet, some parameters can be removed."
                  },
                  "name": "text - 0"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "07c8ac83-371d-4702-ab66-72aeb2a20053",
                        "version": "KqlParameterItem/1.0",
                        "name": "CustomRole",
                        "type": 2,
                        "isRequired": true,
                        "query": " ExchangeConfiguration(SpecificSectionList=\"MRCustom\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = CmdletResultValue.Name\r\n| project Identity",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "timeContext": {
                          "durationMs": 86400000
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 2"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\"MRCustom\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = CmdletResultValue.Name\r\n| where Identity contains \"{CustomRole}\"\r\n| extend ParentRole = CmdletResultValue.Parent.Name\r\n| project ParentRole);\r\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/RBACRoleCmdlet.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by  Role;\r\nExchangeConfiguration(SpecificSectionList=\"MRCustomDetails\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")) contains \"{CustomRole}\"\r\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n| extend CmdletName = CmdletResultValue.Name\r\n| extend Parameters = CmdletResultValue.Parameters\r\n| project CmdletName,Parameters,ParentRole = SelectedRole",
                    "size": 1,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "Parameters",
                          "formatter": 0,
                          "formatOptions": {
                            "customColumnWidthSetting": "100ch"
                          }
                        }
                      ],
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "customWidth": "70",
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\"MRCustom\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = CmdletResultValue.Name\r\n| where Identity contains \"{CustomRole}\"\r\n| extend ParentRole = CmdletResultValue.Parent.Name\r\n| project ParentRole);\r\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/RBACRoleCmdlet.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by  Role;\r\nlet MRCustomD = ExchangeConfiguration(SpecificSectionList=\"MRCustomDetails\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")) contains \"{CustomRole}\"\r\n| extend Role = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n| extend CmdletName = CmdletResultValue.Name\r\n| extend ParentRole = tostring(SelectedRole)\r\n| summarize CmdletCount = count() by  Role, ParentRole\r\n| project Role,CmdletCount;\r\nunion MRCustomD, DefMRA",
                    "size": 0,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "piechart"
                  },
                  "customWidth": "30",
                  "name": "query - 3"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "List of Cmdlets ( Get- command have been removed to clarify the information) with :\r\nCustomParamCount : number of parameters for the Cmdlet in the custom role\r\nDefaultCmdletNumberofParam : number of parameters for the Cmdlet in the default role\r\n"
                  },
                  "name": "text - 5"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\"MRCustom\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = CmdletResultValue.Name\r\n| where Identity contains \"{CustomRole}\"\r\n| extend ParentRole = CmdletResultValue.Parent.Name\r\n| project ParentRole);\r\nlet DefMRA = externaldata (Role:string,Name:string,Parameters:string )[h\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/refs/heads/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/%23%20-%20General%20Content/Operations/Watchlists/RBACRoleCmdlet.csv\"]with(format=\"csv\",ignoreFirstRecord=true)| where Role == SelectedRole | mv-expand split(todynamic(Parameters),\";\")| summarize ParamCount = count() by  Name;\r\nExchangeConfiguration(SpecificSectionList=\"MRCustomDetails\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")) contains \"{CustomRole}\"\r\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\",\",0)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n| extend CmdletName = tostring(CmdletResultValue.Name)\r\n| where CmdletName !contains \"get-\"\r\n| extend Parameters = CmdletResultValue.Parameters\r\n| extend ParentRole = tostring(SelectedRole)\r\n| mv-expand split(todynamic(Parameters),\";\")\r\n| summarize ParamCount = count() by CmdletName, ParentRole\r\n| join (DefMRA) on $left.CmdletName == $right.Name\r\n| project CmdletName, CustomParamCount = ParamCount , DefaultCmdletNumberofParam = ParamCount1",
                    "size": 1,
                    "showAnalytics": true,
                    "timeContext": {
                      "durationMs": 86400000
                    },
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "DefaultCmdletNumberofParam",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "DefaultCmdletNumberofParam",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 4",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "Details for Custom Roles Cmdlets "
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "CustomRole"
      },
      "name": "Custom Role",
      "styleSettings": {
        "showBorder": true
      }
    }
  ],
  "fromTemplateId": "sentinel-MicrosoftExchangeLeastPrivilegewithRBAC",
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}