{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 1,
      "content": {
        "json": "# Microsoft Exchange Security Review"
      },
      "name": "text - 2"
    },
    {
      "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,
              "additionalResourceOptions": [],
              "showDefault": false
            },
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces",
            "value": []
          },
          {
            "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": {
              "additionalResourceOptions": [],
              "showDefault": false
            },
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          },
          {
            "id": "cfc36178-c5d7-4f69-87f5-b887e722f968",
            "version": "KqlParameterItem/1.0",
            "name": "Compare_Collect",
            "label": "CompareCollect",
            "type": 10,
            "description": "If this sesstion is checked, two collection will be compared",
            "isRequired": true,
            "typeSettings": {
              "additionalResourceOptions": [],
              "showDefault": false
            },
            "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":true }\r\n]"
          },
          {
            "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\"}\r\n",
            "timeContext": {
              "durationMs": 2592000000
            },
            "queryType": 8
          }
        ],
        "style": "above",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "TimeRange"
    },
    {
      "type": 9,
      "content": {
        "version": "KqlParameterItem/1.0",
        "parameters": [
          {
            "id": "0a7e59b0-755e-40c9-a4e0-ec7f516e991c",
            "version": "KqlParameterItem/1.0",
            "name": "DateCompare",
            "type": 2,
            "description": "This date must be older than the date configured in the Date of configuration",
            "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": {
              "additionalResourceOptions": [],
              "showDefault": false
            },
            "queryType": 0,
            "resourceType": "microsoft.operationalinsights/workspaces"
          }
        ],
        "style": "above",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "conditionalVisibility": {
        "parameterName": "Compare_Collect",
        "comparison": "isEqualTo",
        "value": "True"
      },
      "name": "TimeRange - Copy"
    },
    {
      "type": 1,
      "content": {
        "json": "This workbook helps review your Exchange Security configuration.\r\nSelect your Exchange Organization and adjust the time range.\r\n**By default, the Help won't be displayed. To display the help, choose Yes on the toogle buttom \"Show Help\"**\r\n\r\nTo compare collects, choose **Yes on the toogle buttom Compare Collect ** and choose the initial date.\r\nDepending on the section, a new table will be displayed with **all** the modifications (Add, Remove, Modifications) beetween the two dates.\r\nFor some sections, you'll see Add+Remove. This means that an account has been added and then removed during the choosen time range.\r\n\r\n**Important notes** : Some information are limited are may be not 100% accurate :\r\n  - Date\r\n  - When a fied is modified several times in the range, only first and last values will be displayed\r\n  - **Remove Time is displayed the date of the last collect and not the exact remove time**\r\n  - ... \r\n\r\nThis is due to some restrictions in the collect. The goal of the comparaison is to give you a global overview of the modifications between two collects.\r\nFor more details information, please check the workbook **\"Microsoft Exchange Search AdminAuditLog\"**\r\n.\r\n\r\nThe compare functionnality may not be available for all sections in this workbook.\r\n",
        "style": "info"
      },
      "name": "text - 9"
    },
    {
      "type": 11,
      "content": {
        "version": "LinkItem/1.0",
        "style": "tabs",
        "links": [
          {
            "id": "34188faf-7a02-4697-9b36-2afa986afc0f",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Mailbox Access",
            "subTarget": "Delegation",
            "postText": "t",
            "style": "link",
            "icon": "3",
            "linkIsContextBlade": true
          },
          {
            "id": "be02c735-6150-4b6e-a386-b2b023e754e5",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Exchange & AD Groups",
            "subTarget": "ExchAD",
            "style": "link"
          },
          {
            "id": "30dc6820-339d-4fa9-ad79-5d79816a5cab",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Local Administrators",
            "subTarget": "Server",
            "style": "link"
          },
          {
            "id": "571fa2a4-1f1e-44a2-ada0-ccfb31b9abbb",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Exchange Security Configuration",
            "subTarget": "SecConf",
            "style": "link"
          },
          {
            "id": "26c68d90-925b-4c3c-a837-e3cecd489b2d",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Transport Configuration",
            "subTarget": "Transport",
            "style": "link"
          },
          {
            "id": "eb2888ca-7fa6-4e82-88db-1bb3663a801e",
            "cellValue": "selected",
            "linkTarget": "parameter",
            "linkLabel": "Workbook Summary",
            "subTarget": "Start",
            "style": "link"
          }
        ]
      },
      "name": "TopMenuTabs"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "# Workbook goals\r\n\r\nThe goal of this workbook is to outline key security configurations of your Exchange On-Premises environment.\r\n\r\nMost of Exchange organizations have were installed years ago (sometimes more than 10 years). Many configurations have been done and might not have been documented. For most environments, the core commitment was maintaining a high availability of the users’ mailboxes putting aside other consideration (even security considerations). Recommended security practices have also evolved since the first released and a regular review is necessary.\r\n\r\nThis workbook is designed to show your Exchange organization is configured with a security point of view. Indeed, some configurations easy to display as there are no UI available.\r\n\r\nFor each configuration, you will find explanations and recommendations when applicable.\r\n\r\n- This workbook does not pretend to show you every weak Security configurations, but the most common issues and known to be used by attackers. \r\n- It will not show you if you have been comprised, but will help you identify unexpected configuration.\r\n\r\n----\r\n\r\n## Quick reminder of how Exchange works\r\n\r\nDuring Exchange installation two very important groups are created :\r\n- Exchange Trusted Subsystem : Contain all the computer accounts for Exchange Server\r\n- Exchange Windows Permissions : Contain the group Exchange trusted Subsystem\r\n\r\nThese groups have :\r\n- Very high privileges in ALL AD domains including the root domain\r\n- Right on any Exchange including mailboxes\r\n\r\nAs each Exchange server computer account is member of Exchange Trusted Subsystem, it means by taking control of the computer account or being System on an Exchange server you will gain access to all the permissions granted to Exchange Trusted Subsystem and Exchange Windows Permissions.\r\n\r\nTo protect AD and Exchange, it is very important to ensure the following:\r\n- There is a very limited number of persons that are local Administrator on Exchange server\r\n- To protect user right like : Act part of the operating System, Debug\r\n\r\nEvery service account or application that have high privileges on Exchange need to be considered as sensitive\r\n\r\n** 💡 Exchange servers need to be considered as very sensitive servers**\r\n\r\n-----\r\n\r\n\r\n## Tabs\r\n\r\n### Mailbox Access\r\n\r\nThis tab will show you several top sensitive delegations that allow an account to access, modify, act as another user, search, export the content of a mailbox.\r\n\r\n### Exchange & AD Groups\r\n\r\nThis tab will show you the members of Exchange groups and Sensitive AD groups.\r\n\r\n### Local Administrators\r\n\r\nThis tab will show you the non standard content of the local Administrators group. Remember that a member of the local Administrators group can take control of the computer account of the server and then it will have all the permissions associated with Exchange Trusted Subsytem and Exchange Windows Permissions\r\n\r\nThe information is displayed with different views : \r\n- List of nonstandard users\r\n- Number of servers with a nonstandard a user\r\n- Nonstandard groups content\r\n- For each user important information are displayed like last logon, last password set, enabled\r\n\r\n### Exchange Security configuration\r\n\r\nThis tab will show you some important configuration for your Exchange Organization\r\n- Status of Admin Audit Log configuration\r\n- Status of POP and IMAP configuration : especially, is Plaintext Authentication configured ?\r\n- Nonstandard permissions on the Exchange container in the Configuration Partition\r\n\r\n### Transport Configuration\r\n\r\nThis tab will show you the configuration of the main Transport components\r\n- Receive Connectors configured with Anonymous and/or Open Relay\r\n- Remote Domain Autoforward configuration\r\n- Transport Rules configured with BlindCopyTo, SendTo, RedirectTo\r\n- Journal Rule and Journal Recipient configurations\r\n- Accepted Domains with *\r\n\r\n"
            },
            "name": "WorkbookInfo"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "Start"
      },
      "name": "InformationTab"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Security Configuration for the Exchange Environment",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "This tab displays several security information regarding the organization or server's configuration."
            },
            "name": "text - 12"
          },
          {
            "type": 1,
            "content": {
              "json": "This section displays the Exchange version and the CU installed.\r\n\r\nFor the latest build number, check this link : <a href=\" https://docs.microsoft.com/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019\" target=\"_blank\">Exchange Build Numbers</a>\r\n\r\nThis section is built from a file located in the public GitHub repository.\r\nThe repository is manually updated by the team project when new CU/SU are released. ((Delay may happen between the release of a new CU/SU and the update of the file))\r\n",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "ServerVersionCheckHelp"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let ExchCUSU = externaldata (Productname:string, CU:string, SU:string, BuildNbAll:string, BuilCUNb:string, Major:string, CUBuildNb:string, SUBuildNb:string)[h\"https://aka.ms/ExchBuildNumber\"]with(format=\"csv\",ignoreFirstRecord=true)| project Productname,CU,SU,BuildNbAll,BuilCUNb,Major,CUBuildNb,SUBuildNb;\r\n//ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n//| extend  VersionNumber = strcat(CmdletResultValue.AdminDisplayVersion.Major,\".\",CmdletResultValue.AdminDisplayVersion.Minor,\".\",CmdletResultValue.AdminDisplayVersion.Build)\r\nExchangeConfiguration(SpecificSectionList=\"ExchVersion\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend  VersionNumber = tostring(CmdletResultValue.ProductVersion)\r\n| extend  Server = tostring(ProcessedByServer_s)\r\n| extend CmdletResultType = tostring(CmdletResultType)\r\n| join kind= leftouter  (ExchCUSU) on $left.VersionNumber == $right.BuildNbAll\r\n| distinct Server,VersionNumber,Productname,CU,SU,CmdletResultType\r\n| extend Server = strcat(\"💻 \",Server)\r\n| extend Productname = case ( VersionNumber startswith \"15.02\", \"Exchange 2019\", VersionNumber startswith \"15.01\", \"Exchange 2016\",  VersionNumber startswith \"15.00\",\"Exchange 2013\", \"Exchange 2010\")\r\n| extend CU = iff(CmdletResultType <>\"Success\", \"Unable to retrieve information from server\", iff(CU <> \"\", CU, \"New CU or SU not yet in the List\"))\r\n| extend SU = iff(CmdletResultType <>\"Success\", \"Unable to retrieve information from server\", iff( SU <> \"\", SU, \"New CU or SU not yet in the List\"))\r\n|project-away CmdletResultType\r\n| sort by Server asc\r\n",
              "size": 1,
              "showAnalytics": true,
              "title": "Exchange servers CU-SU level",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "rowLimit": 10000,
                "filter": true
              }
            },
            "customWidth": "50",
            "name": "ExchangeServersList",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let ExchCUSU = externaldata (Productname:string, CU:string, SU:string, BuildNbAll:string, BuilCUNb:string, Major:string, CUBuildNb:string, SUBuildNb:string)[h\"https://aka.ms/ExchBuildNumber\"]with(format=\"csv\",ignoreFirstRecord=true)| project Productname,CU,SU,BuildNbAll,BuilCUNb,Major,CUBuildNb,SUBuildNb;\r\nExchangeConfiguration(SpecificSectionList=\"ExchVersion\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n//| extend  VersionNumber = strcat(CmdletResultValue.AdminDisplayVersion.Major,\".\",CmdletResultValue.AdminDisplayVersion.Minor,\".\",CmdletResultValue.AdminDisplayVersion.Build)\r\n| extend  VersionNumber = tostring(CmdletResultValue.ProductVersion)\r\n| extend  Server = tostring(CmdletResultValue.Server)\r\n| join kind= leftouter  (ExchCUSU) on $left.VersionNumber == $right.BuildNbAll\r\n| extend CU = iff( CU <> \"\", CU, \"New CU/SU not yet in the CU List\")\r\n| extend Version =strcat (VersionNumber,\"-\",CU,\"-\",SU)\r\n| summarize dcount(Server) by Version",
              "size": 0,
              "showAnalytics": true,
              "title": "Version break down",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "piechart"
            },
            "customWidth": "50",
            "name": "ExchangeServerVersionPie"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Admin Audit Log configuration",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "The Admin Audit log stores all the actions performed on Exchange Servers (except Read actions such as Get/Test).\r\n\r\n<a href=\"https://learn.microsoft.com /exchange/policy-and-compliance/admin-audit-logging/admin-audit-logging?view=exchserver-2019\" target=\"_blank\">Admin Audit Log </a>\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/admin-audit-logging/manage-admin-audit-logging?view=exchserver-2019\" target=\"_blank\">Manage Admin Audit Log </a>\r\n\r\n\r\nThis can be used to track :\r\n- Unexpected behaviors\r\n- Who did a modification\r\n- Real actions performed by an account (the output could be used to identify the necessary privileges) and then reduce the privilege of the account by creating appropriate RBAC delegation\r\n\r\nℹ️ Recommendations\r\n- Ensure that Admin Audit Log is not disabled\r\n- Ensure that critical Cmdlets have not been excluded\r\n- Ensure that AdminAuditLogCmdlets is set to * (list of audited Cmdlets)\r\n- Review the retention configuration for the Admin Audit Log content",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "AdminAuditHelp"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Here the main settings for the Admin Audit Log. \r\nRemember that AdminAudit log needs to be enabled and no cmdlet should be excluded. Also check the retention limit."
                  },
                  "name": "text - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let SensitiveCMDLet = externaldata (Cmdlet:string, UserOriented:string, Parameters:string)[h\"https://aka.ms/CmdletWatchlist\"]with(format=\"csv\",ignoreFirstRecord=true)| project Cmdlet,UserOriented,Parameters;\r\nlet AAL = (ExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend AdminAuditLogExcludedCmdlets = CmdletResultValue.AdminAuditLogExcludedCmdlets\r\n| project AdminAuditLogExcludedCmdlets);\r\nlet SentsitivecmdletTrack = toscalar(SensitiveCMDLet | where Cmdlet has_any ( AAL)| project Cmdlet);\r\nExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| extend AdminAuditLogEnabled = iff(CmdletResultValue.AdminAuditLogEnabled == \"FALSE\", \" ❌ Disabled, High Risk\", \"✅ Enabled\")\r\n| extend AdminAuditLogAgeLimit = tostring(CmdletResultValue.AdminAuditLogAgeLimit)\r\n| extend AdminAuditLogAgeLimit = substring(AdminAuditLogAgeLimit,8)\r\n| extend AdminAuditLogAgeLimit =substring(AdminAuditLogAgeLimit,0,indexof(AdminAuditLogAgeLimit, ','))\r\n| extend AdminAuditLogAgeLimit = iff(toint(AdminAuditLogAgeLimit) == 0,strcat(\"❌ No AdminAuditlog recorded \",AdminAuditLogAgeLimit), iff(toint(AdminAuditLogAgeLimit) <=30,strcat(\"⚠️ Value to low except if exported \",AdminAuditLogAgeLimit), strcat(\"✅\",AdminAuditLogAgeLimit)))\r\n| extend AdminAuditLogCmdlets = tostring(CmdletResultValue.AdminAuditLogCmdlets)\r\n| extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets,2)\r\n| extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets,0,indexof(AdminAuditLogCmdlets, '\"]') )\r\n| extend AdminAuditLogCmdlets = replace_string(AdminAuditLogCmdlets,'\"',\"\")\r\n| extend Comment_AdminAuditLogCmdlets = iff( AdminAuditLogCmdlets == \"*\",\"✅ Default configuration\",\"❌ if AdminAuditLogCmdlets empty no logging else only AdminAuditLogCmdlets will be logged\")\r\n| extend AdminAuditLogExcludedCmdlets = tostring(CmdletResultValue.AdminAuditLogExcludedCmdlets)\r\n| extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets,2)\r\n| extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets,0,indexof(AdminAuditLogExcludedCmdlets, ']'))\r\n| extend AdminAuditLogExcludedCmdlets = replace_string(AdminAuditLogExcludedCmdlets,'\"',\"\")\r\n//| extend Cmdlet = replace_string(AdminAuditLogExcludedCmdlets,'\"',\"\")\r\n//| extend AALECSplit = tostring(split(AdminAuditLogExcludedCmdlets,\",\"))\r\n| project-away CmdletResultValue\r\n| extend Comment_AdminAuditLogExcludedCmdlet = case(  isnotempty( SentsitivecmdletTrack ),\"❌ Some excluded CmdLets are part of Sensitive Cmdlets\",AdminAuditLogExcludedCmdlets <>\"\",\"⚠️ Some Cmdlets are excluded \",\"✅ No Excluded CmdLet\")",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "Comment_AdminAuditLogCmdlets",
                          "formatter": 0,
                          "formatOptions": {
                            "customColumnWidthSetting": "70ch"
                          }
                        }
                      ],
                      "rowLimit": 10000,
                      "sortBy": [
                        {
                          "itemKey": "AdminAuditLogCmdlets",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "AdminAuditLogCmdlets",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let SensitiveCMDLet = externaldata (Cmdlet:string, UserOriented:string, Parameters:string)[h\"https://aka.ms/CmdletWatchlist\"]with(format=\"csv\",ignoreFirstRecord=true)| project Cmdlet,UserOriented,Parameters;\r\nlet AAL = (ExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend AdminAuditLogExcludedCmdlets = CmdletResultValue.AdminAuditLogExcludedCmdlets\r\n| project AdminAuditLogExcludedCmdlets);\r\nlet SentsitivecmdletTrack = toscalar(SensitiveCMDLet | where Cmdlet has_any ( AAL)| project Cmdlet);\r\nlet _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    | extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\n//let _CurrentDateB = todatetime(toscalar(_currD));\r\nlet _CurrentDateB =  datetime_add('day', 1, todatetime(toscalar(_currD)));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | extend AdminAuditLogAgeLimit = tostring(CmdletResultValue.AdminAuditLogAgeLimit)\r\n    | extend AdminAuditLogAgeLimit = substring(AdminAuditLogAgeLimit, 8)\r\n    | extend AdminAuditLogAgeLimit =substring(AdminAuditLogAgeLimit, 0, indexof(AdminAuditLogAgeLimit, ','))\r\n    | extend AdminAuditLogCmdlets = tostring(CmdletResultValue.AdminAuditLogCmdlets)\r\n    | extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets, 2)\r\n    | extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets, 0, indexof(AdminAuditLogCmdlets, '\"]'))\r\n    | extend AdminAuditLogCmdlets = replace_string(AdminAuditLogCmdlets, '\"', \"\")\r\n    | extend Comment_AdminAuditLogCmdlets = iff(AdminAuditLogCmdlets == \"*\", \"✅ Default configuration\", \"❌ if AdminAuditLogCmdlets empty no logging else only AdminAuditLogCmdlets will be logged\")\r\n    | extend AdminAuditLogExcludedCmdlets = tostring(CmdletResultValue.AdminAuditLogExcludedCmdlets)\r\n    | extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets, 2)\r\n    | extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets, 0, indexof(AdminAuditLogExcludedCmdlets, ']'))\r\n    | extend AdminAuditLogExcludedCmdlets = replace_string(AdminAuditLogExcludedCmdlets, '\"', \"\")\r\n    | project-away CmdletResultValue\r\n    | extend Comment_AdminAuditLogExcludedCmdlet = case(isnotempty(SentsitivecmdletTrack), \"❌ Some excluded CmdLets are part of Sensitive Cmdlets\", AdminAuditLogExcludedCmdlets <> \"\", \"⚠️ Some Cmdlets are excluded \", \"✅ No Excluded CmdLet\")\r\n    | extend WhenChanged = todatetime(WhenChanged)\r\n    | extend WhenCreated = todatetime(WhenCreated)\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"AdminAuditLog\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | extend AdminAuditLogAgeLimit = tostring(CmdletResultValue.AdminAuditLogAgeLimit)\r\n    | extend AdminAuditLogAgeLimit = substring(AdminAuditLogAgeLimit, 8)\r\n    | extend AdminAuditLogAgeLimit =substring(AdminAuditLogAgeLimit, 0, indexof(AdminAuditLogAgeLimit, ','))\r\n    | extend AdminAuditLogCmdlets = tostring(CmdletResultValue.AdminAuditLogCmdlets)\r\n    | extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets, 2)\r\n    | extend AdminAuditLogCmdlets = substring(AdminAuditLogCmdlets, 0, indexof(AdminAuditLogCmdlets, '\"]'))\r\n    | extend AdminAuditLogCmdlets = replace_string(AdminAuditLogCmdlets, '\"', \"\")\r\n    | extend Comment_AdminAuditLogCmdlets = iff(AdminAuditLogCmdlets == \"*\", \"✅ Default configuration\", \"❌ if AdminAuditLogCmdlets empty no logging else only AdminAuditLogCmdlets will be logged\")\r\n    | extend AdminAuditLogExcludedCmdlets = tostring(CmdletResultValue.AdminAuditLogExcludedCmdlets)\r\n    | extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets, 2)\r\n    | extend AdminAuditLogExcludedCmdlets = substring(AdminAuditLogExcludedCmdlets, 0, indexof(AdminAuditLogExcludedCmdlets, ']'))\r\n    | extend AdminAuditLogExcludedCmdlets = replace_string(AdminAuditLogExcludedCmdlets, '\"', \"\")\r\n    | project-away CmdletResultValue\r\n    | extend Comment_AdminAuditLogExcludedCmdlet = case(isnotempty(SentsitivecmdletTrack), \"❌ Some excluded CmdLets are part of Sensitive Cmdlets\", AdminAuditLogExcludedCmdlets <> \"\", \"⚠️ Some Cmdlets are excluded \", \"✅ No Excluded CmdLet\")\r\n    | extend WhenChanged = todatetime(WhenChanged)\r\n    | extend WhenCreated = todatetime(WhenCreated)\r\n;\r\nlet i=0;\r\nlet DiffModifData = union AfterData, BeforeData\r\n    | sort by WhenChanged asc \r\n    | project\r\n        WhenChanged,\r\n        AdminAuditLogAgeLimit,\r\n        AdminAuditLogCmdlets,\r\n        Comment_AdminAuditLogCmdlets,\r\n        AdminAuditLogExcludedCmdlets,\r\n        Comment_AdminAuditLogExcludedCmdlet,\r\n        WhenCreated\r\n    | extend AdminAuditLogAgeLimit = iff(AdminAuditLogAgeLimit != prev(AdminAuditLogAgeLimit) and prev(AdminAuditLogAgeLimit) != \"\", strcat(\"📍 \", AdminAuditLogAgeLimit, \" (\", prev(AdminAuditLogAgeLimit), \"->\", AdminAuditLogAgeLimit, \" )\"), AdminAuditLogAgeLimit)\r\n    | extend AdminAuditLogCmdlets = iff(AdminAuditLogCmdlets != prev(AdminAuditLogCmdlets) and prev(AdminAuditLogCmdlets) != \"\", strcat(\"📍 \", AdminAuditLogCmdlets, \" (\", prev(AdminAuditLogCmdlets), \"->\", AdminAuditLogCmdlets, \" )\"), AdminAuditLogCmdlets)\r\n    | extend Comment_AdminAuditLogCmdlets = iff(Comment_AdminAuditLogCmdlets != prev(Comment_AdminAuditLogCmdlets) and prev(Comment_AdminAuditLogCmdlets) != \"\", strcat(\"📍 \", Comment_AdminAuditLogCmdlets, \" (\", prev(Comment_AdminAuditLogCmdlets), \"->\", Comment_AdminAuditLogCmdlets, \" )\"), Comment_AdminAuditLogCmdlets)\r\n    | extend AdminAuditLogExcludedCmdlets = iff(AdminAuditLogExcludedCmdlets != prev(AdminAuditLogExcludedCmdlets) and prev(AdminAuditLogExcludedCmdlets) != \"\", strcat(\"📍 \", AdminAuditLogExcludedCmdlets, \" (\", prev(AdminAuditLogExcludedCmdlets), \"->\", AdminAuditLogExcludedCmdlets, \" )\"), AdminAuditLogExcludedCmdlets)\r\n    | extend Comment_AdminAuditLogExcludedCmdlet  = iff(Comment_AdminAuditLogExcludedCmdlet != prev(Comment_AdminAuditLogExcludedCmdlet) and prev(Comment_AdminAuditLogExcludedCmdlet) != \"\", strcat(\"📍 \", Comment_AdminAuditLogExcludedCmdlet, \" (\", prev(Comment_AdminAuditLogExcludedCmdlet), \"->\", Comment_AdminAuditLogExcludedCmdlet, \" )\"), Comment_AdminAuditLogExcludedCmdlet)\r\n    | extend ActiontypeR =iff(( AdminAuditLogAgeLimit  contains \"📍\" or AdminAuditLogCmdlets contains \"📍\" or Comment_AdminAuditLogCmdlets contains \"📍\" or AdminAuditLogExcludedCmdlets contains \"📍\" or Comment_AdminAuditLogExcludedCmdlet contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        AdminAuditLogAgeLimit,\r\n        AdminAuditLogCmdlets,\r\n        Comment_AdminAuditLogCmdlets,\r\n        AdminAuditLogExcludedCmdlets,\r\n        Comment_AdminAuditLogExcludedCmdlet,\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n    WhenChanged,\r\n    AdminAuditLogAgeLimit,\r\n    AdminAuditLogCmdlets,\r\n    Comment_AdminAuditLogCmdlets,\r\n    AdminAuditLogExcludedCmdlets,\r\n    Comment_AdminAuditLogExcludedCmdlet",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "AdminAuditLog settings comparaison",
                    "noDataMessage": "No modification",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 3"
                }
              ]
            },
            "name": "group - 0Admin Audit Log configuration"
          },
          {
            "type": 1,
            "content": {
              "json": "### POP authentication configuration"
            },
            "name": "text - 11"
          },
          {
            "type": 1,
            "content": {
              "json": "If the POP Service is started, the LoginType should not set to Plaintext. This means that the password will be sent in clear on the network. As POP is enabled by default on all the mailboxes, this represents a high security risk.\r\n\r\nPOP Authentication\r\n- **PlainText** TLS encryption is not required on port 110.  Usernames and passwords are sent unencrypted unless the underlying connection is encrypted by using TLS or SSL.\r\n- **PlainTextAuthentication** TLS encryption is not required on port 110. However, Basic authentication is permitted only on a port that uses TLS or SSL encryption.\r\n- **SecureLogin** Connection on port 110  must use TLS encryption before authenticating.\r\n\r\nℹ️ Recommendations\r\nDisable POP on all mailboxes except those which really need to use this protocol.\r\nSet the authentication to SecureLogin or at least to PlainTextAuthentication and configure the application.\r\n\r\nIf the application is not able to perform this type of authentication:\r\n- Ensure that POP is disabled on all the mailboxes except those who really need it \r\n- Monitor the POP connections\r\n- Change the password of the application on a regular basis\r\n\r\nRecommended Reading : \r\n\r\n<a href=\"https://technet.microsoft.com/library/aa997188(v=exchg.141).aspx \" target=\"_blank\">Configuring Authentication for POP3 and IMAP4</a>\r\n \r\n<a href=\"https://technet.microsoft.com/library/aa997154(v=exchg.160).aspx\" target=\"_blank\"> Set-PopSettings</a>\r\n\r\n\r\nIn order to track mailboxes that are currently using POP\r\n- Enable POP logging\r\n- Set-PopSettings -Server SRV1  -ProtocolLogEnabled verbose\r\n- Several weeks later, analyze the log content\r\n- Default location :    - Get-PopSettings -server SRV1 | fl server,*log*\r\n- Check for connection and authentication\r\n",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "PopServiceHelp"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "ExchangeConfiguration(SpecificSectionList=\"PopSettings\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n| join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name == (\"MSExchangePop3\")\r\n| project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n| join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name contains (\"MSExchangePop3BE\" )\r\n| project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n| extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n| extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n| extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n| extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n| extend Status =  tostring(Status)\r\n| extend BackendEndService=  tostring(ServiceName1)\r\n| extend StartupType =  tostring(StartupType)\r\n| extend BEStatus =  tostring(Status1)\r\n| extend BEStartupType =  tostring(StartupType1)\r\n| project ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n| sort by ServerName asc",
              "size": 1,
              "showAnalytics": true,
              "title": "Pop Authentication : should not be set as Plaintext",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "LoginType",
                    "formatter": 5
                  },
                  {
                    "columnMatch": "Count",
                    "formatter": 0,
                    "formatOptions": {
                      "aggregation": "Sum"
                    }
                  }
                ],
                "rowLimit": 10000,
                "filter": true,
                "hierarchySettings": {
                  "treeType": 1,
                  "groupBy": [
                    "LoginType"
                  ],
                  "finalBy": "LoginType"
                }
              }
            },
            "name": "PopSettingsQuery",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "POP settings comparaison",
              "items": [
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"PopSettings\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n| summarize TimeMax = arg_max(TimeGenerated,*)\r\n//| extend TimeMax = tostring(split(TimeMax,\"T\")[0])\r\n| project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\n//let _CurrentDateB =  datetime_add('day',1,todatetime(toscalar(_currD)));\r\nlet BeforeData = \r\n     ExchangeConfiguration(SpecificSectionList=\"PopSettings\",SpecificConfigurationDate=_DateCompareB,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_DateCompareB,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name == (\"MSExchangePop3\")\r\n    | project TimeGenerated,ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n    | join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_DateCompareB,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name contains (\"MSExchangePop3BE\" )\r\n    | project TimeGenerated,ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n    | extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n    | extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n    | extend Status =  tostring(Status)\r\n    | extend BackendEndService=  tostring(ServiceName1)\r\n    | extend StartupType =  tostring(StartupType)\r\n    | extend BEStatus =  tostring(Status1)\r\n    | extend BEStartupType =  tostring(StartupType1)\r\n    | project TimeGenerated,ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n    | sort by ServerName asc\r\n;\r\nlet AfterData = \r\n     ExchangeConfiguration(SpecificSectionList=\"PopSettings\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name == (\"MSExchangePop3\")\r\n    | project TimeGenerated,ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n    | join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name contains (\"MSExchangePop3BE\" )\r\n    | project TimeGenerated,ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n    | extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n    | extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n    | extend Status =  tostring(Status)\r\n    | extend BackendEndService=  tostring(ServiceName1)\r\n    | extend StartupType =  tostring(StartupType)\r\n    | extend BEStatus =  tostring(Status1)\r\n    | extend BEStartupType =  tostring(StartupType1)\r\n    | project TimeGenerated,ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n    | sort by ServerName asc\r\n;\r\nlet i=0;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by ServerName,TimeGenerated asc\r\n    | extend LoginType = iff(ServerName == prev(ServerName) and LoginType != prev(LoginType) and prev(LoginType) != \"\", strcat(\"📍 \", LoginType, \" (\", prev(LoginType), \"->\", LoginType, \" )\"), LoginType)\r\n    | extend ProtocolLogEnabled = iff(ServerName == prev(ServerName) and ProtocolLogEnabled != prev(ProtocolLogEnabled) and prev(ProtocolLogEnabled) != \"\", strcat(\"📍 \", ProtocolLogEnabled, \" (\", prev(ProtocolLogEnabled), \"->\", ProtocolLogEnabled, \" )\"), ProtocolLogEnabled)\r\n    | extend Status = iff( ServerName == prev(ServerName) and Status != prev(Status) and prev(Status) != \"\", strcat(\"📍 \", Status, \" (\", prev(Status), \"->\", Status, \" )\"), Status)\r\n    | extend StartupType = iff(ServerName == prev(ServerName) and StartupType != prev(StartupType) and prev(StartupType) != \"\", strcat(\"📍 \", StartupType, \" (\", prev(StartupType), \"->\", StartupType, \" )\"), StartupType)\r\n    | extend BEStatus  = iff(ServerName == prev(ServerName) and BEStatus != prev(BEStatus) and prev(BEStatus) != \"\", strcat(\"📍 \", BEStatus, \" (\", prev(BEStatus), \"->\", BEStatus, \" )\"), BEStatus)\r\n    | extend BEStartupType  = iff(ServerName == prev(ServerName) and BEStartupType != prev(BEStartupType) and prev(BEStartupType) != \"\", strcat(\"📍 \", BEStartupType, \" (\", prev(BEStartupType), \"->\", BEStartupType, \" )\"), BEStartupType)\r\n    | extend ActiontypeR =iff((LoginType contains \"📍\" or ProtocolLogEnabled contains \"📍\" or Status contains \"📍\" or StartupType contains \"📍\" or BEStatus contains \"📍\" or BEStartupType contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        TimeGenerated,\r\n        Actiontype,\r\n        ServerName,\r\n        LoginType,\r\n        ProtocolLogEnabled,\r\n        Status,\r\n        StartupType,\r\n        BEStatus,\r\n        BEStartupType\r\n;\r\nDiffModifData\r\n//| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| project\r\n    ServerName,\r\n    LoginType,\r\n    ProtocolLogEnabled,\r\n    Status,\r\n    StartupType,\r\n    BEStatus, \r\n    BEStartupType",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "Compare"
                }
              ]
            },
            "name": "POP authentication configuration"
          },
          {
            "type": 1,
            "content": {
              "json": "### IMAP authentication configuration"
            },
            "name": "IMAPTitle"
          },
          {
            "type": 1,
            "content": {
              "json": "If the IMAP Service is started, the LoginType should not set to Plaintext. This means that the passwords will be sent in clear over the network. As IMAP is enabled by default on all the mailboxes, this is a high security risk.\r\n\r\nIMAP Authentication\r\n- **PlainText** TLS encryption is not required on port 110.  User name and password are sent unencrypted unless the underlying connection is encrypted by using TLS or SSL.\r\n- **PlainTextAuthentication** TLS encryption is not required on port 143. However, Basic authentication is permitted only on a port that uses TLS or SSL encryption.\r\n- **SecureLogin** Connection on port 143 must use TLS encryption before authenticating.\r\n\r\nℹ️ Recommendations \r\nDisable IMAP on all mailboxes except those which really need to use this protocol. Set the authentication to SecureLogin or at least to PlainTextAuthentication and configure the application accordingly.\r\n\r\nIf the application is not able to perform this type of authentication:\r\n- Ensure that IMAP is disable on all the mailboxes except those who really need it \r\n- Monitor the connection\r\n- Regularly, change the password of the application\r\n\r\nRecommended Reading : \r\n\r\n<a href=\"https://technet.microsoft.com/library/aa997188(v=exchg.141).aspx \" target=\"_blank\">Configuring Authentication for POP3 and IMAP4</a>\r\n\r\n<a href=\"https://technet.microsoft.com/library/aa998252(v=exchg.160).aspx\" target=\"_blank\"> Set-IMAPSettings</a>\r\n\r\n\r\n\r\nIn order to track mailboxes that are currently using IMAP\r\n- Enable IMAP logging\r\n- Set-IMAPSettings -Server SRV1  -ProtocolLogEnabled verbose\r\n- Several weeks later, analyze the log content\r\n- Default location :  Get-IMAPSettings -server SRV1 | fl server,*log*\r\n- Check for connection and authentication\r\n",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "IMAPHelp"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "ExchangeConfiguration(SpecificSectionList=\"IMAPSettings\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n| join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name == (\"MSExchangeImap4\")\r\n| project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n| join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name contains (\"MSExchangeIMAP4BE\" )\r\n| project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n| extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n| extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n| extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n| extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n| extend Status =  tostring(Status)\r\n| extend BackendEndService=  tostring(ServiceName1)\r\n| extend StartupType =  tostring(StartupType)\r\n| extend BEStatus =  tostring(Status1)\r\n| extend BEStartupType =  tostring(StartupType1)\r\n| project ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n| sort by ServerName asc",
              "size": 1,
              "showAnalytics": true,
              "title": "IMAP Authentication  : should not be set as Plaintext",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "LoginType",
                    "formatter": 5
                  }
                ],
                "rowLimit": 10000,
                "filter": true,
                "hierarchySettings": {
                  "treeType": 1,
                  "groupBy": [
                    "LoginType"
                  ],
                  "finalBy": "LoginType"
                }
              }
            },
            "name": "IMAPSettingsQuery",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"IMAPSettings\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n| summarize TimeMax = arg_max(TimeGenerated,*)\r\n//| extend TimeMax = tostring(split(TimeMax,\"T\")[0])\r\n| project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\n//let _CurrentDateB =  datetime_add('day',1,todatetime(toscalar(_currD)));\r\nlet BeforeData = \r\n     ExchangeConfiguration(SpecificSectionList=\"IMAPSettings\",SpecificConfigurationDate=_DateCompareB,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name == (\"MSExchangeImap4\")\r\n    | project TimeGenerated,ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n    | join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name contains (\"MSExchangeIMAP4BE\" )\r\n    | project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n    | extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n    | extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n    | extend Status =  tostring(Status)\r\n    | extend BackendEndService=  tostring(ServiceName1)\r\n    | extend StartupType =  tostring(StartupType)\r\n    | extend BEStatus =  tostring(Status1)\r\n    | extend BEStartupType =  tostring(StartupType1)\r\n    | project TimeGenerated,ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n    | sort by ServerName asc\r\n;\r\nlet AfterData = \r\n     ExchangeConfiguration(SpecificSectionList=\"IMAPSettings\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | join kind = leftouter(ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name == (\"MSExchangeImap4\")\r\n    | project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString\r\n    | join (ExchangeConfiguration(SpecificSectionList=\"POPIMAPServicesStatus\",SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\r\n    | where CmdletResultValue.Name contains (\"MSExchangeIMAP4BE\" )\r\n    | project ServerName= tostring(CmdletResultValue.Server), ServiceName=CmdletResultValue.Name, Status=CmdletResultValue.StatusString,StartupType=CmdletResultValue.StartTypeString) on ServerName) on ServerName\r\n    | extend ServerName =  tostring(CmdletResultValue.Server.Name)\r\n    | extend LoginType =  iff(CmdletResultValue.LoginType== 1 , \"⛔ PlainText, High Risk\", iff(CmdletResultValue.LoginType== 2, \"⚠️ PlainTextAuthentication\",\"✅ SecureLogin\"))\r\n    | extend ProtocolLogEnabled =  tostring(CmdletResultValue.ProtocolLogEnabled)\r\n    | extend ServiceName =  iff(tostring(ServiceName)==\"\", \"Service Status not retrieved\",tostring(ServiceName))\r\n    | extend Status =  tostring(Status)\r\n    | extend BackendEndService=  tostring(ServiceName1)\r\n    | extend StartupType =  tostring(StartupType)\r\n    | extend BEStatus =  tostring(Status1)\r\n    | extend BEStartupType =  tostring(StartupType1)\r\n    | project TimeGenerated,ServerName,LoginType,ServiceName,Status,StartupType,BackendEndService,BEStatus,BEStartupType,ProtocolLogEnabled\r\n    | sort by ServerName asc\r\n;\r\nlet i=0;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by ServerName,TimeGenerated asc\r\n    | extend LoginType = iff(ServerName == prev(ServerName) and LoginType != prev(LoginType) and prev(LoginType) != \"\", strcat(\"📍 \", LoginType, \" (\", prev(LoginType), \"->\", LoginType, \" )\"), LoginType)\r\n    | extend ProtocolLogEnabled = iff(ServerName == prev(ServerName) and ProtocolLogEnabled != prev(ProtocolLogEnabled) and prev(ProtocolLogEnabled) != \"\", strcat(\"📍 \", ProtocolLogEnabled, \" (\", prev(ProtocolLogEnabled), \"->\", ProtocolLogEnabled, \" )\"), ProtocolLogEnabled)\r\n    | extend Status = iff( ServerName == prev(ServerName) and Status != prev(Status) and prev(Status) != \"\", strcat(\"📍 \", Status, \" (\", prev(Status), \"->\", Status, \" )\"), Status)\r\n    | extend StartupType = iff(ServerName == prev(ServerName) and StartupType != prev(StartupType) and prev(StartupType) != \"\", strcat(\"📍 \", StartupType, \" (\", prev(StartupType), \"->\", StartupType, \" )\"), StartupType)\r\n    | extend BEStatus  = iff(ServerName == prev(ServerName) and BEStatus != prev(BEStatus) and prev(BEStatus) != \"\", strcat(\"📍 \", BEStatus, \" (\", prev(BEStatus), \"->\", BEStatus, \" )\"), BEStatus)\r\n    | extend BEStartupType  = iff(ServerName == prev(ServerName) and BEStartupType != prev(BEStartupType) and prev(BEStartupType) != \"\", strcat(\"📍 \", BEStartupType, \" (\", prev(BEStartupType), \"->\", BEStartupType, \" )\"), BEStartupType)\r\n    | extend ActiontypeR =iff((LoginType contains \"📍\" or ProtocolLogEnabled contains \"📍\" or Status contains \"📍\" or StartupType contains \"📍\" or BEStatus contains \"📍\" or BEStartupType contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        Actiontype,\r\n        ServerName,\r\n        LoginType,\r\n        ProtocolLogEnabled,\r\n        Status,\r\n        StartupType,\r\n        BEStatus,\r\n        BEStartupType\r\n;\r\nDiffModifData\r\n//| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| project\r\n    ServerName,\r\n    LoginType,\r\n    ProtocolLogEnabled,\r\n    Status,\r\n    StartupType,\r\n    BEStatus, \r\n    BEStartupType",
              "size": 1,
              "showAnalytics": true,
              "title": "IMAP settings comparaison",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces"
            },
            "conditionalVisibility": {
              "parameterName": "Compare_Collect",
              "comparison": "isEqualTo",
              "value": "True"
            },
            "name": "Compare - Copy"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Nonstandard permissions on Configuration Partitions",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This section highlights nonstandard permissions on the Exchange container in the Configuration Partition. By selecting Yes for **Generic All** button, only delegations set to Generic All will be displayed. \r\nAlso Standard, Deny and inherited permissions have been removed"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "During the lifetime of an Exchange Organization, many permissions may have been set on Exchange containers in the Configuration Partition.\r\nThis section displayed all the nonstandard permissions found on the most important Exchange containers :\r\n - Groups from legacy Exchange versions (Exchange Enterprise Servers, Exchange Domain Servers,...)\r\n - SID for deleted accounts\r\n - Old service accounts (that may not have been disabled or removed...)\r\n \r\nWhen an administrator runs setup /PrepareAD, his account will be granted Generic All at the top-level Exchange container\r\n\r\nBy default, this section only displayed the **Generic All** permissions.\r\n \r\nThis section is built by removing all the standard AD and Exchange groups.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/exchange-2013-deployment-permissions-reference-exchange-2013-help\" target=\"_blank\"> Exchange 2013 deployment permissions reference</a>\r\n \r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "80f9134a-420f-47c9-b171-1ca8e72efa3e",
                        "version": "KqlParameterItem/1.0",
                        "name": "GenericAll",
                        "type": 10,
                        "isRequired": true,
                        "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":true }\r\n]"
                      },
                      {
                        "id": "29e2005c-3bd4-4bb8-be63-053d11abe1d4",
                        "version": "KqlParameterItem/1.0",
                        "name": "NonStandardPermissions",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\", \"selected\":true  },\r\n { \"value\": \"True,False\", \"label\": \"No\"}\r\n]"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 1"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let StandardGroup = dynamic([\"Authenticated Users\", \"Domain Admins\",  \"Enterprise Admins\",\"Schema Admins\", \"Exchange Trusted Subsystem\", \"Exchange Servers\",\"Organization Management\", \"Public Folder Management\",\"Delegated Setup\", \"ANONYMOUS LOGON\", \"NETWORK SERVICE\", \"SYSTEM\", \"Everyone\",\"Managed Availability Servers\"]);\r\nlet Exchsrv =ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")| summarize make_list(CmdletResultValue.Name);\r\nExchangeConfiguration(SpecificSectionList=\"PartConfPerm\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.Deny !contains \"True\" and CmdletResultValue.IsInherited !contains \"True\"\r\n| where (CmdletResultValue.AccessRights == \"[983551]\") in ({GenericAll})\r\n| where not (CmdletResultValue.UserString has_any (StandardGroup)) in ({NonStandardPermissions})\r\n| where not (CmdletResultValue.UserString has_any (Exchsrv))in ({NonStandardPermissions})\r\n| extend Name =  tostring(CmdletResultValue.Identity.Name)\r\n| extend Account =  tostring(CmdletResultValue.UserString )\r\n| extend AccessRights =  iff (tostring(CmdletResultValue.AccessRightsString) contains \"GenericAll\", strcat (\"❌ \",tostring(CmdletResultValue.AccessRightsString)), tostring(CmdletResultValue.AccessRightsString))\r\n| extend ExtendedRights =   iff (tostring(CmdletResultValue.ExtendedRightsString) contains \"-As\", strcat (\"❌ \",tostring(CmdletResultValue.ExtendedRightsString)), tostring(CmdletResultValue.ExtendedRightsString))\r\n| extend InheritanceType =  tostring(CmdletResultValue.InheritanceType)\r\n| extend DN = tostring(CmdletResultValue.Identity.DistinguishedName)\r\n| project-away CmdletResultValue\r\n| sort by DN desc",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "DN",
                          "sortOrder": 2
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "DN",
                        "sortOrder": 2
                      }
                    ]
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let StandardGroup = dynamic([\"Authenticated Users\", \"Domain Admins\", \"Enterprise Admins\", \"Schema Admins\", \"Exchange Trusted Subsystem\", \"Exchange Servers\", \"Organization Management\", \"Public Folder Management\", \"Delegated Setup\", \"ANONYMOUS LOGON\", \"NETWORK SERVICE\", \"SYSTEM\", \"Everyone\", \"Managed Availability Servers\"]);\r\nlet Exchsrv =ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\", SpecificConfigurationDate=\"lastdate\", SpecificConfigurationEnv='B119E5', Target = \"On-Premises\")\r\n    | summarize make_list(CmdletResultValue.Name);\r\nlet _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"PartConfPerm\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"PartConfPerm\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated, CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | where CmdletResultValue.Deny !contains \"True\" and CmdletResultValue.IsInherited !contains \"True\"\r\n    | where (CmdletResultValue.AccessRights == \"[983551]\") in (True, False)\r\n    | where not (CmdletResultValue.UserString has_any (StandardGroup)) in (True)\r\n    | where not (CmdletResultValue.UserString has_any (Exchsrv))in (True)\r\n    | extend Name =  tostring(CmdletResultValue.Identity.Name)\r\n    | extend Account =  tostring(CmdletResultValue.UserString )\r\n    | extend AccessRights =  iff (tostring(CmdletResultValue.AccessRightsString) contains \"GenericAll\", strcat (\"❌ \",tostring(CmdletResultValue.AccessRightsString)), tostring(CmdletResultValue.AccessRightsString))\r\n    | extend ExtendedRights =   iff (tostring(CmdletResultValue.ExtendedRightsString) contains \"-As\", strcat (\"❌ \",tostring(CmdletResultValue.ExtendedRightsString)), tostring(CmdletResultValue.ExtendedRightsString))\r\n    | extend InheritanceType =  tostring(CmdletResultValue.InheritanceType)\r\n    | extend DN = tostring(CmdletResultValue.Identity.DistinguishedName)\r\n    | extend AllInfo = strcat(Name,Account,CmdletResultValue.AccessRightsString,CmdletResultValue.ExtendedRightsString)\r\n    | project-away CmdletResultValue\r\n    | sort by Name,Account  desc\r\n;\r\nlet AlldataUnique = allDataRange\r\n    | join kind = innerunique     (allDataRange) on AllInfo   \r\n    | distinct \r\n         Name, \r\n         Account, \r\n         AccessRights, \r\n         ExtendedRights, \r\n         InheritanceType, \r\n         DN,\r\n         AllInfo\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"PartConfPerm\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue.Deny !contains \"True\" and CmdletResultValue.IsInherited !contains \"True\"\r\n    | where (CmdletResultValue.AccessRights == \"[983551]\") in (True, False)\r\n    | where not (CmdletResultValue.UserString has_any (StandardGroup)) in (True)\r\n    | where not (CmdletResultValue.UserString has_any (Exchsrv))in (True)\r\n    | extend Name =  tostring(CmdletResultValue.Identity.Name)\r\n    | extend Account =  tostring(CmdletResultValue.UserString )\r\n    | extend AccessRights =  iff (tostring(CmdletResultValue.AccessRightsString) contains \"GenericAll\", strcat (\"❌ \",tostring(CmdletResultValue.AccessRightsString)), tostring(CmdletResultValue.AccessRightsString))\r\n    | extend ExtendedRights =   iff (tostring(CmdletResultValue.ExtendedRightsString) contains \"-As\", strcat (\"❌ \",tostring(CmdletResultValue.ExtendedRightsString)), tostring(CmdletResultValue.ExtendedRightsString))\r\n    | extend InheritanceType =  tostring(CmdletResultValue.InheritanceType)\r\n    | extend DN = tostring(CmdletResultValue.Identity.DistinguishedName)\r\n    | extend AllInfo = strcat(Name,Account,CmdletResultValue.AccessRightsString,CmdletResultValue.ExtendedRightsString)\r\n    | project-away CmdletResultValue\r\n    | sort by Name,Account  desc\r\n    ;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"PartConfPerm\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue.Deny !contains \"True\" and CmdletResultValue.IsInherited !contains \"True\"\r\n    | where (CmdletResultValue.AccessRights == \"[983551]\") in (True, False)\r\n    | where not (CmdletResultValue.UserString has_any (StandardGroup)) in (True)\r\n    | where not (CmdletResultValue.UserString has_any (Exchsrv))in (True)\r\n    | extend Name =  tostring(CmdletResultValue.Identity.Name)\r\n    | extend Account =  tostring(CmdletResultValue.UserString )\r\n    | extend AccessRights =  iff (tostring(CmdletResultValue.AccessRightsString) contains \"GenericAll\", strcat (\"❌ \",tostring(CmdletResultValue.AccessRightsString)), tostring(CmdletResultValue.AccessRightsString))\r\n    | extend ExtendedRights =   iff (tostring(CmdletResultValue.ExtendedRightsString) contains \"-As\", strcat (\"❌ \",tostring(CmdletResultValue.ExtendedRightsString)), tostring(CmdletResultValue.ExtendedRightsString))\r\n    | extend InheritanceType =  tostring(CmdletResultValue.InheritanceType)\r\n    | extend DN = tostring(CmdletResultValue.Identity.DistinguishedName)\r\n    | extend AllInfo = strcat(Name,Account,CmdletResultValue.AccessRightsString,CmdletResultValue.ExtendedRightsString)\r\n    | project-away CmdletResultValue\r\n    | sort by Name,Account desc\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n    | join kind = leftanti  (AfterData) on AllInfo\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n    | join kind = innerunique    (BeforeData) on AllInfo\r\n    | extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n    | join kind = leftanti    (InBeforedatabotAfter) on AllInfo\r\n    | extend Actiontype =\"Add/Remove\"\r\n    | project         \r\n        Actiontype,\r\n        Name, \r\n        Account, \r\n        AccessRights, \r\n        ExtendedRights, \r\n        InheritanceType, \r\n        DN \r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on AllInfo\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData, AddRemoveindataset, InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype), \"N/A\")\r\n| project\r\n    Actiontype,\r\n    Name, \r\n    Account, \r\n    AccessRights, \r\n    ExtendedRights, \r\n    InheritanceType, \r\n    DN ",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Compare NonStandard Permissions for Exchange Container in the Configuration Partition",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "Compare - Copy - Copy"
                }
              ]
            },
            "name": "Nonstandard permissions on Configuration Partitions"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "SecConf"
      },
      "name": "Security Configuration for the Exchange environment"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "This tab displays important security configurations that allow access to all or partial mailboxes' content  - Direct delegations are not listed -  Example : <br>\r\n- Permissions Full Access  \r\n- Permission on mailboxes folders\r\n"
            },
            "name": "text - 6"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.RoleAssignmentDelegationType !=\"6\" \r\n| where CmdletResultValue.RoleAssigneeName !in (\"Hygiene Management\",\"Exchange Online-ApplicationAccount\",\"Discovery Management\")\r\n| where CmdletResultValue.Role.Name == \"Mailbox Import Export\" or CmdletResultValue.Role.Name == \"ApplicationImpersonation\" or (CmdletResultValue.Role.Name == \"Mailbox Search\")\r\n| summarize dcount(tostring(CmdletResultValue.RoleAssigneeName)) by role=tostring(CmdletResultValue.Role.Name)",
              "size": 1,
              "showAnalytics": true,
              "title": "Number of delegations for sensitive RBAC roles",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "role",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "dcount_CmdletResultValue_RoleAssigneeName",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  },
                  "numberFormat": {
                    "unit": 17,
                    "options": {
                      "style": "decimal",
                      "maximumFractionDigits": 2,
                      "maximumSignificantDigits": 3
                    }
                  }
                },
                "showBorder": true,
                "sortCriteriaField": "role",
                "sortOrderField": 1
              }
            },
            "name": "MRAQuery"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Application Impersonation Role",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This delegation allows the delegated accounts to access and modify the content of every mailboxes using EWS.\r\nExcluded from the result as default configuration :\r\n- The Delegating delegation for this role assigned to Organization Management\r\n- Hygiene Management group as it is a default delegation"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**ApplicationImpersonation** is a RBAC role that allows access (read and modify) to the content of all mailboxes using EWS. \r\n\r\n⚡ This role is very powerfull.\r\n\r\nIt should be carefully delegated. When a delegation is necessary, RBAC scopes should be configured to limit the list of impacted mailboxes.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/applicationimpersonation-role-exchange-2013-help\" target=\"_blank\">Help for the role Application Impersonation</a>\r\n\r\nIt is common (but not recommended) to see service accounts from backup solution, antivirus software, MDM... with this delegation.\r\nThese service accounts should be closely monitored and the security of the server where they are running needs to be at the same level of Exchange servers.\r\nNote that the default configuration to the group Hygiene Management is excluded. This group is a sensitive group. Remember to monitor the content of this group.",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 2"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList})\r\n| where CmdletResultValue.Role.Name == \"ApplicationImpersonation\" and CmdletResultValue.RoleAssigneeName != \"Hygiene Management\" and CmdletResultValue.RoleAssignmentDelegationType !=\"6\" \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 Status= tostring(CmdletResultValue.Enabled)\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, RoleAssigneeType, Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "RoleAssignmentDelegationType",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "RoleAssignmentDelegationType",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let ExclusionsAcctValue = dynamic([\"Hygiene Management\", \"RIM-MailboxAdmins\"]);\r\nMESCompareDataOnPMRA(SectionCompare=\"MRA\",DateCompare=\"{DateCompare:value}\",CurrentDate = \"{DateOfConfiguration:value}\",EnvList ={EnvironmentList},TypeEnv = \"On-Premises\",ExclusionsAcct = ExclusionsAcctValue ,CurrentRole=\"Impersonation\")",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 1 - Copy",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**Remove Time is displayed the date of the last collect and not the exact remove time**"
                  },
                  "name": "text - 4"
                }
              ]
            },
            "name": "Application Impersonation Role"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Mailbox Import Export Role",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This delegation allows to export the content all  mailboxes in a scope in PST file.\r\nExcluded from the result as default configuration :\r\nDelegating delegation to Organization Management\r\n"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**Mailbox Import Export**  is a RBAC role that allows an account to export the content of any maibox in a PST. It also allows the delegated account to perform searches in all mailboxes.\r\n\r\n⚡ This role is very powerfull.\r\n\r\nBy default, this role is not delegated to any user or group. The members of the group Organization Management by default do not have this role but are able to delegate it.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/mailbox-import-export-role-exchange-2013-help\" target=\"_blank\">Help for the role Mailbox Import Export</a>\r\n\r\nℹ️ Recommendations\r\n\r\nIf you temporarily need this delegation, consider the following:\r\n- Create an empty group with this delegation\r\n- Monitor the group content and  alert when the group content  is modified\r\n- Add administrators in this group only for a short period of time\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "ExportRoleHelp"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Name == \"Mailbox Import Export\" and CmdletResultValue.RoleAssignmentDelegationType !=\"6\" \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 Status= tostring(CmdletResultValue.Enabled)\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, RoleAssigneeType,Status, CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "ConfigWriteScope",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "ConfigWriteScope",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let ExclusionsAcctValue = dynamic([\"Hygiene Management\", \"RIM-MailboxAdmins\"]);\r\nMESCompareDataOnPMRA(SectionCompare=\"MRA\",DateCompare=\"{DateCompare:value}\",CurrentDate = \"{DateOfConfiguration:value}\",EnvList ={EnvironmentList},TypeEnv = \"On-Premises\",ExclusionsAcct = ExclusionsAcctValue ,CurrentRole=\"export\")",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**Remove Time is displayed the date of the last collect and not the exact remove time**"
                  },
                  "name": "text - 4"
                }
              ]
            },
            "name": "Mailbox Import Export Role"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Mailbox Search Role",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This delegation allows the delegated account to search inside all or in a scope of mailboxes and export the result in PST.\r\nExcluded from the result as default configuration :\r\n- The Delegating delegation for this role assigned to Organization Management\r\n- Delegation for the account Exchange Online-Application\r\n- Delegation for the group Discovery Management \r\n"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**Mailbox Search** is an RBAC role that allows an account to search in any mailbox and export the results to a PST.\r\n\r\n⚡ This role is very powerful.\r\n\r\nBy default, this role is only delegated to the group Discovery Management. The members of the group Organization Management do not have this role but are able to delegate it.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/mailbox-search-role-exchange-2013-help\" target=\"_blank\">Help for the role Mailbox Search</a>\r\n\r\nℹ️ Recommendations\r\n\r\nIf you temporarily need this delegation, consider the following:\r\n\r\n- Temporarily add the administrators in the Discovery Management group\r\n- Monitor the group content and alert when the group is modified\r\n- Add administrators in this group only for a short period of time\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "SearchRBACHelp"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MRA\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Role.Name == \"Mailbox Search\" and CmdletResultValue.RoleAssignmentDelegationType !=\"6\" \r\n| where CmdletResultValue.RoleAssigneeName != \"Exchange Online-ApplicationAccount\" and CmdletResultValue.RoleAssigneeName != \"Discovery Management\"\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 Status= tostring(CmdletResultValue.Enabled)\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, RoleAssigneeType, Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "ConfigWriteScope",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "ConfigWriteScope",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let ExclusionsAcctValue = dynamic([\"Hygiene Management\", \"RIM-MailboxAdmins\"]);\r\nMESCompareDataOnPMRA(SectionCompare=\"MRA\",DateCompare=\"{DateCompare:value}\",CurrentDate = \"{DateOfConfiguration:value}\",EnvList ={EnvironmentList},TypeEnv = \"On-Premises\",ExclusionsAcct = ExclusionsAcctValue ,CurrentRole=\"Search\")",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 1,
                  "content": {
                    "json": "**Remove Time is displayed the date of the last collect and not the exact remove time**"
                  },
                  "name": "text - 4"
                }
              ]
            },
            "name": "Mailbox Search Role"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "ReceiveAs/SendAs  Extended Right on databases",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "These sections display delegations at the database level (the database Object, not the container) ..\r\n\r\n**Receive As Extended Right on database's objects in the Configuration**\r\n\r\nWhen an account has **ReceiveAs** permissions on a database's object, it can open and view the content of any mailboxes on that database.\r\n\r\n<a href=\"https://technet.microsoft.com/library/bb123879(v=exchg.80).aspx\" target=\"_blank\">Help for Receive As Permission</a>\r\n\r\n\r\nℹ️ Recommendations\r\n\r\nDo not set this permission on databases. When an application requires this permission, ensure that the application account’s password is well protected and known by a very limited number of person. This account should be closely monitored and the security of the server where it is running needs to be at the same level of Exchange servers.\r\nChange the password as often as possible.\r\n\r\n**Send As Extended Right on database objects in the Configuration**\r\n\r\n\r\nWhen an account has **SendAs** permissions on a database's object, it can send messages from all the mailboxes contained in this database. The messages that are sent from a mailbox will appear as if the mailbox owner sent them.\r\n\r\n<a href=\"https://technet.microsoft.com/ library/bb123879(v=exchg.80).aspx\" target=\"_blank\">Help for Send As Permission</a>\r\n\r\n\r\nℹ️ Recommendations\r\n\r\nDo not set this permission on databases. When an application requires this permission, ensure that the application account’s password is well protected and known by a very limited number of person.\r\nThis account should be closely monitored and the security of the server where it is running needs to be at the same level of Exchange servers. \r\nChange the password as often as possible.\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "SendAsHelp"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "eb0af112-df51-47f5-8849-b3ee764fa72d",
                        "version": "KqlParameterItem/1.0",
                        "name": "IsInherited",
                        "label": "Included Inherited deleg",
                        "type": 10,
                        "description": "Yes Show all the delegations (Databases object and Database Containers), No only databases objects",
                        "isRequired": true,
                        "typeSettings": {
                          "additionalResourceOptions": [],
                          "showDefault": false
                        },
                        "jsonData": "[\r\n { \"value\": \"false\", \"label\": \"No\" , \"selected\":true },\r\n { \"value\": \"true, false\", \"label\": \"Yes\"}\r\n]",
                        "timeContext": {
                          "durationMs": 86400000
                        },
                        "value": "true, false"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 7"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| union ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n| where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n| summarize dcount(tostring(CmdletResultValue.UserString)) by iff( tostring(Section) contains \"MailboxDatabaseReceiveAs\",\"ReceiveAs Unique Acct\",\"SendAs Unique Acct\")",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Number of accounts with ReceiveAs/SendAs delegations",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "tiles",
                    "tileSettings": {
                      "titleContent": {
                        "columnMatch": "Column1",
                        "formatter": 1
                      },
                      "leftContent": {
                        "columnMatch": "dcount_CmdletResultValue_UserString",
                        "formatter": 12,
                        "formatOptions": {
                          "palette": "auto"
                        },
                        "numberFormat": {
                          "unit": 17,
                          "options": {
                            "style": "decimal",
                            "maximumFractionDigits": 2,
                            "maximumSignificantDigits": 3
                          }
                        }
                      },
                      "showBorder": true,
                      "sortCriteriaField": "Column1",
                      "sortOrderField": 1
                    }
                  },
                  "customWidth": "50",
                  "name": "ReceiveAsUsersTiles"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| union ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n| where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n| summarize dcount(tostring(CmdletResultValue.Identity.Name)) by iff( tostring(Section) contains \"MailboxDatabaseReceiveAs\",\"ReceiveAs Unique DB\",\"SendAs Unique DB\")",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Databases with ReceiveAs/SendAs delegations",
                    "color": "purple",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "tiles",
                    "tileSettings": {
                      "titleContent": {
                        "columnMatch": "Column1",
                        "formatter": 1
                      },
                      "leftContent": {
                        "columnMatch": "dcount_CmdletResultValue_Identity_Name",
                        "formatter": 12,
                        "formatOptions": {
                          "palette": "auto"
                        },
                        "numberFormat": {
                          "unit": 17,
                          "options": {
                            "style": "decimal",
                            "maximumFractionDigits": 2,
                            "maximumSignificantDigits": 3
                          }
                        }
                      },
                      "showBorder": true,
                      "sortCriteriaField": "Column1",
                      "sortOrderField": 1
                    }
                  },
                  "customWidth": "50",
                  "name": "ReceiveAsTiles",
                  "styleSettings": {
                    "margin": "25"
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n| where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n| extend Account = tostring(CmdletResultValue.UserString)\r\n| extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n| extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n| summarize Count =count() by Account,DatabaseName,IsInherited\r\n| project Account,Count,DatabaseName,IsInherited\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "ReceiveAs Extended Right on databases",
                    "noDataMessage": "No Receive-As delegation",
                    "noDataMessageStyle": 3,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "Account",
                          "formatter": 5
                        },
                        {
                          "columnMatch": "Count",
                          "formatter": 8,
                          "formatOptions": {
                            "palette": "blue",
                            "aggregation": "Sum"
                          }
                        }
                      ],
                      "rowLimit": 10000,
                      "filter": true,
                      "hierarchySettings": {
                        "treeType": 1,
                        "groupBy": [
                          "Account"
                        ],
                        "finalBy": "Account"
                      },
                      "sortBy": [
                        {
                          "itemKey": "$gen_count_$gen_group_0",
                          "sortOrder": 1
                        }
                      ],
                      "labelSettings": [
                        {
                          "columnId": "Account",
                          "comment": "Account and the number of databases on which it has delegation "
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "$gen_count_$gen_group_0",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "customWidth": "50",
                  "name": "MailboxDatabaseReceiveAsGrid",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n| where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n| extend Account = tostring(CmdletResultValue.UserString)\r\n| extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n| extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n| summarize Count =count() by Account,DatabaseName,IsInherited\r\n| project Account,Count,DatabaseName,IsInherited",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "SendAs Extended Right on databases",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "Account",
                          "formatter": 5
                        }
                      ],
                      "filter": true,
                      "hierarchySettings": {
                        "treeType": 1,
                        "groupBy": [
                          "Account"
                        ],
                        "finalBy": "Account"
                      }
                    }
                  },
                  "customWidth": "50",
                  "name": "SendAs Extended Right on databases",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"MailboxDatabaseReceiveAs\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated, CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n        | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n    | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n    | extend Account = tostring(CmdletResultValue.UserString)\r\n    | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n    | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n    | extend Allinfo = strcat(Account,DatabaseName)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Account\r\n;\r\nlet AlldataUnique = allDataRange\r\n    | join kind = innerunique     (allDataRange) on Allinfo   \r\n    | distinct \r\n    Account,\r\n    DatabaseName,\r\n    IsInherited,\r\n    Allinfo\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n    | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n    | extend Account = tostring(CmdletResultValue.UserString)\r\n    | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n    | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n    | extend Allinfo = strcat(Account,DatabaseName)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Account\r\n    ;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseReceiveAs\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n        | project CmdletResultValue\r\n        | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n        | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n        | extend Account = tostring(CmdletResultValue.UserString)\r\n        | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n        | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n        | extend Allinfo = strcat(Account,DatabaseName)\r\n        | extend CmdletResultV = tostring(CmdletResultValue)\r\n        | sort by Account\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n    | join kind = leftanti  (AfterData) on Allinfo\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n    | join kind = innerunique    (BeforeData) on Allinfo\r\n    | extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n    | join kind = leftanti    (InBeforedatabotAfter) on Allinfo\r\n    | extend Actiontype =\"Add/Remove\"\r\n    | project         \r\n        Actiontype,\r\n        Account,\r\n        DatabaseName,\r\n        IsInherited,\r\n        Allinfo\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Allinfo\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData, AddRemoveindataset, InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype), \"N/A\")\r\n| project\r\n    Actiontype,\r\n    Account,\r\n    DatabaseName,\r\n    IsInherited",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Comparaison ReceiveAs",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "filter": true
                    }
                  },
                  "customWidth": "50",
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 5"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"MailboxDatabaseSendAs\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated, CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n    | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n    | extend Account = tostring(CmdletResultValue.UserString)\r\n    | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n    | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n    | extend Allinfo = strcat(Account,DatabaseName)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Account\r\n;\r\nlet AlldataUnique = allDataRange\r\n    | join kind = innerunique     (allDataRange) on Allinfo   \r\n    | distinct \r\n    Account,\r\n    DatabaseName,\r\n    IsInherited,\r\n    Allinfo\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n    | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n    | extend Account = tostring(CmdletResultValue.UserString)\r\n    | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n    | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n    | extend Allinfo = strcat(Account,DatabaseName)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Account\r\n    ;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"MailboxDatabaseSendAs\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue <> \"{'Error':'EmptyResult'}\"\r\n    | where (CmdletResultValue.IsInherited  == false ) in ({IsInherited})\r\n    | extend Account = tostring(CmdletResultValue.UserString)\r\n    | extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\r\n    | extend IsInherited = tostring(CmdletResultValue.IsInherited)\r\n    | extend Allinfo = strcat(Account,DatabaseName)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Account\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n    | join kind = leftanti  (AfterData) on Allinfo\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n    | join kind = innerunique    (BeforeData) on Allinfo\r\n    | extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n    | join kind = leftanti    (InBeforedatabotAfter) on Allinfo\r\n    | extend Actiontype =\"Add/Remove\"\r\n    | project         \r\n        Actiontype,\r\n        Account,\r\n        DatabaseName,\r\n        IsInherited,\r\n        Allinfo\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Allinfo\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData, AddRemoveindataset, InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype), \"N/A\")\r\n| project\r\n    Actiontype,\r\n    Account,\r\n    DatabaseName,\r\n    IsInherited",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Comparaison SendAs",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "filter": true
                    }
                  },
                  "customWidth": "50",
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 5 - Copy"
                }
              ]
            },
            "name": "ReceiveSendAs"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "Delegation"
      },
      "name": "Importantsecurityconfiguration"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Local Administrators",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "The following section will display the content of the local Administrators group for each server\r\n\r\n** When content refers to groups from other forests, none or partial information will be displayed, and the number of Administrators may be inconsistent. **\r\n\r\nMost of the sections display the same information  but with different sorting, views...\r\nIf an SID is part of the local Administrators group, it won't be displayed due to a collect limitation."
            },
            "name": "text - 12"
          },
          {
            "type": 1,
            "content": {
              "json": "Only Exchange administrators should be members of the local Administrators group of Exchange servers.\r\n\r\nYou need to review  the content of the local Administrators group on a regular basis. Ensure that the content is enforced by GPO.\r\n\r\nIt is considered as a high security risk to have a discrepancy of members between the servers. \r\n\r\nIt is not recommended to have more than one local Administrator accounts. Furthermore, the password should be unique on each server and regularly changed. A solution like LAPS could be used to manage the local administrator password.\r\n\r\nOnly Exchange administrators should be able to logon on Exchange servers.\r\n\r\nHere the default content of the local Administrators group for an Exchange server \r\n:\r\n- Administrator (this account can be renamed)\r\n- Domain Admins\r\n- Exchange Trusted Subsystem\r\n- Organization Management\r\n\r\n**Service accounts should not be members of the local Administrators group**. If it is necessary, you need to ensure that the account is dedicated to Exchange. If the service account opens sessions on other servers, it can be used for lateral movements.\r\nThese service accounts should be closely monitored and the security of the server where they are running needs to be at the same level of Exchange servers.\r\n",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "LocalAdminsHelp"
          },
          {
            "type": 9,
            "content": {
              "version": "KqlParameterItem/1.0",
              "parameters": [
                {
                  "id": "dfffbaa4-5888-41c2-b039-dafb6110260c",
                  "version": "KqlParameterItem/1.0",
                  "name": "Limited",
                  "type": 10,
                  "isRequired": true,
                  "typeSettings": {
                    "showDefault": false
                  },
                  "jsonData": "[{ \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":true }\r\n]"
                }
              ],
              "style": "pills",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces"
            },
            "name": "parameters - 7"
          },
          {
            "type": 1,
            "content": {
              "json": "**Yes** : display all content including the default Groups :  Default groups after the installation of Exchange\r\n\r\n**No** : display only content of non standard Groups"
            },
            "name": "text - 15"
          },
          {
            "type": 1,
            "content": {
              "json": "**Top 10 servers with high number of unique local Administrators members**"
            },
            "name": "text - 13"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Level != 0\r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup)) in ({Limited})\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| where ObjectClass !contains \"group\"\r\n| summarize dcount(MemberPath) by Parentgroup\r\n| top 10 by dcount_MemberPath\r\n| sort by dcount_MemberPath",
              "size": 4,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Parentgroup",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "dcount_MemberPath",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  },
                  "numberFormat": {
                    "unit": 17,
                    "options": {
                      "style": "decimal",
                      "maximumFractionDigits": 2,
                      "maximumSignificantDigits": 3
                    }
                  }
                },
                "showBorder": false
              }
            },
            "name": "query - 9"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Click to see number of unique members for every servers in the organization",
              "expandable": true,
              "expanded": true,
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "Number of unique members for all servers"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Level != 0\r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup)) in ({Limited})\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| where ObjectClass !contains \"group\"\r\n| summarize dcount(MemberPath) by Parentgroup\r\n| sort by dcount_MemberPath",
                    "size": 4,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "tiles",
                    "tileSettings": {
                      "titleContent": {
                        "columnMatch": "Parentgroup",
                        "formatter": 1
                      },
                      "leftContent": {
                        "columnMatch": "dcount_MemberPath",
                        "formatter": 12,
                        "formatOptions": {
                          "palette": "auto"
                        },
                        "numberFormat": {
                          "unit": 17,
                          "options": {
                            "style": "decimal",
                            "maximumFractionDigits": 2,
                            "maximumSignificantDigits": 3
                          }
                        }
                      },
                      "showBorder": false
                    }
                  },
                  "name": "query - 9 - Copy"
                }
              ]
            },
            "name": "All servers number of members"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let allsrv = ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") | where \r\nCmdletResultValue.IsMailboxServer== true | extend Name=tostring(CmdletResultValue.Name);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") \r\n| where CmdletResultValue.Level == 1\r\n| project CmdletResultValue\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Name = tostring(trim_end(@'\\\\Local Administrators', tostring(CmdletResultValue.Parentgroup)))\r\n| distinct Name\r\n| project Name\r\n| join kind=rightanti (allsrv) on Name\r\n| project CmdletResultValue.Name",
              "size": 4,
              "title": "Servers not reachable during the collect",
              "noDataMessage": "All server were successfully analyzed",
              "noDataMessageStyle": 3,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "CmdletResultValue_Name",
                  "formatter": 1,
                  "numberFormat": {
                    "unit": 0,
                    "options": {
                      "style": "decimal"
                    }
                  }
                },
                "showBorder": true
              }
            },
            "name": "query - 9 - Copy"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n| where CmdletResultValue.ServerRole <> 64\r\n| count\r\n",
              "size": 4,
              "title": "Total number of servers in the Organizaton",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Count",
                  "formatter": 1,
                  "numberFormat": {
                    "unit": 0,
                    "options": {
                      "style": "decimal"
                    }
                  }
                },
                "showBorder": false
              }
            },
            "customWidth": "50",
            "name": "query - 9 - Copy - Copy"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n| where CmdletResultValue.Level == 1\r\n| project CmdletResultValue\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators', tostring(CmdletResultValue.Parentgroup))\r\n| distinct Parentgroup = Parentgroup\r\n| count ",
              "size": 4,
              "title": "Number of Analyzed servers",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "Count",
                  "formatter": 1,
                  "numberFormat": {
                    "unit": 0,
                    "options": {
                      "style": "decimal"
                    }
                  }
                },
                "showBorder": false
              }
            },
            "customWidth": "50",
            "name": "query - 9 - Copy - Copy - Copy"
          },
          {
            "type": 1,
            "content": {
              "json": "This Tab shows each nonstandard user account that is member (directly or by a group) of the local Administrators group per server.\r\n\r\nConsider reviewing:\r\n- **nonstandard members** : the Memberpath help to understand from which group inclusion the user come from\r\n- **inconsistent members** across servers\r\n\r\nNote that content from Trusted forests might not be displayed. ",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "LocalAdminPerServersHelp"
          },
          {
            "type": 1,
            "content": {
              "json": "This tabled shows a comparaison of the content between two dates.",
              "style": "info"
            },
            "conditionalVisibility": {
              "parameterName": "Compare_Collect",
              "comparison": "isEqualTo",
              "value": "True"
            },
            "name": "LocalAdminPerServersHelp - Copy"
          },
          {
            "type": 9,
            "content": {
              "version": "KqlParameterItem/1.0",
              "parameters": [
                {
                  "id": "590a6eb9-3349-46cd-ace1-cae9aac1f26a",
                  "version": "KqlParameterItem/1.0",
                  "name": "Server",
                  "type": 2,
                  "query": "ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n| where CmdletResultValue.Level == 1\r\n| project CmdletResultValue\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators', tostring(CmdletResultValue.Parentgroup))\r\n| distinct Parentgroup = Parentgroup",
                  "typeSettings": {
                    "additionalResourceOptions": []
                  },
                  "queryType": 0,
                  "resourceType": "microsoft.operationalinsights/workspaces",
                  "value": null
                }
              ],
              "style": "pills",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces"
            },
            "name": "parameters - 18"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nlet _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"LocalAminGroup\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated, CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | where CmdletResultValue.Level != 0 \r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup))\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastPwdSet = tostring(CmdletResultValue.LastPwdSetString)\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| extend Allinfo = strcat(Parentgroup,MemberPath)\r\n| sort by Parentgroup asc\r\n;\r\nlet AlldataUnique = allDataRange\r\n    | join kind = innerunique     (allDataRange) on Allinfo   \r\n    | distinct \r\n    Parentgroup,\r\n    MemberPath, \r\n    Level, \r\n    ObjectClass, \r\n    LastLogon, \r\n    LastPwdSet, \r\n    Enabled, \r\n    DN,\r\n    Allinfo\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue.Level != 0 \r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup))\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastPwdSet = tostring(CmdletResultValue.LastPwdSetString)\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| extend Allinfo = strcat(Parentgroup,MemberPath)\r\n| sort by Parentgroup asc\r\n    ;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | where CmdletResultValue.Level != 0 \r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup))\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastPwdSet = tostring(CmdletResultValue.LastPwdSetString)\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| extend Allinfo = strcat(Parentgroup,MemberPath)\r\n| sort by Parentgroup asc\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n    | join kind = leftanti  (AfterData) on Allinfo\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n    | join kind = innerunique    (BeforeData) on Allinfo\r\n    | extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n    | join kind = leftanti    (InBeforedatabotAfter) on Allinfo\r\n    | extend Actiontype =\"Add/Remove\"\r\n    | project         \r\n        Actiontype,\r\n        Parentgroup,\r\n        MemberPath, \r\n        Level, \r\n        ObjectClass, \r\n        LastLogon, \r\n        LastPwdSet, \r\n        Enabled, \r\n        DN\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Allinfo\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData, AddRemoveindataset, InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype), \"N/A\")\r\n| project\r\n    Actiontype,\r\n    Parentgroup, \r\n    MemberPath, \r\n    Level, \r\n    ObjectClass, \r\n    LastLogon,  \r\n    LastPwdSet, \r\n    Enabled, \r\n    DN\r\n| where Parentgroup contains \"{Server}\"",
              "size": 3,
              "showAnalytics": true,
              "title": "To view the comparaison for one specific server, select a server in the dropdown list",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "filter": true
              }
            },
            "name": "query - 17"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Level != 0 \r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup))\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\r\n| extend LastPwdSet = tostring(CmdletResultValue.LastPwdSetString)\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| summarize Count=count() by MemberPath,Parentgroup,Level,ObjectClass,LastLogon,LastPwdSet,Enabled,DN\r\n| project  Parentgroup = strcat(\"💻  \",Parentgroup),Count,MemberPath,Level,ObjectClass,LastLogon,LastPwdSet,Enabled,DN\r\n| sort by Parentgroup asc ",
              "size": 1,
              "showAnalytics": true,
              "title": " Total per server of Non standard Groups and accounts including nested groups",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Parentgroup",
                    "formatter": 5,
                    "formatOptions": {
                      "aggregation": "Count"
                    }
                  },
                  {
                    "columnMatch": "Count",
                    "formatter": 4,
                    "formatOptions": {
                      "palette": "blue",
                      "aggregation": "Sum"
                    }
                  }
                ],
                "rowLimit": 10000,
                "filter": true,
                "hierarchySettings": {
                  "treeType": 1,
                  "groupBy": [
                    "Parentgroup"
                  ],
                  "finalBy": "Parentgroup"
                },
                "sortBy": [
                  {
                    "itemKey": "MemberPath",
                    "sortOrder": 1
                  }
                ],
                "labelSettings": [
                  {
                    "columnId": "Parentgroup",
                    "label": "Server"
                  }
                ]
              },
              "sortBy": [
                {
                  "itemKey": "MemberPath",
                  "sortOrder": 1
                }
              ]
            },
            "name": "LocalAdminPerServers",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Level == 1\r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup))\r\n| project CmdletResultValue\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend MemberPath = case( ObjectClass == \"group\", strcat( \"👪 \", MemberPath), ObjectClass == \"computer\", strcat( \"💻 \", MemberPath), strcat( \"🧑‍🦰 \", MemberPath) )\r\n| project-away  CmdletResultValue\r\n//| summarize Count=count(), Servers=make_set(Parentgroup) by MemberPath\r\n| summarize Count=count() by MemberPath,Parentgroup \r\n| sort by Count desc",
              "size": 1,
              "showAnalytics": true,
              "title": "Non Standard accounts summary for all servers",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Group",
                    "formatter": 1
                  },
                  {
                    "columnMatch": "MemberPath",
                    "formatter": 5
                  },
                  {
                    "columnMatch": "Count",
                    "formatter": 4,
                    "formatOptions": {
                      "palette": "blue"
                    }
                  },
                  {
                    "columnMatch": "Member",
                    "formatter": 1
                  }
                ],
                "rowLimit": 10000,
                "filter": true,
                "hierarchySettings": {
                  "treeType": 1,
                  "groupBy": [
                    "MemberPath"
                  ],
                  "expandTopLevel": false
                },
                "labelSettings": [
                  {
                    "columnId": "MemberPath",
                    "label": "MemberPath"
                  },
                  {
                    "columnId": "Parentgroup",
                    "label": "Servers"
                  },
                  {
                    "columnId": "Count",
                    "label": "Nb Servers"
                  }
                ]
              }
            },
            "name": "LocalAdminCount",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 1,
            "content": {
              "json": "##### Select a server to display its content\r\n\r\nBy default only the non-standard members are displayed. \r\n\r\n❌ : for last logon displayed when the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 365 days"
            },
            "name": "text - 0"
          },
          {
            "type": 9,
            "content": {
              "version": "KqlParameterItem/1.0",
              "parameters": [
                {
                  "id": "19e606d9-7f3e-4d2f-a314-892da571e50a",
                  "version": "KqlParameterItem/1.0",
                  "name": "Server",
                  "type": 2,
                  "query": "ExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n| where CmdletResultValue.Level == 1\r\n| project CmdletResultValue\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Parentgroup = trim_end(@'\\\\Local Administrators', tostring(CmdletResultValue.Parentgroup))\r\n| distinct Parentgroup = Parentgroup",
                  "typeSettings": {
                    "additionalResourceOptions": [],
                    "showDefault": false
                  },
                  "queryType": 0,
                  "resourceType": "microsoft.operationalinsights/workspaces",
                  "value": null
                },
                {
                  "id": "05ef4f1c-4cf4-406f-9fb2-9ee30dc93abd",
                  "version": "KqlParameterItem/1.0",
                  "name": "Limited",
                  "label": "Show only nonstandard members",
                  "type": 10,
                  "description": "Show only non standard members",
                  "isRequired": true,
                  "typeSettings": {
                    "showDefault": false
                  },
                  "jsonData": "[{ \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":true }\r\n]",
                  "value": "True"
                },
                {
                  "id": "901bf975-426f-486b-82de-ff0d64f139bb",
                  "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": "2f7a613f-8749-44c9-b8be-844964badef8",
                  "version": "KqlParameterItem/1.0",
                  "name": "PasswordLast",
                  "label": "Password Last Set",
                  "type": 10,
                  "isRequired": true,
                  "typeSettings": {
                    "showDefault": false
                  },
                  "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": "let StandardGroup = dynamic([\"Administrator\", \"Domain Admins\",\"Exchange Trusted Subsystem\",\"Organization Management\", \"Admins du domaine\"]);\r\nExchangeConfiguration(SpecificSectionList=\"LocalAminGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Level != 0 \r\n| where CmdletResultValue.Parentgroup contains \"{Server}\"\r\n| where not (CmdletResultValue.MemberPath has_any (StandardGroup)) in ({Limited})\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 = trim_end(@'\\\\Local Administrators',tostring(CmdletResultValue.Parentgroup))\r\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n| extend Level = tostring(CmdletResultValue.Level)\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(365d), 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\r\n| project-away Parentgroup",
              "size": 1,
              "showAnalytics": true,
              "title": "Local Administrators group content",
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "rowLimit": 10000,
                "filter": true,
                "sortBy": [
                  {
                    "itemKey": "MemberPath",
                    "sortOrder": 1
                  }
                ]
              },
              "sortBy": [
                {
                  "itemKey": "MemberPath",
                  "sortOrder": 1
                }
              ]
            },
            "conditionalVisibility": {
              "parameterName": "Server",
              "comparison": "isNotEqualTo",
              "value": ""
            },
            "name": "AdGroups",
            "styleSettings": {
              "showBorder": true
            }
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "Server"
      },
      "name": "Local Administrators"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Exchange and AD GRoup",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "This tab displays the content of high privilege groups in Exchange and AD."
            },
            "name": "text - 7"
          },
          {
            "type": 1,
            "content": {
              "json": "The **Exchange Trusted Subsystem** group is one of the two most sensitive groups in Exchange. This group has all privileges in Exchange and very high privileges in AD.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/exchange-2013-deployment-permissions-reference-exchange-2013-help\" target=\"_blank\">Exchange 2013 deployment permissions reference</a>\r\n\r\nThis group should only contain computer accounts for each Exchange servers. When the DAG has an IP and a CNO, it is acceptable to have the DAG's computer account.\r\n\r\nThis section only shows direct nonstandard members.",
              "style": "info"
            },
            "customWidth": "50",
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "ExchangeTrustedSubsystemHelp"
          },
          {
            "type": 1,
            "content": {
              "json": "The **Exchange Windows Permissions** group is one of the two most sensitive groups in Exchange. This group has very high privileges in AD.\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/exchange-2013-deployment-permissions-reference-exchange-2013-help\" target=\"_blank\">Exchange 2013 deployment permissions reference</a>\r\n\r\nThis group should only contain the group Exchange Trusted SubSystem. This section only shows direct nonstandard members. ",
              "style": "info"
            },
            "customWidth": "50",
            "conditionalVisibility": {
              "parameterName": "Help",
              "comparison": "isEqualTo",
              "value": "Yes"
            },
            "name": "WindowsPermissionGroupTileHelp"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let ETSValidcontent = union kind=outer (ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")| project Name = tostring(CmdletResultValue.Name)), (ExchangeConfiguration(SpecificSectionList=\"DAG\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")| project Name = tostring(Identity));\r\nExchangeConfiguration(SpecificSectionList=\"ETS\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name !in (ETSValidcontent)\r\n| summarize MyCount=countif( CmdletResultType == \"Success\") by CmdletResultType\r\n| project   Result = iff ( CmdletResultType == \"Success\", tostring(MyCount), \"\")",
              "size": 1,
              "showAnalytics": true,
              "title": "Exchange Trusted SubSystem group nonstandard member count",
              "noDataMessage": "Content of group as Expected",
              "noDataMessageStyle": 3,
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "CmdletResultValue_Name",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Result",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "hotCold"
                  },
                  "numberFormat": {
                    "unit": 17,
                    "options": {
                      "style": "decimal",
                      "maximumFractionDigits": 2,
                      "maximumSignificantDigits": 3
                    },
                    "emptyValCustomText": "ScriptError"
                  }
                },
                "showBorder": true
              }
            },
            "customWidth": "50",
            "name": "ExchangeServersTileGroup1Query"
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let ETScontent = ExchangeConfiguration(SpecificSectionList=\"ETS\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") | project Name = tostring(CmdletResultValue.Name);\r\nExchangeConfiguration(SpecificSectionList=\"EWP\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name !in (ETScontent) and CmdletResultValue.Name != \"Exchange Trusted Subsystem\"\r\n| extend Result = iff ( CmdletResultType == \"Success\", \"\", \"Error in the script unable to retrieve value\")\r\n| summarize MyCount=countif( CmdletResultType == \"Success\") by CmdletResultType\r\n| project   Result = iff ( CmdletResultType == \"Success\", tostring(MyCount), \"\")\r\n",
              "size": 1,
              "showAnalytics": true,
              "title": "Exchange Windows Permissions group direct nonstandard members (Exchange Trusted subsystem non standard content not included)",
              "noDataMessage": "Content of group as expected",
              "noDataMessageStyle": 3,
              "showExportToExcel": true,
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "tiles",
              "tileSettings": {
                "titleContent": {
                  "columnMatch": "CmdletResultValue_Name",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "Result",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "hotCold"
                  },
                  "numberFormat": {
                    "unit": 17,
                    "options": {
                      "style": "decimal",
                      "maximumFractionDigits": 2,
                      "maximumSignificantDigits": 3
                    },
                    "emptyValCustomText": "ScriptError"
                  }
                },
                "showBorder": true
              }
            },
            "customWidth": "50",
            "name": "ExchangeServersTileGroup2Query"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "items": [
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let ETSValidcontnet = union kind=outer (ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")| project Name = tostring(CmdletResultValue.Name)), (ExchangeConfiguration(SpecificSectionList=\"DAG\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")| project Name = tostring(Identity));\r\nExchangeConfiguration(SpecificSectionList=\"ETS\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name !in (ETSValidcontnet)\r\n//| extend Name = strcat (\"⛔\",tostring(CmdletResultValue.Name))\r\n| extend Name = iff(CmdletResultType == \"Success\", strcat (\"⛔\",tostring(CmdletResultValue.Name)),\"Script was unable to retrieve data\")\r\n| project Name ",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Exchange Trusted SubSystem nonstandard content",
                    "noDataMessage": "Content of Exchange Trusted SubSystem as Expected",
                    "noDataMessageStyle": 3,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000
                    }
                  },
                  "customWidth": "50",
                  "name": "ETSDetails",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let ETScontent = ExchangeConfiguration(SpecificSectionList=\"ETS\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") | project Name = tostring(CmdletResultValue.Name);\r\nExchangeConfiguration(SpecificSectionList=\"EWP\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Name !in (ETScontent) and CmdletResultValue.Name != \"Exchange Trusted Subsystem\"\r\n| extend Name = iff(CmdletResultType == \"Success\", strcat (\"⛔\",tostring(CmdletResultValue.Name)),\"Script was unable to retrieve data\")\r\n| project Name ",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Exchange Windows Permissions direct nonstandard content (Exchange Trusted subsystem non standard content not included)",
                    "noDataMessage": "Content of Exchange Windows Permissions as Expected",
                    "noDataMessageStyle": 3,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "customWidth": "50",
                  "name": "WindowsPermissionsQuery",
                  "styleSettings": {
                    "showBorder": true
                  }
                }
              ]
            },
            "name": "ETS and WP Grids"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Exchange groups from old Exchange version",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "ℹ️ Recommendations\r\n\r\n- Groups from the old Exchange version should have been removed\r\n- List of old groups \r\n\t- Exchange Organization Administrators\r\n\t- Exchange Recipient Administrators\r\n\t- Exchange Public Folder Administrators\r\n\t- Exchange Server Administrator\r\n\t- Exchange View-Only Administrator\r\n\t- Exchange Enterprise Servers (located in the root domain)\r\n\t- Exchange Domain Servers : one group per domain\r\n\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/built-in-role-groups-exchange-2013-help\" target=\"_blank\">Help for Built-in role groups</a>",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "If still exist, this section showed a summary of the content of old groups",
                    "items": [
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "\r\nlet OldVGroup = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")| where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" or  CmdletResultValue.Parentgroup == \"Exchange Services\"| extend Parentgroup = tostring(CmdletResultValue.Parentgroup));\r\nExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") \r\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| where CmdletResultValue.Parentgroup in (\"Exchange Organization Administrators\", \"Exchange Recipient Administrators\", \"Exchange Public Folder Administrators\", \"Exchange Server Administrator\", \"Exchange View-Only Administrator\") |union OldVGroup\r\n| where CmdletResultValue.Level != 0 and CmdletResultValue.ObjectClass !contains \"group\"\r\n| extend MemberPath= tostring(split(tostring(CmdletResultValue.MemberPath), \"\\\\\")[countof(tostring(CmdletResultValue.MemberPath), \"\\\\\")])\r\n| summarize dcount(tostring(MemberPath)) by Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| sort by dcount_MemberPath\r\n\r\n\r\n",
                          "size": 4,
                          "showAnalytics": true,
                          "noDataMessage": "No groups from old versions found",
                          "noDataMessageStyle": 3,
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "visualization": "tiles",
                          "tileSettings": {
                            "titleContent": {
                              "columnMatch": "Parentgroup",
                              "formatter": 1
                            },
                            "leftContent": {
                              "columnMatch": "dcount_MemberPath",
                              "formatter": 12,
                              "formatOptions": {
                                "palette": "auto"
                              }
                            },
                            "showBorder": true
                          }
                        },
                        "name": "query - 0"
                      }
                    ]
                  },
                  "name": "ExchangeGroupsList"
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "Expand this section to details on the content of the old groups",
                    "expandable": true,
                    "items": [
                      {
                        "type": 1,
                        "content": {
                          "json": "Please select a group"
                        },
                        "name": "text - 5"
                      },
                      {
                        "type": 9,
                        "content": {
                          "version": "KqlParameterItem/1.0",
                          "parameters": [
                            {
                              "id": "b4b7a6ad-381a-48d6-9938-bf7cb812b474",
                              "version": "KqlParameterItem/1.0",
                              "name": "Group",
                              "type": 2,
                              "query": "let OldVGroup = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")| where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" or  CmdletResultValue.Parentgroup == \"Exchange Services\"| extend Parentgroup = tostring(CmdletResultValue.Parentgroup));\r\nExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") \r\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| where CmdletResultValue.Parentgroup in (\"Exchange Organization Administrators\", \"Exchange Recipient Administrators\", \"Exchange Public Folder Administrators\", \"Exchange Server Administrator\", \"Exchange View-Only Administrator\") |union OldVGroup\r\n| project CmdletResultValue\r\n| extend GroupName = tostring(CmdletResultValue.Parentgroup)\r\n| distinct GroupName\r\n| sort by GroupName asc\r\n",
                              "typeSettings": {
                                "showDefault": false
                              },
                              "queryType": 0,
                              "resourceType": "microsoft.operationalinsights/workspaces",
                              "value": null
                            },
                            {
                              "id": "a695df39-1965-479a-ad0f-b4d3d168aaed",
                              "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]\r\n"
                            },
                            {
                              "id": "2d69bad8-0904-467a-86e6-cb0923520c18",
                              "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 - 3"
                      },
                      {
                        "type": 1,
                        "content": {
                          "json": "Old Exchange groups content  groups (Extract for the OU \"Microsoft Exchange Security Groups\").\r\nSelect a group to display detailed information of its contents.\r\nLevel attribute helps you understand the level of nested groups.\r\n\r\n❌ : for last logon displayed when the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 365 days"
                        },
                        "name": "text - 2"
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "let OldVGroupEES = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n    | where (CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.MemberPath != @\"Exchange Enterprise Servers\\Exchange Domain Servers\")  or CmdletResultValue.Parentgroup == \"Exchange Services\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | extend Level = tostring(CmdletResultValue.Level)\r\n    | extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled) );\r\nlet OldVGroupEDS = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n    | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.Level ==0\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | mv-expand CmdletResultValue.Members\r\n    | where CmdletResultValue_Members.objectClass == \"group\"\r\n    | project Parentgroup, MemberPath= strcat(Parentgroup,\"\\\\\", CmdletResultValue_Members.name), Level = tostring(1), ObjectClass = tostring(CmdletResultValue_Members.objectClass), DN = tostring(CmdletResultValue_Members.DistinguishedName), ObjectGuid = tostring(CmdletResultValue_Members.ObjectGuid)\r\n    | join kind=inner ( ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\")\r\n    | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend ObjectGuid = tostring(CmdletResultValue.ObjectGuid)) on ObjectGuid) ;\r\nExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=\"{DateOfConfiguration:value}\", SpecificConfigurationEnv={EnvironmentList}, Target = \"On-Premises\") \r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | where CmdletResultValue.Parentgroup in (\"Exchange Organization Administrators\", \"Exchange Recipient Administrators\", \"Exchange Public Folder Administrators\", \"Exchange Server Administrator\", \"Exchange View-Only Administrator\")\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\r\n    | extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | union OldVGroupEES,OldVGroupEDS\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | where todatetime (CmdletResultValue.LastPwdSetString) < ago(0d) or tostring (CmdletResultValue.LastPwdSetString) == \"\"\r\n    | where todatetime (CmdletResultValue.LastLogonString) < ago(0d) or tostring (CmdletResultValue.LastLogonString) == \"\"\r\n    | sort by tostring(CmdletResultValue.MemberPath) asc \r\n    | where CmdletResultValue.Level != 0\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 MemberPath = case(ObjectClass == \"group\", strcat(\"👪 \", MemberPath), ObjectClass == \"computer\", strcat(\"💻 \", MemberPath), strcat(\"🧑‍🦰 \", MemberPath))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | project Parentgroup, MemberPath, Level, ObjectClass,LastLogon, LastPwdSet ,Enabled,DN\r\n",
                          "size": 1,
                          "showAnalytics": true,
                          "title": "Selected group content",
                          "noDataMessage": "The query returned no results.",
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "gridSettings": {
                            "formatters": [
                              {
                                "columnMatch": "CmdletResultValue",
                                "formatter": 5
                              },
                              {
                                "columnMatch": "Parentgroup",
                                "formatter": 5
                              },
                              {
                                "columnMatch": "LastPwdSet",
                                "formatter": 0,
                                "numberFormat": {
                                  "unit": 0,
                                  "options": {
                                    "style": "decimal"
                                  }
                                }
                              },
                              {
                                "columnMatch": "ParentId",
                                "formatter": 5
                              },
                              {
                                "columnMatch": "Id",
                                "formatter": 5
                              }
                            ],
                            "rowLimit": 10000,
                            "filter": true
                          }
                        },
                        "showPin": true,
                        "name": "ExchangeServersGroupsGrid",
                        "styleSettings": {
                          "showBorder": true
                        }
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeDataEES=\r\n    (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where (CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.MemberPath != @\"Exchange Enterprise Servers\\Exchange Domain Servers\") or CmdletResultValue.Parentgroup == \"Exchange Services\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | extend Level = tostring(CmdletResultValue.Level)\r\n    | extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled));\r\nlet BeforeDataEDS = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.Level == 0\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | mv-expand CmdletResultValue.Members\r\n    | where CmdletResultValue_Members.objectClass == \"group\"\r\n    | project\r\n        Parentgroup,\r\n        MemberPath= strcat(Parentgroup, \"\\\\\", CmdletResultValue_Members.name),\r\n        Level = tostring(1),\r\n        ObjectClass = tostring(CmdletResultValue_Members.objectClass),\r\n        DN = tostring(CmdletResultValue_Members.DistinguishedName),\r\n        ObjectGuid = tostring(CmdletResultValue_Members.ObjectGuid)\r\n    | join kind=inner (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=\"lastdate\", SpecificConfigurationEnv='B13', Target = \"On-Premises\")\r\n        | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\"\r\n        | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n        | extend ObjectGuid = tostring(CmdletResultValue.ObjectGuid))\r\n        on ObjectGuid); \r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where CmdletResultValue.Parentgroup in (\"Exchange Organization Administrators\", \"Exchange Recipient Administrators\", \"Exchange Public Folder Administrators\", \"Exchange Server Administrator\", \"Exchange View-Only Administrator\")\r\n    | union BeforeDataEES, BeforeDataEDS\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet AfterDataEES=\r\n    (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where (CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.MemberPath != @\"Exchange Enterprise Servers\\Exchange Domain Servers\") or CmdletResultValue.Parentgroup == \"Exchange Services\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | extend Level = tostring(CmdletResultValue.Level)\r\n    | extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled));\r\nlet AfterDataEDS = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\" and CmdletResultValue.Level == 0\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | mv-expand CmdletResultValue.Members\r\n    | where CmdletResultValue_Members.objectClass == \"group\"\r\n    | project\r\n        Parentgroup,\r\n        MemberPath= strcat(Parentgroup, \"\\\\\", CmdletResultValue_Members.name),\r\n        Level = tostring(1),\r\n        ObjectClass = tostring(CmdletResultValue_Members.objectClass),\r\n        DN = tostring(CmdletResultValue_Members.DistinguishedName),\r\n        ObjectGuid = tostring(CmdletResultValue_Members.ObjectGuid)\r\n    | join kind=inner (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n        | where CmdletResultValue.Parentgroup == \"Exchange Enterprise Servers\"\r\n        | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n        | extend ObjectGuid = tostring(CmdletResultValue.ObjectGuid))\r\n        on ObjectGuid); \r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | union AfterDataEES, AfterDataEDS\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"ExGroup\" or Section_s == \"ADGroup\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated,CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | where CmdletResultValue.Parentgroup in (\"Exchange Organization Administrators\", \"Exchange Recipient Administrators\", \"Exchange Public Folder Administrators\", \"Exchange Server Administrator\", \"Exchange View-Only Administrator\", \"Exchange Enterprise Servers\" , \"Exchange Services\")\r\n    //| where CmdletResultValue.MemberPath != @\"Exchange Enterprise Servers\\Exchange Domain Servers\"\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    ;\r\nlet AlldataUnique = allDataRange\r\n    | join  kind = innerunique     (allDataRange) on MemberPath   \r\n    | distinct \r\n        TimeGenerated,\r\n        Parentgroup,\r\n        MemberPath,\r\n        Level,\r\n        ObjectClass,\r\n        LastLogon,\r\n        LastPwdSet,\r\n        Enabled\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n  | join kind = leftanti  (AfterData ) on MemberPath\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n| join kind = innerunique    (BeforeData ) on MemberPath\r\n| extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n| join kind = leftanti    (InBeforedatabotAfter ) on MemberPath\r\n| extend Actiontype =\"Add/Remove\"\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on MemberPath\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData,AddRemoveindataset,InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype),\"N/A\")\r\n| where MemberPath <> \"Exchange Enterprise Servers\\\\Exchange Domain Servers\"\r\n| project\r\n    Actiontype,Parentgroup, MemberPath, Level, ObjectClass, LastLogon, LastPwdSet, Enabled\r\n",
                          "size": 3,
                          "showAnalytics": true,
                          "title": "Compare of the contents of selected old group",
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "gridSettings": {
                            "rowLimit": 10000,
                            "filter": true,
                            "sortBy": [
                              {
                                "itemKey": "MemberPath",
                                "sortOrder": 1
                              }
                            ]
                          },
                          "sortBy": [
                            {
                              "itemKey": "MemberPath",
                              "sortOrder": 1
                            }
                          ]
                        },
                        "conditionalVisibility": {
                          "parameterName": "Compare_Collect",
                          "comparison": "isEqualTo",
                          "value": "True"
                        },
                        "name": "ExchangeServersGroupsGrid - Compare",
                        "styleSettings": {
                          "showBorder": true
                        }
                      }
                    ]
                  },
                  "name": "group - 5"
                }
              ]
            },
            "name": "Exchange group from old Exchange versions"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Exchange group",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "ℹ️ Recommendations\r\n\r\n- Ensure that no service account is a member of the high privilege groups. Use RBAC to delegate the exact required permissions.\r\n- Limit the usage of nested group for administration.\r\n- Ensure that accounts are given only the required permissions to execute their tasks.\r\n- Use just in time administration principle by adding users in a group only when they need the required permissions, then remove them when their operation is over.\r\n- Limit the number of Organization management members. When you review the Admin Audit logs you might see that the administrators rarely needed Organization Management privileges.\r\n- Monitor the content of the following groups:\r\n  - Organization Management\r\n  - Recipient Management (Member of this group have at least the following rights : set-mailbox, Add-MailboxPermission)\r\n  - Discovery Management\r\n  - Server Management\r\n  - Hygiene Management\r\n  - Exchange Servers\r\n  - Exchange Trusted Subsystem  \r\n  - Exchange Windows Permissions\r\n  - xxx High privilege group (not an exhaustive list)\r\n  - All RBAC groups that have high roles delegation\r\n  - All nested groups in high privileges groups\r\n  - Note that this is not a complete list. The content of all the groups that have high privileges should be monitored.\r\n- Each time a new RBAC group is created, decide if the content of this groups should be monitored\r\n- Periodically review the members of the groups\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/built-in-role-groups-exchange-2013-help\" target=\"_blank\">Help for Built-in role groups</a>",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "Summary content of most important groups",
                    "items": [
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "ExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.Level != 0 and CmdletResultValue.ObjectClass !contains \"group\"\r\n| extend MemberPath= tostring(split(tostring(CmdletResultValue.MemberPath),\"\\\\\")[countof(tostring(CmdletResultValue.MemberPath),\"\\\\\")])\r\n| summarize dcount(tostring(MemberPath)) by Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| where Parentgroup in  (\"Organization Management\", \"Compliance Management\", \"Discovery Management\", \"Server Management\", \"Recipient Manangement\",\"Security Administrator\", \"Hygiene Management\", \"Public Folder Manangement\", \"Records Manangement\") or Parentgroup contains \"Impersonation\" or Parentgroup contains \"Export\"\r\n| sort by dcount_MemberPath\r\n\r\n",
                          "size": 4,
                          "showAnalytics": true,
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "visualization": "tiles",
                          "tileSettings": {
                            "titleContent": {
                              "columnMatch": "Parentgroup",
                              "formatter": 1
                            },
                            "leftContent": {
                              "columnMatch": "dcount_MemberPath",
                              "formatter": 12,
                              "formatOptions": {
                                "palette": "auto"
                              }
                            },
                            "showBorder": true
                          }
                        },
                        "name": "query - 0"
                      },
                      {
                        "type": 12,
                        "content": {
                          "version": "NotebookGroup/1.0",
                          "groupType": "editable",
                          "title": "Expand for summary content for all groups located in the OU Exchange Security Groups",
                          "expandable": true,
                          "items": [
                            {
                              "type": 3,
                              "content": {
                                "version": "KqlItem/1.0",
                                "query": "ExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.Level != 0 and CmdletResultValue.ObjectClass !contains \"group\"\r\n| extend MemberPath= tostring(split(tostring(CmdletResultValue.MemberPath),\"\\\\\")[countof(tostring(CmdletResultValue.MemberPath),\"\\\\\")])\r\n| summarize dcount(tostring(MemberPath)) by Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n| sort by dcount_MemberPath desc\r\n\r\n",
                                "size": 1,
                                "showAnalytics": true,
                                "title": "OU Exchange Security Groups",
                                "showExportToExcel": true,
                                "queryType": 0,
                                "resourceType": "microsoft.operationalinsights/workspaces",
                                "visualization": "tiles",
                                "tileSettings": {
                                  "titleContent": {
                                    "columnMatch": "Parentgroup",
                                    "formatter": 1
                                  },
                                  "leftContent": {
                                    "columnMatch": "dcount_MemberPath",
                                    "formatter": 12,
                                    "formatOptions": {
                                      "palette": "auto"
                                    }
                                  },
                                  "showBorder": true
                                }
                              },
                              "showPin": false,
                              "name": "query - 0 - Copy"
                            }
                          ]
                        },
                        "name": "All groups"
                      }
                    ]
                  },
                  "name": "ExchangeGroupsList"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Please select a group"
                  },
                  "name": "text - 5 - Copy"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "b4b7a6ad-381a-48d6-9938-bf7cb812b474",
                        "version": "KqlParameterItem/1.0",
                        "name": "Group",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n//| where CmdletResultValue.Parentgroup != \"Exchange Trusted Subsystem\"\r\n//| where CmdletResultValue.Parentgroup != \"Exchange Windows Permissions\"\r\n| project CmdletResultValue\r\n| extend GroupName = tostring(CmdletResultValue.Parentgroup)\r\n| distinct GroupName\r\n| sort by GroupName asc\r\n",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "showExportToExcel": true,
                        "showAnalytics": true,
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "value": null
                      },
                      {
                        "id": "f3b935d7-b78f-41d2-94bc-f8c878a13260",
                        "version": "KqlParameterItem/1.0",
                        "name": "LastLogon",
                        "label": "Last Logon >",
                        "type": 10,
                        "isRequired": true,
                        "multiSelect": true,
                        "quote": "'",
                        "delimiter": ",",
                        "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": "3343688f-e609-4822-b4ed-cdd50b77d948",
                        "version": "KqlParameterItem/1.0",
                        "name": "PasswordLast",
                        "label": "Password Last Set >",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "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 - 3"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Exchange groups content (Extract for the OU \"Microsoft Exchange Security Groups\").\r\nSelect a group to display detailed information of its contents.\r\nLevel attribute helps you understand the level of nested groups.\r\n\r\n❌ : for last logon displayed when the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 365 days"
                  },
                  "name": "text - 2"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ExGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| search CmdletResultValue.Parentgroup == \"{Group}\"\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| sort by tostring(CmdletResultValue.MemberPath) asc \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| 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==\"\", \"❌ No logon\",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==\"\", \"❌ No logon\",strcat(\"❌\",LastPwdSet))))\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| sort by MemberPath asc\r\n| project-away CmdletResultValue,Parentgroup",
                    "size": 3,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "MemberPath",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "MemberPath",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "ExchangeServersGroupsGrid",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"ExGroup\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated,CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    ;\r\nlet AlldataUnique = allDataRange\r\n    | join  kind = innerunique     (allDataRange) on MemberPath   \r\n    | distinct \r\n        TimeGenerated,\r\n        Parentgroup,\r\n        MemberPath,\r\n        Level,\r\n        ObjectClass,\r\n        LastLogon,\r\n        LastPwdSet,\r\n        Enabled\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ExGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n  | join kind = leftanti  (AfterData ) on MemberPath\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n| join kind = innerunique    (BeforeData ) on MemberPath\r\n| extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n| join kind = leftanti    (InBeforedatabotAfter ) on MemberPath\r\n| extend Actiontype =\"Add/Remove\"\r\n| project         \r\n        TimeGenerated,\r\n        Parentgroup,\r\n        Actiontype,\r\n        MemberPath,\r\n        Level,\r\n        ObjectClass,\r\n        LastLogon,\r\n        LastPwdSet,\r\n        Enabled\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on MemberPath\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData,AddRemoveindataset,InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype),\"N/A\")\r\n| project\r\n    Actiontype,Parentgroup, MemberPath, Level, ObjectClass, LastLogon, LastPwdSet, Enabled",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Add/Remove information in selected group",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "MemberPath",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "MemberPath",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "ExchangeServersGroupsGrid - Copy",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Add/Remove means that the account has been added and removed between the Time Range (so not present Before or After the Time Range)"
                  },
                  "name": "text - 7"
                }
              ]
            },
            "name": "Exchange group"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "AD Group",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "Please select a group"
                  },
                  "name": "text - 5 - Copy"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "High privileges AD groups can take control of Exchange by adding any accounts in the Exchange groups.\r\n\r\nNote that the members of the Account Operators are able to manage every AD group (except those protected by AdminSDHolder). This means they can manage the content of every high privilege Exchange groups.\r\n\r\nℹ️ It is recommended to not use this group and to monitor its changes.\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "ADGroupHelp"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "268bd356-7d05-41c3-9867-00c6ab198c5a",
                        "version": "KqlParameterItem/1.0",
                        "name": "Group",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"ADGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where tostring(CmdletResultValue.Parentgroup) != \"Exchange Enterprise Servers\" and tostring(CmdletResultValue.Parentgroup) <> \"Exchange Services\"\r\n| extend GroupName = tostring(CmdletResultValue.Parentgroup)\r\n| distinct GroupName\r\n| sort by GroupName asc\r\n",
                        "typeSettings": {
                          "additionalResourceOptions": [],
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "value": null
                      },
                      {
                        "id": "9d02cad2-f4c5-418d-976f-b88b56f80cb5",
                        "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": "9e591429-d8ea-40c2-80c1-2426c72c92d5",
                        "version": "KqlParameterItem/1.0",
                        "name": "PasswordLast",
                        "label": "Password Last Set",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "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": 1,
                  "content": {
                    "json": "Overview of high privileges AD Groups' content.\r\nSelect a group to display detailed information of its contents.\r\nLevel attribute helps you understand the level of nested groups.\r\n\r\n❌ : for last logon displayed when the last logon is greater than 180 days\r\n\r\n❌ : for password last set displayed when last password set greater than 365 days"
                  },
                  "name": "text - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ADGroup\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| search CmdletResultValue.Parentgroup == \"{Group}\"\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| sort by tostring(CmdletResultValue.MemberPath) asc \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| 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==\"\", \"❌ No logon\",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==\"\", \"❌ No logon\",strcat(\"❌\",LastPwdSet))))\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend DN = tostring(CmdletResultValue.DN)\r\n| sort by MemberPath asc\r\n| project-away CmdletResultValue,Parentgroup",
                    "size": 3,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "formatters": [
                        {
                          "columnMatch": "CmdletResultValue",
                          "formatter": 5
                        },
                        {
                          "columnMatch": "Parentgroup",
                          "formatter": 5
                        }
                      ],
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"ADGroup\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated,CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    ;\r\nlet AlldataUnique = allDataRange\r\n    | join  kind = innerunique     (allDataRange) on MemberPath   \r\n    | distinct \r\n        TimeGenerated,\r\n        Parentgroup,\r\n        MemberPath,\r\n        Level,\r\n        ObjectClass,\r\n        LastLogon,\r\n        LastPwdSet,\r\n        Enabled\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ADGroup\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | search CmdletResultValue.Parentgroup == \"{Group}\"\r\n    | extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\r\n    | extend MemberPath = tostring(CmdletResultValue.MemberPath)\r\n    | extend Level = tostring(CmdletResultValue.Level)\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 == \"\", \"❌ No logon\", 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 == \"\", \"❌ No logon\", strcat(\"❌\", LastPwdSet))))\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend DN = tostring(CmdletResultValue.DN)\r\n    | sort by MemberPath asc\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n  | join kind = leftanti  (AfterData ) on MemberPath\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n| join kind = innerunique    (BeforeData ) on MemberPath\r\n| extend Actiontype =\"Remove\"\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n| join kind = leftanti    (InBeforedatabotAfter ) on MemberPath\r\n| extend Actiontype =\"Add/Remove\"\r\n| project         \r\n        TimeGenerated,\r\n        Parentgroup,\r\n        Actiontype,\r\n        MemberPath,\r\n        Level,\r\n        ObjectClass,\r\n        LastLogon,\r\n        LastPwdSet,\r\n        Enabled\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on MemberPath\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData,AddRemoveindataset,InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype),\"N/A\")\r\n| project\r\n    Actiontype,Parentgroup, MemberPath, Level, ObjectClass, LastLogon, LastPwdSet, Enabled",
                    "size": 3,
                    "showAnalytics": true,
                    "noDataMessage": "Add/Remove information in selected group",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "MemberPath",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "MemberPath",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "ExchangeServersGroupsGrid - Compare",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 1,
                  "content": {
                    "json": "Add/Remove means that the account has been added and removed between the Time Range (so not present Before or After the Time Range)"
                  },
                  "name": "text - 6"
                }
              ]
            },
            "name": "AD Group"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "ExchAD"
      },
      "name": "Exchange and AD GRoup"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "title": "Transport Security configuration",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "This tab displays different security configurations for transport components."
            },
            "name": "text - 10"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Receive Connectors with",
              "items": [
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.PermissionGroupsString contains \"Anonymous\"\r\n| summarize Count = countif (CmdletResultValue.PermissionGroupsString contains \"Anonymous\")  by Name,tostring(CmdletResultValue.Server.Name)\r\n",
                    "size": 0,
                    "title": "Anonymous Configuration",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "piechart",
                    "chartSettings": {
                      "yAxis": [
                        "Count"
                      ],
                      "group": "CmdletResultValue_Server_Name",
                      "ySettings": {
                        "numberFormatSettings": {
                          "unit": 0,
                          "options": {
                            "style": "decimal",
                            "useGrouping": true
                          }
                        }
                      }
                    }
                  },
                  "customWidth": "33",
                  "name": "query - 0"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"RCAnonymous\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| extend Identity = tostring(Identity)\r\n|summarize count() by Identity",
                    "size": 0,
                    "title": "OpenRelay with \"ms-Exch-SMTP-Accept-Any-Recipient\" for Anonymous",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "piechart"
                  },
                  "customWidth": "33",
                  "name": "query - 1"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.AuthMechanismString contains (\"ExternalAuthoritative\")\r\n| extend Server = tostring(CmdletResultValue.Server.Name)\r\n| summarize count() by Name,Server\r\n",
                    "size": 0,
                    "title": "Open Relay using with Externally Secure",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "visualization": "piechart"
                  },
                  "customWidth": "33",
                  "name": "query - 2"
                }
              ]
            },
            "name": "group - 8"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Receive Connectors OpenRelay using Extended Right \"ms-Exch-SMTP-Accept-Any-Recipient\" for Anonymous",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This view shows all **Receive Connectors** configured configured as Open Relay with the Extended Rights \"ms-Exch-SMTP-Accept-Any-Recipient\" set on the Receive Connector object in the Configuration partition.\r\n\r\n\r\nRemember that with this configuration, the Exchange servers can be used to send emails outside the organization. Depending on the configuration, the connectors may be protected by IPs. However, IP protection is not safe configuration.\r\n\r\nYou can check if the \"ms-Exch-SMTP-Accept-Any-Recipient\" ExtendedRights has been added on the Receive connector for Anonymous with PowerShell: `Get-ReceiveConnector  | Get-ADPermission | ? {$_.ExtendedRights -like \"ms-Exch-SMTP-Accept-Any-Recipient\"}`\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/mail-flow/connectors/allow-anonymous-relay?view=exchserver-2019\" target=\"_blank\">Allow anonymous relay on Exchange server</a>\r\n\r\nSee the section \"Receive Connectors with Anonymous Permission\" for additional information regarding Anonymous authentication and IP protection.",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "ReceiveConnectorsHelp"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "fa5f9749-d6f8-436f-ae00-cba306713bac",
                        "version": "KqlParameterItem/1.0",
                        "name": "Server",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.ServerRole <> \"64\"\r\n| extend SRVName = tostring(CmdletResultValue.Name)\r\n| distinct SRVName\r\n| sort by SRVName asc",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "timeContext": {
                          "durationMs": 86400000
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "value": null
                      },
                      {
                        "id": "14912e83-60a1-4a21-a34b-500d4662a666",
                        "version": "KqlParameterItem/1.0",
                        "name": "NoIPRestriction",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":\"False\" }\r\n]",
                        "timeContext": {
                          "durationMs": 86400000
                        }
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 2"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "The toggle button  helps you to sort by:\r\n\r\n- Server\r\n- Receive connectors with/without no IP restrictions"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"RCAnonymous\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project Identity,CmdletResultValue\r\n| extend Identity = tostring(Identity)\r\n| extend Server = replace_string(replace_string(tostring(split(CmdletResultValue.Identity.DistinguishedName,\",\",3)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n|join kind=leftouter  ( ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\") ) on $left.Identity == $right.Name\r\n| where CmdletResultValue1.Server.Name contains \"{Server}\"\r\n| where (CmdletResultValue1.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue1.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n| where CmdletResultValue1.PermissionGroupsString contains \"Anonymous\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n| extend Server = tostring(CmdletResultValue1.Server.Name)\r\n| extend Name = tostring(CmdletResultValue1.Name)\r\n| extend TransportRole = iff(CmdletResultValue1.TransportRole== \"32\" , \"HubTransport\", \"FrontendTransport\")\r\n| extend Enabled = tostring(CmdletResultValue1.Enabled)\r\n| extend PermissionGroups = tostring(CmdletResultValue1.PermissionGroupsString) \r\n| extend AuthMechanism = tostring(CmdletResultValue1.AuthMechanismString)\r\n| mv-expand RemoteIPall=CmdletResultValue1.RemoteIPRanges\r\n| mv-expand BindingAllall=CmdletResultValue1.Bindings\r\n| extend RemoteIP= RemoteIPall.Expression\r\n| extend IP= strcat (BindingAllall.Address,\"-\",BindingAllall.Port)\r\n| summarize Bindings = make_set(tostring(IP)),RemoteIPRange = make_set(tostring(RemoteIP)) by Server,Name,TransportRole,Enabled,PermissionGroups,AuthMechanism\r\n| sort  by Server asc",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "Server",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "Server",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "RCAnonymousQuery",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    | extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"RCAnonymous\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| project Identity,CmdletResultValue\r\n| extend Identity = tostring(Identity)\r\n| extend Server = replace_string(replace_string(tostring(split(CmdletResultValue.Identity.DistinguishedName,\",\",3)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"RCAnonymous\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project Identity,CmdletResultValue\r\n    | extend Identity = tostring(Identity)\r\n    | extend Server = replace_string(replace_string(tostring(split(CmdletResultValue.Identity.DistinguishedName,\",\",3)),\"[\\\"CN=\",\"\"),\"\\\"]\",\"\")\r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Server\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Server\r\n    | extend Actiontype =\"Remove\"\r\n    | distinct \r\n        Actiontype,\r\n        Identity,\r\n        Server\r\n    | project         \r\n        Actiontype,\r\n        Identity,\r\n        Server\r\n;\r\nunion DiffAddData, DiffRemoveData\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), \"N/A\")\r\n| project\r\n    Actiontype,\r\n    Permission = \"ms-Exch-SMTP-Accept-Any-Recipient\",\r\n    Identity,\r\n    Server\r\n| order by Server\r\n\r\n",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "filter": true
                    }
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 4"
                }
              ]
            },
            "name": "Receive Connectors OpenRelay using Extended Right \"ms-Exch-SMTP-Accept-Any-Recipient\" for Anonymous"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Receive Connectors OpenRelay using Authentication ExternalAuthoritative",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This view shows all Receive Connectors configured with authentication set to Externally Secure. With this configuration the Receive connector will be allow as Open Relay.\r\n\r\nRemember that with this configuration, the Exchange servers can be used to send emails outside the organization. Depending on the configuration, the connectors may be protected by IP. However, IP protection is not safe configuration.\r\n\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/mail-flow/connectors/allow-anonymous-relay?view=exchserver-2019\" target=\"_blank\">Allow anonymous relay on Exchange server</a>\r\n\r\nSee the section \"Receive Connectors with Anonymous Permission\" for additional information regarding Anonymous authentication and IP protection.\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "ReceiveConnectorsHelp"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "195a66a1-7aa2-4564-bd3b-233049d6f101",
                        "version": "KqlParameterItem/1.0",
                        "name": "Server",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.ServerRole <> \"64\"\r\n| extend SRVName = tostring(CmdletResultValue.Name)\r\n| distinct SRVName\r\n| sort by SRVName asc",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "value": null
                      },
                      {
                        "id": "4ef1d2a2-a13f-4bd4-9e66-2d9a15ad8a7a",
                        "version": "KqlParameterItem/1.0",
                        "name": "NoIPRestriction",
                        "type": 10,
                        "description": "See Receive Connectors with no IP restriction",
                        "isRequired": true,
                        "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":\"False\" }\r\n]"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 3"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "The toggle button helps you to sort by:\r\n\r\n- Server\r\n- Receive connectors with/without no IP restrictions"
                  },
                  "name": "text - 3"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Server.Name contains \"{Server}\"\r\n| where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n| where CmdletResultValue.AuthMechanismString contains \"ExternalAuthoritative\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n| project CmdletResultValue\r\n| extend Server = tostring(CmdletResultValue.Server.Name)\r\n| extend Name = tostring(CmdletResultValue.Name)\r\n| extend TransportRole = iff(CmdletResultValue.TransportRole== \"32\" , \"HubTransport\", \"FrontendTransport\")\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString)\r\n//| extend Bindings = iif(tostring(parse_json(tostring(CmdletResultValue.Bindings))[1].Port )!=\"\",tostring(strcat(tostring(parse_json(tostring(CmdletResultValue.Bindings))[0].Address),\"-\",tostring(parse_json(tostring(CmdletResultValue.Bindings))[0].Port),\",\",tostring(parse_json(tostring(CmdletResultValue.Bindings))[1].Address),\"-\",tostring(parse_json(tostring(CmdletResultValue.Bindings))[1].Port))),tostring(strcat(tostring(parse_json(tostring(CmdletResultValue.Bindings))[0].Address),\"-\",tostring(parse_json(tostring(CmdletResultValue.Bindings))[0].Port))))\r\n//| extend RemoteIPRanges = tostring(CmdletResultValue.RemoteIPRanges)\r\n| extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n| mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n| mv-expand BindingAllall=CmdletResultValue.Bindings\r\n| extend RemoteIP= RemoteIPall.Expression\r\n| extend IP= strcat (BindingAllall.Address,\"-\",BindingAllall.Port)\r\n| summarize Bindings = make_set(tostring(IP)),RemoteIPRange = make_set(tostring(RemoteIP)) by Server,Name,TransportRole,Enabled,PermissionGroups,AuthMechanism\r\n| sort  by Server asc\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Receive Connectors configure with Externally Secured Authentication",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "Server",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "Server",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| where CmdletResultValue.Server.Name contains \"{Server}\"\r\n| where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n    | where CmdletResultValue.AuthMechanismString contains \"ExternalAuthoritative\"\r\n    | project CmdletResultValue,WhenChanged,WhenCreated\r\n    | extend Server = tostring(CmdletResultValue.Server.Name)\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend TransportRole = iff(CmdletResultValue.TransportRole == \"32\", \"HubTransport\", \"FrontendTransport\")\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString)\r\n    | extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n    | mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n    | mv-expand BindingAllall=CmdletResultValue.Bindings\r\n    | extend RemoteIP= RemoteIPall.Expression\r\n    | extend IP= strcat (BindingAllall.Address, \"-\", BindingAllall.Port)\r\n    | extend Identity = strcat(Server,'\\\\',Name)\r\n    | summarize Bindings = make_set(tostring(IP)), RemoteIPRange = make_set(tostring(RemoteIP)) by Server, Name, TransportRole, Enabled, PermissionGroups, AuthMechanism,WhenChanged,WhenCreated,Identity\r\n    | sort by Server asc\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where CmdletResultValue.Server.Name contains \"{Server}\"\r\n    | where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n    | where CmdletResultValue.AuthMechanismString contains \"ExternalAuthoritative\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n    | project CmdletResultValue, WhenChanged,WhenCreated\r\n    | extend Server = tostring(CmdletResultValue.Server.Name)\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend TransportRole = iff(CmdletResultValue.TransportRole == \"32\", \"HubTransport\", \"FrontendTransport\")\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString)\r\n    | extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n    | mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n    | mv-expand BindingAllall=CmdletResultValue.Bindings\r\n    | extend RemoteIP= RemoteIPall.Expression\r\n    | extend IP= strcat (BindingAllall.Address, \"-\", BindingAllall.Port)\r\n    | extend Identity = strcat(Server,'\\\\',Name)\r\n    | summarize Bindings = make_set(tostring(IP)), RemoteIPRange = make_set(tostring(RemoteIP)) by Server, Name, TransportRole, Enabled, PermissionGroups, AuthMechanism,WhenChanged,WhenCreated,Identity\r\n    | sort by Server asc\r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Identity\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Server\r\n    | extend Actiontype =\"Remove\"\r\n    | extend Binding = tostring(Bindings)\r\n    | extend RIR = tostring(RemoteIPRange)\r\n    | distinct\r\n        WhenChanged,\r\n        Actiontype,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        Bindings = Binding,\r\n        RemoteIPRange = RIR,\r\n        WhenCreated        \r\n;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by WhenChanged asc \r\n    | sort by Server, Name asc\r\n    | extend Identity = strcat(Server,\"\\\\\",Name)\r\n    | extend Name = iff(Name != prev(Name) and prev(Name) != \"\" and Identity == prev(Identity) , strcat(\"📍 \", Name, \" (\", prev(Name), \"->\", Name, \" )\"), Name)\r\n    | extend TransportRole = iff(TransportRole != prev(TransportRole) and prev(TransportRole) != \"\"and Identity == prev(Identity), strcat(\"📍 \", TransportRole, \" (\", prev(TransportRole), \"->\", TransportRole, \" )\"), TransportRole)\r\n    | extend Enabled = iff(Enabled != prev(Enabled) and prev(Enabled) != \"\" and Identity == prev(Identity), strcat(\"📍 \", Enabled, \" (\", prev(Enabled), \"->\", Enabled, \" )\"), Enabled)\r\n    | extend PermissionGroups = iff(PermissionGroups != prev(PermissionGroups) and prev(PermissionGroups) != \"\" and Identity == prev(Identity), strcat(\"📍 \", PermissionGroups, \" (\", prev(PermissionGroups), \"->\", PermissionGroups, \" )\"), PermissionGroups)\r\n    | extend AuthMechanism  = iff(AuthMechanism != prev(AuthMechanism) and prev(AuthMechanism) != \"\" and Identity == prev(Identity), strcat(\"📍 \", AuthMechanism, \" (\", prev(AuthMechanism), \"->\", AuthMechanism, \" )\"), AuthMechanism)\r\n    | extend Bindings  = iff(tostring(Bindings) != tostring(prev(Bindings)) and tostring(prev(Bindings)) != \"\" and Identity == prev(Identity), strcat(\"📍 \", tostring(Bindings), \" (\", prev(Bindings), \"->\", tostring(Bindings), \" )\"), tostring(Bindings))\r\n    | extend RemoteIPRange  = iff(tostring(RemoteIPRange) != tostring(prev(RemoteIPRange)) and tostring(prev(RemoteIPRange)) != \"\" and Identity == prev(Identity), strcat(\"📍 \", tostring(RemoteIPRange), \" (\", prev(RemoteIPRange), \"->\", RemoteIPRange, \" )\"), tostring(RemoteIPRange))\r\n    | extend ActiontypeR =iff(( Name  contains \"📍\" or TransportRole contains \"📍\" or Enabled contains \"📍\" or PermissionGroups contains \"📍\" or AuthMechanism contains \"📍\" or Bindings contains \"📍\" or Bindings contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        tostring=(Bindings),\r\n        tostring(RemoteIPRange),\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n        Actiontype,\r\n        WhenChanged,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        Bindings = Bindings_string,\r\n        RemoteIPRange = RemoteIPRange_string,\r\n        WhenCreated",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "filter": true
                    }
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 4 - Copy"
                }
              ]
            },
            "name": "Security Transport  Configuration"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Receive Connectors with Anonymous Permission",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "This view shows all Receive Connectors configured with Anonymous authentication. It is not recommended to configure connectors with Anonymous authentication.\r\n\r\nWhen configured with Anonymous and No Ip Restriction, any machine can initiate an SMTP session with the Receive Connectors. This can then be used send emails (SPAM/Virus/Phishing....) to all the mailboxes in the organization. The mail will be seen as an internal mail and might bypass some protections.\r\n\r\nIf you absolute need this configuration because some of your application does not support Authentication, it is strongly recommended to limit the IP addresses that can establish SMTP sessions with Exchange. Do not use range of subnet.\r\n\r\nThis section has an option button to display \r\n     All Receive Connectors with Anonymous (No)\r\n     All Receive Connectors with Anonymous and with no IP Restriction (Yes)",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "ReceiveConnectorsHelp"
                },
                {
                  "type": 9,
                  "content": {
                    "version": "KqlParameterItem/1.0",
                    "parameters": [
                      {
                        "id": "195a66a1-7aa2-4564-bd3b-233049d6f101",
                        "version": "KqlParameterItem/1.0",
                        "name": "Server",
                        "type": 2,
                        "query": "ExchangeConfiguration(SpecificSectionList=\"ExchangeServers\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.ServerRole <> \"64\"\r\n| extend SRVName = tostring(CmdletResultValue.Name)\r\n| distinct SRVName\r\n| sort by SRVName asc",
                        "typeSettings": {
                          "showDefault": false
                        },
                        "queryType": 0,
                        "resourceType": "microsoft.operationalinsights/workspaces",
                        "value": null
                      },
                      {
                        "id": "bcb24a01-9242-4fec-b30a-02b0583cbc87",
                        "version": "KqlParameterItem/1.0",
                        "name": "NoIPRestriction",
                        "type": 10,
                        "isRequired": true,
                        "typeSettings": {
                          "showDefault": false
                        },
                        "jsonData": "[\r\n { \"value\": \"True\", \"label\": \"Yes\" },\r\n { \"value\": \"True,False\", \"label\": \"No\", \"selected\":\"False\" }\r\n]"
                      }
                    ],
                    "style": "pills",
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "name": "parameters - 3"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "The toggle button helps you to sort by:\r\n- Server\r\n- Receive connectors with/without no IP restrictions"
                  },
                  "name": "text - 3 - Copy"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.Server.Name contains \"{Server}\"\r\n| where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n| where CmdletResultValue.PermissionGroupsString contains \"Anonymous\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n| project CmdletResultValue\r\n| extend Server = tostring(CmdletResultValue.Server.Name)\r\n| extend Name = tostring(CmdletResultValue.Name)\r\n| extend TransportRole = iff(CmdletResultValue.TransportRole== \"32\" , \"HubTransport\", \"FrontendTransport\")\r\n| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString) \r\n| extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n| mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n| mv-expand BindingAllall=CmdletResultValue.Bindings\r\n| extend RemoteIP= RemoteIPall.Expression\r\n| extend IP= strcat (BindingAllall.Address,\"-\",BindingAllall.Port)\r\n| summarize Bindings = make_set(tostring(IP)),RemoteIPRange = make_set(tostring(RemoteIP)) by Server,Name,TransportRole,Enabled,PermissionGroups,AuthMechanism\r\n| sort  by Server asc\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Receive Connectors configure with Anonymous Permission",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true,
                      "sortBy": [
                        {
                          "itemKey": "Server",
                          "sortOrder": 1
                        }
                      ]
                    },
                    "sortBy": [
                      {
                        "itemKey": "Server",
                        "sortOrder": 1
                      }
                    ]
                  },
                  "name": "query - 2",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| where CmdletResultValue.Server.Name contains \"{Server}\"\r\n| where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n    | where CmdletResultValue.PermissionGroupsString contains \"Anonymous\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n    | project CmdletResultValue,WhenChanged,WhenCreated\r\n    | extend Server = tostring(CmdletResultValue.Server.Name)\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend TransportRole = iff(CmdletResultValue.TransportRole == \"32\", \"HubTransport\", \"FrontendTransport\")\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString)\r\n    | extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n    | mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n    | mv-expand BindingAllall=CmdletResultValue.Bindings\r\n    | extend RemoteIP= RemoteIPall.Expression\r\n    | extend IP= strcat (BindingAllall.Address, \"-\", BindingAllall.Port)\r\n    | extend Identity = strcat(Server,'\\\\',Name)\r\n    | summarize Bindings = make_set(tostring(IP)), RemoteIPRange = make_set(tostring(RemoteIP)) by Server, Name, TransportRole, Enabled, PermissionGroups, AuthMechanism,WhenChanged,WhenCreated,Identity\r\n    | sort by Server asc\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"ReceiveConnector\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | where CmdletResultValue.Server.Name contains \"{Server}\"\r\n    | where (CmdletResultValue.RemoteIPRanges contains \"0.0.0.0\" or CmdletResultValue.RemoteIPRanges contains \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\") in ({NoIPRestriction})\r\n    | where CmdletResultValue.PermissionGroupsString contains \"Anonymous\" //> 12 and CmdletResultValue.PermissionGroups != 14 and CmdletResultValue.PermissionGroups != 16\r\n    | project CmdletResultValue, WhenChanged,WhenCreated\r\n    | extend Server = tostring(CmdletResultValue.Server.Name)\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend TransportRole = iff(CmdletResultValue.TransportRole == \"32\", \"HubTransport\", \"FrontendTransport\")\r\n    | extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend PermissionGroups = tostring(CmdletResultValue.PermissionGroupsString)\r\n    | extend AuthMechanism = tostring(CmdletResultValue.AuthMechanismString)\r\n    | mv-expand RemoteIPall=CmdletResultValue.RemoteIPRanges\r\n    | mv-expand BindingAllall=CmdletResultValue.Bindings\r\n    | extend RemoteIP= RemoteIPall.Expression\r\n    | extend IP= strcat (BindingAllall.Address, \"-\", BindingAllall.Port)\r\n    | extend Identity = strcat(Server,'\\\\',Name)\r\n    | summarize Bindings = make_set(tostring(IP)), RemoteIPRange = make_set(tostring(RemoteIP)) by Server, Name, TransportRole, Enabled, PermissionGroups, AuthMechanism,WhenChanged,WhenCreated,Identity\r\n    | sort by Server asc\r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Identity\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Identity\r\n    | extend Actiontype =\"Remove\"\r\n    | extend Binding = tostring(Bindings)\r\n    | extend RIR = tostring(RemoteIPRange)\r\n    | distinct\r\n        WhenChanged,\r\n        Actiontype,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        Bindings = Binding,\r\n        RemoteIPRange = RIR,\r\n        WhenCreated        \r\n;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by WhenChanged asc \r\n    | sort by Server, Name asc\r\n    | extend Identity = strcat(Server,\"\\\\\",Name)\r\n    | extend Name = iff(Name != prev(Name) and prev(Name) != \"\" and Identity == prev(Identity) , strcat(\"📍 \", Name, \" (\", prev(Name), \"->\", Name, \" )\"), Name)\r\n    | extend TransportRole = iff(TransportRole != prev(TransportRole) and prev(TransportRole) != \"\"and Identity == prev(Identity), strcat(\"📍 \", TransportRole, \" (\", prev(TransportRole), \"->\", TransportRole, \" )\"), TransportRole)\r\n    | extend Enabled = iff(Enabled != prev(Enabled) and prev(Enabled) != \"\" and Identity == prev(Identity), strcat(\"📍 \", Enabled, \" (\", prev(Enabled), \"->\", Enabled, \" )\"), Enabled)\r\n    | extend PermissionGroups = iff(PermissionGroups != prev(PermissionGroups) and prev(PermissionGroups) != \"\" and Identity == prev(Identity), strcat(\"📍 \", PermissionGroups, \" (\", prev(PermissionGroups), \"->\", PermissionGroups, \" )\"), PermissionGroups)\r\n    | extend AuthMechanism  = iff(AuthMechanism != prev(AuthMechanism) and prev(AuthMechanism) != \"\" and Identity == prev(Identity), strcat(\"📍 \", AuthMechanism, \" (\", prev(AuthMechanism), \"->\", AuthMechanism, \" )\"), AuthMechanism)\r\n    | extend Bindings  = iff(tostring(Bindings) != tostring(prev(Bindings)) and tostring(prev(Bindings)) != \"\" and Identity == prev(Identity), strcat(\"📍 \", tostring(Bindings), \" (\", prev(Bindings), \"->\", tostring(Bindings), \" )\"), tostring(Bindings))\r\n    | extend RemoteIPRange  = iff(tostring(RemoteIPRange) != tostring(prev(RemoteIPRange)) and tostring(prev(RemoteIPRange)) != \"\" and Identity == prev(Identity), strcat(\"📍 \", tostring(RemoteIPRange), \" (\", prev(RemoteIPRange), \"->\", RemoteIPRange, \" )\"), tostring(RemoteIPRange))\r\n    | extend ActiontypeR =iff(( Name  contains \"📍\" or TransportRole contains \"📍\" or Enabled contains \"📍\" or PermissionGroups contains \"📍\" or AuthMechanism contains \"📍\" or Bindings contains \"📍\" or Bindings contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        Bindings,\r\n        RemoteIPRange,\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n        Actiontype,\r\n        WhenChanged,\r\n        Server,\r\n        Name,\r\n        TransportRole,\r\n        Enabled,\r\n        PermissionGroups,\r\n        AuthMechanism,\r\n        Bindings = Bindings_string,\r\n        RemoteIPRange = RemoteIPRange_string,\r\n        WhenCreated",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 4 - Copy - Copy"
                }
              ]
            },
            "name": "Receive Connectors configure with Anonymous Permission"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "title": "Transport Rules with specific actions to monitor",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "A  common way used by attackers to exfiltrate data is to set Transport Rules that send all or sensitive messages outside the organization or to a mailbox where they already have full control.\r\n\r\nThis section shows your Transport rules with sentitive actions that can lead to data leaks:\r\n- BlindCopyTo\r\n- RedirectMessageTo\r\n- CopyTo\r\n\r\n\r\nFor more information :\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/mail-flow-rules/mail-flow-rules?view=exchserver-2019\" target=\"_blank\">Mail flow rules in Exchange Server</a>\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "TransportRulesHelp"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"TransportRule\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| extend Identity = iif( CmdletResultValue.Identity contains \"OrgHierarchyToIgnore\",tostring(CmdletResultValue.Identity.Name),tostring(CmdletResultValue.Identity))\r\n//| extend State = tostring(CmdletResultValue.State)\r\n| extend Status= iff ( tostring(CmdletResultValue.State)== \"Enabled\" or tostring(CmdletResultValue.State)== \"1\" , \"Enabled\",iff(tostring(CmdletResultValue.State)==\"\",\"\", \"Disabled\"))\r\n| extend SentTo = tostring(CmdletResultValue.SentToString)\r\n| extend BlindCopyTo = tostring(CmdletResultValue.BlindCopyToString)\r\n| extend CopyTo = tostring(CmdletResultValue.CopyToString)\r\n| extend RedirectMessageTo = tostring(CmdletResultValue.RedirectMessageToString)\r\n| extend Mode = tostring(CmdletResultValue.Identity.Mode)\r\n| project-away CmdletResultValue\r\n| sort  by Identity asc\r\n| sort  by Status desc",
                    "size": 1,
                    "showAnalytics": true,
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "query - 1",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"TransportRule\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    | extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\n//let _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"TransportRule\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| project CmdletResultValue,TimeGenerated\r\n| extend Identity = iif( CmdletResultValue.Identity contains \"OrgHierarchyToIgnore\",tostring(CmdletResultValue.Identity.Name),tostring(CmdletResultValue.Identity))\r\n//| extend State = tostring(CmdletResultValue.State)\r\n| extend Status= iff ( tostring(CmdletResultValue.State)== \"Enabled\" or tostring(CmdletResultValue.State)== \"1\" , \"Enabled\",iff(tostring(CmdletResultValue.State)==\"\",\"\", \"Disabled\"))\r\n| extend SentTo = tostring(CmdletResultValue.SentToString)\r\n| extend BlindCopyTo = tostring(CmdletResultValue.BlindCopyToString)\r\n| extend CopyTo = tostring(CmdletResultValue.CopyToString)\r\n| extend RedirectMessageTo = tostring(CmdletResultValue.RedirectMessageToString)\r\n| extend Mode = tostring(CmdletResultValue.Identity.Mode)\r\n| project-away CmdletResultValue\r\n| sort  by Identity asc\r\n| sort  by Status desc\r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"TransportRule\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| project CmdletResultValue, TimeGenerated\r\n| extend Identity = iif( CmdletResultValue.Identity contains \"OrgHierarchyToIgnore\",tostring(CmdletResultValue.Identity.Name),tostring(CmdletResultValue.Identity))\r\n//| extend State = tostring(CmdletResultValue.State)\r\n| extend Status= iff ( tostring(CmdletResultValue.State)== \"Enabled\" or tostring(CmdletResultValue.State)== \"1\" , \"Enabled\",iff(tostring(CmdletResultValue.State)==\"\",\"\", \"Disabled\"))\r\n| extend SentTo = tostring(CmdletResultValue.SentToString)\r\n| extend BlindCopyTo = tostring(CmdletResultValue.BlindCopyToString)\r\n| extend CopyTo = tostring(CmdletResultValue.CopyToString)\r\n| extend RedirectMessageTo = tostring(CmdletResultValue.RedirectMessageToString)\r\n| extend Mode = tostring(CmdletResultValue.Identity.Mode)\r\n| project-away CmdletResultValue\r\n| sort  by Identity asc\r\n| sort  by Status desc\r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Identity\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Identity\r\n    | extend Actiontype =\"Remove\"\r\n    | distinct\r\n        TimeGenerated,\r\n        Actiontype,\r\n        Identity,\r\n        Status,\r\n        SentTo,\r\n        BlindCopyTo,\r\n        CopyTo,\r\n        RedirectMessageTo,\r\n        Mode\r\n;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by Identity, TimeGenerated asc\r\n    | extend Status = iff(Status != prev(Status) and Identity == prev(Identity), strcat(\"📍 \", Status, \" (\", iff(prev(Status)==\"\",\"Null\",prev(Status)), \"->\", Status, \" )\"), Status)\r\n    | extend SentTo = iff(SentTo != prev(SentTo) and Identity == prev(Identity), strcat(\"📍 \", SentTo, \" (\", iff(prev(SentTo)==\"\",\"Null\",prev(SentTo)), \"->\", SentTo, \" )\"), SentTo)\r\n    | extend BlindCopyTo = iff(BlindCopyTo != prev(BlindCopyTo) and Identity == prev(Identity), strcat(\"📍 \", BlindCopyTo, \" (\", iff(prev(BlindCopyTo)==\"\",\"Null\",prev(BlindCopyTo)), \"->\", BlindCopyTo, \" )\"), BlindCopyTo)\r\n    | extend CopyTo = iff(CopyTo != prev(CopyTo) and Identity == prev(Identity), strcat(\"📍 \", CopyTo, \" (\", iff(prev(CopyTo)==\"\",\"Null\",prev(CopyTo)), \"->\", CopyTo, \" )\"), CopyTo)\r\n    | extend RedirectMessageTo = iff(CopyTo != prev(RedirectMessageTo) and Identity == prev(Identity), strcat(\"📍 \", RedirectMessageTo, \" (\", iff(prev(RedirectMessageTo)==\"\",\"Null\",prev(RedirectMessageTo)), \"->\", RedirectMessageTo, \" )\"), RedirectMessageTo)\r\n    | extend Mode = iff(Mode != prev(Mode) and Identity == prev(Identity), strcat(\"📍 \", Mode, \" (\", iff(prev(Mode)==\"\",\"Null\",prev(Mode)), \"->\", Mode, \" )\"), Mode)\r\n    | extend ActiontypeR =iff(( Identity  contains \"📍\" or Status contains \"📍\" or SentTo contains \"📍\" or BlindCopyTo contains \"📍\" or CopyTo contains \"📍\" or RedirectMessageTo contains \"📍\" or Mode contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        TimeGenerated,\r\n        Actiontype,\r\n        Identity,\r\n        Status,\r\n        SentTo,\r\n        BlindCopyTo,\r\n        CopyTo,\r\n        RedirectMessageTo,\r\n        Mode\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by TimeGenerated desc \r\n| project\r\n        TimeGenerated,\r\n        Actiontype,\r\n        Identity,\r\n        Status,\r\n        SentTo,\r\n        BlindCopyTo,\r\n        CopyTo,\r\n        RedirectMessageTo,\r\n        Mode",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 4 - Copy - Copy - Copy - Copy"
                }
              ]
            },
            "name": "Transport Rules actions to monitor"
          },
          {
            "type": 12,
            "content": {
              "version": "NotebookGroup/1.0",
              "groupType": "editable",
              "items": [
                {
                  "type": 1,
                  "content": {
                    "json": "### Journal Mailboxes"
                  },
                  "name": "JournalMailboxHelp"
                },
                {
                  "type": 1,
                  "content": {
                    "json": "The **Journal Mailboxes** contain emails sent and received by specific or all users. The content of these mailboxes is very sensitives.\r\n\r\nJournal Rules should be reviewed to check if they are still needed. Mailbox audit should be set on these mailboxes. Also by default, no one should access to these mailboxes.\r\n\r\nThen, it is recommended to regularly check who have Full Access mailbox or Receive As on these mailboxes.\r\nAdditional information :\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/journaling/journaling?view=exchserver-2019\" target=\"_blank\">Journaling in Exchange Server</a>\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/journaling/journaling-procedures?view=exchserver-2019\" target=\"_blank\">Journaling procedures</a>\r\n\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/mailbox-audit-logging/mailbox-audit-logging?view=exchserver-2019\" target=\"_blank\">Mailbox audit logging in Exchange Server</a>\r\n\r\n\r\n",
                    "style": "info"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Help",
                    "comparison": "isEqualTo",
                    "value": "Yes"
                  },
                  "name": "JournalHelp"
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "ExchangeConfiguration(SpecificSectionList=\"JournalRule\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| extend Name = tostring(CmdletResultValue.Name)\r\n| extend Status= iff ( tostring(CmdletResultValue.Enabled)== \"true\"  , \"Enabled\", iff(tostring(CmdletResultValue.Enabled)==\"\",\"\", \"Disabled\"))\r\n//| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n| extend JournalEmailAddress = tostring(CmdletResultValue.JournalEmailAddress.Address)\r\n| extend Recipient = tostring(CmdletResultValue.Recipient.Address)\r\n| sort  by Name asc\r\n| sort  by Status desc\r\n| project-away CmdletResultValue\r\n",
                    "size": 1,
                    "showAnalytics": true,
                    "title": "Journal Rules configured in your environment",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces",
                    "gridSettings": {
                      "rowLimit": 10000,
                      "filter": true
                    }
                  },
                  "name": "JournalQuery",
                  "styleSettings": {
                    "showBorder": true
                  }
                },
                {
                  "type": 3,
                  "content": {
                    "version": "KqlItem/1.0",
                    "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"JournalRule\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet allDataRange = \r\n    ESIExchangeConfig_CL\r\n    | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\r\n    | where ESIEnvironment_s == _EnvList\r\n    | where Section_s == \"JournalRule\"\r\n    | extend CmdletResultValue = parse_json(rawData_s)\r\n    | project TimeGenerated, CmdletResultValue //,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\r\n    | project CmdletResultValue, TimeGenerated\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend Status= iff (tostring(CmdletResultValue.Enabled) == \"true\", \"Enabled\", iff(tostring(CmdletResultValue.Enabled) == \"\", \"\", \"Disabled\"))\r\n    //| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend JournalEmailAddress = tostring(CmdletResultValue.JournalEmailAddress.Address)\r\n    | extend Recipient = tostring(CmdletResultValue.Recipient.Address)\r\n    | extend Allinfo = strcat(Name,JournalEmailAddress,Recipient)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Name asc\r\n    | sort by Status desc\r\n;\r\nlet AlldataUnique = allDataRange\r\n    | join kind = innerunique     (allDataRange) on Allinfo   \r\n    | distinct \r\n        TimeGenerated,\r\n        Name,\r\n        Status,\r\n        JournalEmailAddress,\r\n        Recipient,\r\n        Allinfo\r\n;\r\nlet BeforeData =  ExchangeConfiguration(SpecificSectionList=\"JournalRule\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend Status= iff (tostring(CmdletResultValue.Enabled) == \"true\", \"Enabled\", iff(tostring(CmdletResultValue.Enabled) == \"\", \"\", \"Disabled\"))\r\n    //| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend JournalEmailAddress = tostring(CmdletResultValue.JournalEmailAddress.Address)\r\n    | extend Recipient = tostring(CmdletResultValue.Recipient.Address)\r\n    | extend Allinfo = strcat(Name,JournalEmailAddress,Recipient)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Name asc\r\n    | sort by Status desc\r\n    ;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"JournalRule\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n      | project CmdletResultValue\r\n    | extend Name = tostring(CmdletResultValue.Name)\r\n    | extend Status= iff (tostring(CmdletResultValue.Enabled) == \"true\", \"Enabled\", iff(tostring(CmdletResultValue.Enabled) == \"\", \"\", \"Disabled\"))\r\n    //| extend Enabled = tostring(CmdletResultValue.Enabled)\r\n    | extend JournalEmailAddress = tostring(CmdletResultValue.JournalEmailAddress.Address)\r\n    | extend Recipient = tostring(CmdletResultValue.Recipient.Address)\r\n    | extend Allinfo = strcat(Name,JournalEmailAddress,Recipient)\r\n    | extend CmdletResultV = tostring(CmdletResultValue)\r\n    | sort by Name asc\r\n    | sort by Status desc\r\n;\r\nlet AllnotinAfterData = AlldataUnique\r\n    | join kind = leftanti  (AfterData) on Allinfo\r\n;\r\nlet InBeforedatabotAfter = AllnotinAfterData\r\n    | join kind = innerunique    (BeforeData) on Allinfo\r\n    | extend Actiontype = iff (Name != \"\", \"Remove\", \"\")\r\n;\r\nlet AddRemoveindataset = AllnotinAfterData\r\n    | join kind = leftanti    (InBeforedatabotAfter) on Allinfo\r\n    | extend Actiontype =\"Add/Remove\"\r\n;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Allinfo\r\n    | extend Actiontype =\"Add\"\r\n;\r\nunion DiffAddData, AddRemoveindataset, InBeforedatabotAfter\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Add/Remove\", strcat(\"➕/➖ \", Actiontype), \"N/A\")\r\n| where Name <> \"\"\r\n| project\r\n    Actiontype,\r\n    Name,\r\n    Status,\r\n    JournalEmailAddress,\r\n    Recipient",
                    "size": 3,
                    "showAnalytics": true,
                    "title": "Display changes ( Add, Remove, modifications of parameters )",
                    "showExportToExcel": true,
                    "queryType": 0,
                    "resourceType": "microsoft.operationalinsights/workspaces"
                  },
                  "conditionalVisibility": {
                    "parameterName": "Compare_Collect",
                    "comparison": "isEqualTo",
                    "value": "True"
                  },
                  "name": "query - 4 - Copy - Copy - Copy - Copy - Copy"
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "Journal Recipients on mailbox databases configured in your environment",
                    "items": [
                      {
                        "type": 1,
                        "content": {
                          "json": "As Journal Recipient on databases send all the mail send to users in this database to a specific mailbox. The content of these mailboxes is very sensitive.\r\n\r\nJournal Recipients configuration should be reviewed to check if they are still needed. Mailbox audit should be set on these mailboxes. No one should have access to these mailboxes by default.\r\n\r\nIt is recommended to regularly check who have Full Access or Receive As on these mailboxes.\r\n\r\nAdditional information :\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/journaling/journaling?view=exchserver-2019\" target=\"_blank\">Journaling in Exchange Server</a>\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/journaling/journaling-procedures?view=exchserver-2019\" target=\"_blank\">Journaling procedures</a>\r\n\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/policy-and-compliance/mailbox-audit-logging/mailbox-audit-logging?view=exchserver-2019\" target=\"_blank\">Mailbox audit logging in Exchange Server</a>\r\n",
                          "style": "info"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Help",
                          "comparison": "isEqualTo",
                          "value": "Yes"
                        },
                        "name": "JournalRecipientsHelp"
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "ExchangeConfiguration(SpecificSectionList=\"MbxDBJournaling\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| where CmdletResultValue.JournalRecipient !=\"\"\r\n| project CmdletResultValue\r\n| extend Identity = tostring(CmdletResultValue.Identity.Name)\r\n| extend JournalRecipient = tostring(CmdletResultValue.JournalRecipient.Name)\r\n| project-away CmdletResultValue\r\n| sort  by Identity asc\r\n",
                          "size": 1,
                          "showAnalytics": true,
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "gridSettings": {
                            "sortBy": [
                              {
                                "itemKey": "JournalRecipient",
                                "sortOrder": 1
                              }
                            ]
                          },
                          "sortBy": [
                            {
                              "itemKey": "JournalRecipient",
                              "sortOrder": 1
                            }
                          ]
                        },
                        "name": "query - 1",
                        "styleSettings": {
                          "showBorder": true
                        }
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"MbxDBJournaling\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    | extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\n//let _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"MbxDBJournaling\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| project CmdletResultValue,WhenChanged,WhenCreated\r\n| extend Identity =  tostring(CmdletResultValue.Identity.Name)\r\n| extend JournalRecipient =  tostring(CmdletResultValue.JournalRecipient.Name)\r\n| project-away CmdletResultValue\r\n| sort  by Identity asc \r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"MbxDBJournaling\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue,WhenChanged,WhenCreated\r\n    | extend Identity =  tostring(CmdletResultValue.Identity.Name)\r\n    | extend JournalRecipient =  tostring(CmdletResultValue.JournalRecipient.Name)\r\n    | project-away CmdletResultValue\r\n    | sort  by Identity asc \r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Identity\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Identity\r\n    | extend Actiontype =\"Remove\"\r\n    | distinct\r\n        WhenChanged,\r\n        Actiontype,\r\n        Identity,\r\n        JournalRecipient,\r\n        WhenCreated        \r\n;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by Identity, WhenChanged asc\r\n    | extend JournalRecipient = iff(JournalRecipient != prev(JournalRecipient) and Identity == prev(Identity), strcat(\"📍 \", JournalRecipient, \" (\", iff(prev(JournalRecipient)==\"\",\"Null\",prev(JournalRecipient)), \"->\", JournalRecipient, \" )\"), JournalRecipient)\r\n    | extend ActiontypeR =iff(( Identity  contains \"📍\" or JournalRecipient contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Identity,\r\n        JournalRecipient,\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Identity,\r\n        JournalRecipient,\r\n        WhenCreated",
                          "size": 3,
                          "showAnalytics": true,
                          "title": "Display changes ( Add, Remove, modifications of parameters )",
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Compare_Collect",
                          "comparison": "isEqualTo",
                          "value": "True"
                        },
                        "name": "query - 4 - Copy - Copy - Copy - Copy - Copy"
                      }
                    ]
                  },
                  "name": "JournalRecipientsGroup"
                },
                {
                  "type": 12,
                  "content": {
                    "version": "NotebookGroup/1.0",
                    "groupType": "editable",
                    "title": "Remote Domain Autofoward Configuration - * should not allow AutoForwardEnabled",
                    "items": [
                      {
                        "type": 1,
                        "content": {
                          "json": "If **AutoForwardEnabled** is set to True for an SMTP domain, then users in Outlook are allowed to set automatic transfer of all their emails to addresses in this domain.\r\n\r\nWhen the Default Remote domain is set to * and has the AutoForwardEnabled set True, any user can configure an Outlook rule to automatically forward all emails to any SMTP domain domains outside the organization. This is a high risk configuration as it might allow accounts to leak information. \r\n\r\nAlso, when setting AutoForwardEnabled to a specific domain, it is strongly recommended enable TLS encryption.\r\n\r\nAdditional information:\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/remote-domains-exchange-2013-help\" target=\"_blank\">Remote Domains</a>\r\n",
                          "style": "info"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Help",
                          "comparison": "isEqualTo",
                          "value": "Yes"
                        },
                        "name": "AutoForwardHelp"
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "ExchangeConfiguration(SpecificSectionList=\"RemoteDomain\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| extend Name =  tostring(CmdletResultValue.Name)\r\n| extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n| extend AutoForwardEnabled =  iff (CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address == \"*\", strcat (\"❌\",tostring(CmdletResultValue.AutoForwardEnabled)),iff(CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address != \"*\", strcat (\"⚠️\",tostring(CmdletResultValue.AutoForwardEnabled)),strcat (\"✅\",tostring(CmdletResultValue.AutoForwardEnabled))))\r\n| project-away CmdletResultValue\r\n| sort  by Address asc ",
                          "size": 1,
                          "showAnalytics": true,
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "gridSettings": {
                            "rowLimit": 10000,
                            "filter": true
                          }
                        },
                        "name": "query - 1",
                        "styleSettings": {
                          "showBorder": true
                        }
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"RemoteDomain\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"RemoteDomain\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n| project CmdletResultValue,WhenChanged,WhenCreated\r\n| extend Name =  tostring(CmdletResultValue.Name)\r\n| extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n| extend AutoForwardEnabled =  iff (CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address == \"*\", strcat (\"❌\",tostring(CmdletResultValue.AutoForwardEnabled)),iff(CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address != \"*\", strcat (\"⚠️\",tostring(CmdletResultValue.AutoForwardEnabled)),strcat (\"✅\",tostring(CmdletResultValue.AutoForwardEnabled))))\r\n| project-away CmdletResultValue\r\n| sort  by Address asc \r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"RemoteDomain\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue,WhenChanged,WhenCreated\r\n    | extend Name =  tostring(CmdletResultValue.Name)\r\n    | extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n    | extend AutoForwardEnabled =  iff (CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address == \"*\", strcat (\"❌\",tostring(CmdletResultValue.AutoForwardEnabled)),iff(CmdletResultValue.AutoForwardEnabled== \"true\" and CmdletResultValue.Address != \"*\", strcat (\"⚠️\",tostring(CmdletResultValue.AutoForwardEnabled)),strcat (\"✅\",tostring(CmdletResultValue.AutoForwardEnabled))))\r\n    | project-away CmdletResultValue\r\n    | sort  by Address asc \r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Name\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Name\r\n    | extend Actiontype =\"Remove\"\r\n    | distinct\r\n        WhenChanged,\r\n        Actiontype,\r\n        Name,\r\n        Address,\r\n        AutoForwardEnabled,\r\n        WhenCreated        \r\n;\r\nlet DiffModifData = union BeforeData,AfterData\r\n    | sort by WhenChanged asc \r\n    | sort by Name asc\r\n    //| extend Name = iff(Name != prev(Name) and prev(Name) != \"\" , strcat(\"📍 \", Name, \" (\", prev(Name), \"->\", Name, \" )\"), Name)\r\n    | extend Address = iff(Address != prev(Address) and prev(Address) != \"\" and Name == prev(Name), strcat(\"📍 \", Address, \" (\", prev(Address), \"->\", Address, \" )\"), Address)\r\n    | extend AutoForwardEnabled = iff(AutoForwardEnabled != prev(AutoForwardEnabled) and prev(AutoForwardEnabled) != \"\" and Name == prev(Name), strcat(\"📍 \", AutoForwardEnabled, \" (\", prev(AutoForwardEnabled), \"->\", AutoForwardEnabled, \" )\"), AutoForwardEnabled)\r\n    | extend ActiontypeR =iff(( Name  contains \"📍\" or Address contains \"📍\" or AutoForwardEnabled contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Name,\r\n        Address,\r\n        AutoForwardEnabled,\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Name,\r\n        Address,\r\n        AutoForwardEnabled,\r\n        WhenCreated",
                          "size": 3,
                          "showAnalytics": true,
                          "title": "Display changes ( Add, Remove, modifications of parameters )",
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Compare_Collect",
                          "comparison": "isEqualTo",
                          "value": "True"
                        },
                        "name": "query - 4 - Copy - Copy - Copy - Copy"
                      },
                      {
                        "type": 1,
                        "content": {
                          "json": "Accepted domains set to * authorize Open Relay.\r\n\r\nMore information:\r\n\r\n<a href=\"https://learn.microsoft.com/exchange/mail-flow/accepted-domains/accepted-domains?view=exchserver-2019\" target=\"_blank\">Accepted domains</a>\r\n",
                          "style": "info"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Help",
                          "comparison": "isEqualTo",
                          "value": "Yes"
                        },
                        "name": "text - 3"
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "ExchangeConfiguration(SpecificSectionList=\"AcceptedDomain\",SpecificConfigurationDate=\"{DateOfConfiguration:value}\",SpecificConfigurationEnv={EnvironmentList},Target = \"On-Premises\")\r\n| project CmdletResultValue\r\n| where CmdletResultValue.DomainName.Address == \"*\"\r\n| extend Name =  tostring(CmdletResultValue.Name)\r\n| extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n| extend Address =  \"* : ❌ OpenRelay configuration\"\r\n| extend DomainType =  case(CmdletResultValue.DomainType==\"0\",\"Authoritative Domain\",CmdletResultValue.DomainType==\"1\",\"ExternalRelay\",CmdletResultValue.DomainType==\"2\",\"InternalRelay\",\"NotApplicable\")\r\n| project-away CmdletResultValue",
                          "size": 1,
                          "showAnalytics": true,
                          "title": "Accepted domain with *",
                          "noDataMessage": "Accepted Domain * not confirgured (no Open Relay)",
                          "noDataMessageStyle": 3,
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces",
                          "gridSettings": {
                            "rowLimit": 10000,
                            "filter": true
                          }
                        },
                        "name": "query - 4",
                        "styleSettings": {
                          "showBorder": true
                        }
                      },
                      {
                        "type": 3,
                        "content": {
                          "version": "KqlItem/1.0",
                          "query": "let _EnvList ={EnvironmentList};\r\nlet _TypeEnv = \"On-Premises\";\r\nlet _DateCompare = \"{DateCompare:value}\";\r\nlet _CurrentDate = \"{DateOfConfiguration:value}\";\r\nlet _DateCompareB = todatetime(_DateCompare);\r\nlet _currD = (ExchangeConfiguration(SpecificSectionList=\"AcceptedDomain\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | summarize TimeMax = arg_max(TimeGenerated, *)\r\n    //| extend TimeMax = tostring(split(TimeMax, \"T\")[0])\r\n    | project TimeMax);\r\nlet _CurrentDateB = todatetime(toscalar(_currD));\r\nlet BeforeData = \r\n    ExchangeConfiguration(SpecificSectionList=\"AcceptedDomain\", SpecificConfigurationDate=_DateCompareB, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue, WhenChanged, WhenCreated\r\n    | extend Name =  tostring(CmdletResultValue.Name)\r\n    | extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n    | extend DomainType =  case(CmdletResultValue.DomainType==\"0\",\"Authoritative Domain\",CmdletResultValue.DomainType==\"1\",\"ExternalRelay\",CmdletResultValue.DomainType==\"2\",\"InternalRelay\",\"NotApplicable\")\r\n    | project-away CmdletResultValue\r\n    | sort by Address asc \r\n;\r\nlet AfterData = \r\n    ExchangeConfiguration(SpecificSectionList=\"AcceptedDomain\", SpecificConfigurationDate=_CurrentDate, SpecificConfigurationEnv=_EnvList, Target = _TypeEnv)\r\n    | project CmdletResultValue, WhenChanged, WhenCreated\r\n    | extend Name =  tostring(CmdletResultValue.Name)\r\n    | extend Address =  tostring(CmdletResultValue.DomainName.Address)\r\n    | extend DomainType =  case(CmdletResultValue.DomainType==\"0\",\"Authoritative Domain\",CmdletResultValue.DomainType==\"1\",\"ExternalRelay\",CmdletResultValue.DomainType==\"2\",\"InternalRelay\",\"NotApplicable\")\r\n    | project-away CmdletResultValue\r\n    | sort by Address asc \r\n;\r\nlet i=0;\r\nlet DiffAddData = BeforeData\r\n    | join kind = rightanti  (AfterData)\r\n        on Name\r\n    | extend Actiontype =\"Add\"\r\n;\r\nlet DiffRemoveData = BeforeData\r\n    | join kind = leftanti AfterData on Name\r\n    | extend Actiontype =\"Remove\"\r\n    | distinct\r\n        WhenChanged,\r\n        Actiontype,\r\n        Name,\r\n        Address,\r\n        DomainType,\r\n        WhenCreated        \r\n;\r\nlet DiffModifData = union BeforeData, AfterData\r\n    | sort by WhenChanged asc \r\n    | sort by Name asc\r\n    // | extend Name = iff(Name != prev(Name) and prev(Name) != \"\", strcat(\"📍 \", Name, \" (\", prev(Name), \"->\", Name, \" )\"), Name)\r\n    | extend Address = iff(Address != prev(Address) and prev(Address) != \"\" and Name == prev(Name), strcat(\"📍 \", Address, \" (\", prev(Address), \"->\", Address, \" )\"), Address)\r\n    | extend DomainType = iff(DomainType != prev(DomainType) and prev(DomainType) != \"\" and Name == prev(Name), strcat(\"📍 \", DomainType, \" (\", prev(DomainType), \"->\", DomainType, \" )\"), DomainType)\r\n    | extend ActiontypeR =iff((Name contains \"📍\" or Address contains \"📍\" or DomainType contains \"📍\"), i=i + 1, i)\r\n    | extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\r\n    | where ActiontypeR == 1\r\n    | project\r\n        WhenChanged,\r\n        Actiontype,\r\n        Name,\r\n        Address,\r\n        DomainType,\r\n        WhenCreated\r\n;\r\nDiffModifData\r\n| union DiffAddData, DiffRemoveData\r\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\", WhenCreated, WhenChanged))\r\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\r\n| sort by WhenChanged desc \r\n| project\r\n    WhenChanged,\r\n    Actiontype,\r\n    Name,\r\n    Address,\r\n    DomainType,\r\n    WhenCreated",
                          "size": 3,
                          "showAnalytics": true,
                          "title": "Display changes ( Add, Remove, modifications of parameters )",
                          "showExportToExcel": true,
                          "queryType": 0,
                          "resourceType": "microsoft.operationalinsights/workspaces"
                        },
                        "conditionalVisibility": {
                          "parameterName": "Compare_Collect",
                          "comparison": "isEqualTo",
                          "value": "True"
                        },
                        "name": "query - 4 - Copy - Copy - Copy - Copy - Copy"
                      }
                    ]
                  },
                  "name": "ForwardGroup"
                }
              ]
            },
            "name": "Journal Rules"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "selected",
        "comparison": "isEqualTo",
        "value": "Transport"
      },
      "name": "Transport Security configuration"
    }
  ],
  "fromTemplateId": "sentinel-MicrosoftExchangeSecurityReview",
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}