diff --git a/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json b/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
index 9bda2566a31..8ec3c249d4c 100644
--- a/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
+++ b/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
@@ -2624,6 +2624,16 @@
"templateName": "InfobloxSOCInsightsDataConnector_API.json",
"validationFailReason": "The name 'insightId_g' does not refer to any known column, table, variable or function."
},
+ {
+ "id": "ESI-Opt6ExchangeMessageTrackingLogs",
+ "templateName": "ESI-Opt6ExchangeMessageTrackingLogs.json",
+ "validationFailReason": "This is a Azure Monitor Connector which doesnt requires more permissions. Skipping this ID as a check is failing for required permissions for Data Connector template. "
+ },
+ {
+ "id": "ESI-Opt7ExchangeHTTPProxyLogs",
+ "templateName": "ESI-Opt7ExchangeHTTPProxyLogs.json",
+ "validationFailReason": "This is a Azure Monitor Connector which doesnt requires more permissions. Skipping this ID as a check is failing for required permissions for Data Connector template. "
+ },
// Temporarily adding Data connector template id's for KQL Validations - End
@@ -2819,6 +2829,11 @@
"templateName": "ExchangeConfiguration.yaml",
"validationFailReason": "Temporarily Added for Parser KQL Queries validation"
},
+ {
+ "id": "0a0f4ea0-6b94-4420-892e-41ca985f2f01",
+ "templateName": "MESCompareDataOnPMRA.yaml",
+ "validationFailReason": "Temporarily Added for Parser KQL Queries validation"
+ },
{
"id": "1acab329-1c11-42a7-b5ea-41264947947a",
"templateName": "ExchangeEnvironmentList.yaml",
diff --git a/.script/tests/NonAsciiValidationsTests/SkipValidationsTemplates.json b/.script/tests/NonAsciiValidationsTests/SkipValidationsTemplates.json
index 7b91baea4ee..1fb5f54cb75 100644
--- a/.script/tests/NonAsciiValidationsTests/SkipValidationsTemplates.json
+++ b/.script/tests/NonAsciiValidationsTests/SkipValidationsTemplates.json
@@ -28,6 +28,11 @@
"id": "39f51672-8c63-4600-882a-5db8275f798f",
"templateName": "Microsoft Exchange Security - MESCompareDataMRA parser",
"validationFailReason": "Non-ASCII characters are required to test comparison of strings with non-ASCII characters"
+ },
+ {
+ "id": "0a0f4ea0-6b94-4420-892e-41ca985f2f01",
+ "templateName": "Microsoft Exchange Security - MESCompareDataOnPMRA parser",
+ "validationFailReason": "Non-ASCII characters are required to test comparison of strings with non-ASCII characters"
}
]
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeAdminAuditLogEvents.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeAdminAuditLogEvents.json
index b2403b8410e..51b86166103 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeAdminAuditLogEvents.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeAdminAuditLogEvents.json
@@ -1,8 +1,8 @@
{
"id": "ESI-ExchangeAdminAuditLogEvents",
- "title": "Microsoft Exchange Logs and Events",
+ "title": "[Deprecated] Microsoft Exchange Logs and Events",
"publisher": "Microsoft",
- "descriptionMarkdown": "You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "descriptionMarkdown": "Deprecated, use the 'ESI-Opt' dataconnectors. You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
"graphQueries": [
{
"metricName": "Total data received",
@@ -100,35 +100,14 @@
"customs": [
{
"description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
- }
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
]
},
"instructionSteps": [
- {
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)",
- "instructionSteps": [
- {
- "title": "1. Download the Parser file",
- "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
- "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- },
{
"description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)"
},
@@ -209,7 +188,7 @@
"instructionSteps": [
{
"title": "A. Create DCR, Type Event log",
- "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MS Exchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
}
]
},
@@ -229,7 +208,7 @@
},
{
"title": "Data Collection Rules - When the legacy Azure Log Analytics Agent is used",
- "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
+ "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MSExchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -689,15 +668,53 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "",
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"metadata": {
"id": "5738bef7-b6c0-4fec-ba0b-ac728bef83a9",
- "version": "2.2.1",
+ "version": "2.2.2",
"kind": "dataConnector",
"source": {
"kind": "solution",
- "name": "ESI - Exchange Security Configuration Analyzer"
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
},
"support": {
"name": "Community",
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeOnPremisesCollector.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeOnPremisesCollector.json
index 8a5aca66a47..ab20473cb4c 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeOnPremisesCollector.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-ExchangeOnPremisesCollector.json
@@ -19,7 +19,7 @@
"dataTypes": [
{
"name": "ESIExchangeConfig_CL",
- "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time)"
+ "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time) |summarize Time = max(Time) | project Time"
}
],
"connectivityCriterias": [
@@ -61,40 +61,14 @@
{
"name": "Service Account with Organization Management role",
"description": "The service Account that launch the script as scheduled task needs to be Organization Management to be able to retrieve all the needed security Information."
- }
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
]
},
"instructionSteps": [
- {
- "title": "Parser deployment **(When using Microsoft Exchange Security Solution, Parsers are automatically deployed)**",
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps for each Parser to create the Kusto Functions alias : [**ExchangeConfiguration**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parsers deployment",
- "instructionSteps": [
- {
- "title": "1. Download the Parser files",
- "description": "The latest version of the 2 files [**ExchangeConfiguration.yaml**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList.yaml**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeConfiguration** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeConfiguration** function",
- "description": "Click on save button.\n Define the parameters as asked on the header of the parser file.\nClick save again."
- },
- {
- "title": "4. Reproduce the same steps for Parser **ExchangeEnvironmentList**",
- "description": "Reproduce the step 2 and 3 with the content of 'ExchangeEnvironmentList.yaml' file"
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- },
{
"title": "1. Install the ESI Collector Script on a server with Exchange Admin PowerShell console",
"description": "This is the script that will collect Exchange Information to push content in Microsoft Sentinel.\n ",
@@ -152,11 +126,49 @@
{
"title": "3. Schedule the ESI Collector Script (If not done by the Install Script due to lack of permission or ignored during installation)",
"description": "The script needs to be scheduled to send Exchange configuration to Microsoft Sentinel.\n We recommend to schedule the script once a day.\n The account used to launch the Script needs to be member of the group Organization Management"
+ },
+ {
+ "title": "",
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"metadata": {
"id": "ed950fd7-e457-4a59-88f0-b9c949aa280d",
- "version": "1.2.1",
+ "version": "1.2.2",
"kind": "dataConnector",
"source": {
"kind": "solution",
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt1ExchangeAdminAuditLogsByEventLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt1ExchangeAdminAuditLogsByEventLogs.json
new file mode 100644
index 00000000000..fa1ad2c7c2e
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt1ExchangeAdminAuditLogsByEventLogs.json
@@ -0,0 +1,199 @@
+{
+ "id": "ESI-Opt1ExchangeAdminAuditLogsByEventLogs",
+ "title": "Microsoft Exchange Admin Audit Logs by Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 1] - Using Azure Monitor Agent - You can stream all Exchange Audit events from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "ExchangeAuditLogs",
+ "baseQuery": "Event | where EventLog == 'MSExchange Management'"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'MSExchange Management' | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'MSExchange Management' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'MSExchange Management' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 1** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "2. [Option 1] MS Exchange Management Log collection - MS Exchange Admin Audit event logs by Data Collection Rules",
+ "description": "The MS Exchange Admin Audit event logs are collected using Data Collection Rules (DCR) and allow to store all Administrative Cmdlets executed in an Exchange environment.",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "DCR",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules Deployment",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption1-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "",
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "dfa2e270-b24f-4d76-b9a5-cd4a878596bf",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt2ExchangeServersEventLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt2ExchangeServersEventLogs.json
new file mode 100644
index 00000000000..f980fc45731
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt2ExchangeServersEventLogs.json
@@ -0,0 +1,183 @@
+{
+ "id": "ESI-Opt2ExchangeServersEventLogs",
+ "title": "Microsoft Exchange Logs and Events",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 2] - Using Azure Monitor Agent - You can stream all Exchange Security & Application Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Eventlogs",
+ "baseQuery": "Event | where EventLog == 'Application'"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'Application' | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'Application' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'Application' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 2** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "2. [Option 2] Security/Application/System logs of Exchange Servers",
+ "description": "The Security/Application/System logs of Exchange Servers are collected using Data Collection Rules (DCR).",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add Exchange Servers on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Application and System Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> Application and System Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered method)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption2-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Basic' option.\n6. For Application, select 'Critical', 'Error' and 'Warning'. For System, select Critical/Error/Warning/Information. \n7. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "22e0234b-278d-40f4-8be8-c2968faeaf91",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt34DomainControllersSecurityEventLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt34DomainControllersSecurityEventLogs.json
new file mode 100644
index 00000000000..8084de0ae36
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt34DomainControllersSecurityEventLogs.json
@@ -0,0 +1,151 @@
+{
+ "id": "ESI-Opt34DomainControllersSecurityEventLogs",
+ "title": " Microsoft Active-Directory Domain Controllers Security Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 3 & 4] - Using Azure Monitor Agent -You can stream a part or all Domain Controllers Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Domain Controllers Security Logs",
+ "baseQuery": "SecurityEvent"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "SecurityEvent | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "SecurityEvent",
+ "lastDataReceivedQuery": "SecurityEvent | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "SecurityEvent | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 3 and 4** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Security logs of Domain Controllers",
+ "description": "Select how to stream Security logs of Domain Controllers. If you want to implement Option 3, you just need to select DC on same site as Exchange Servers. If you want to implement Option 4, you can select all DCs of your forest.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "[Option 3] List only Domain Controllers on the same site as Exchange Servers for next step",
+ "description": "**This limits the quantity of data injested but some incident can't be detected.**"
+ },
+ {
+ "title": "[Option 4] List all Domain Controllers of your Active-Directory Forest for next step",
+ "description": "**This allows collecting all security events**"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add chosen DCs on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "036e16af-5a27-465a-8662-b7ac385a8d45",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt5ExchangeIISLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt5ExchangeIISLogs.json
new file mode 100644
index 00000000000..5e0f308c123
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt5ExchangeIISLogs.json
@@ -0,0 +1,184 @@
+{
+ "id": "ESI-Opt5ExchangeIISLogs",
+ "title": "IIS Logs of Microsoft Exchange Servers",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 5] - Using Azure Monitor Agent - You can stream all IIS Logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange IIS logs",
+ "baseQuery": "W3CIISLog"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "W3CIISLog | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "W3CIISLog",
+ "lastDataReceivedQuery": "W3CIISLog | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "W3CIISLog | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 5** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "[Option 5] IIS logs of Exchange Servers",
+ "description": "Select how to stream IIS logs of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> IIS logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "type": "AdminAuditEvents"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Preferred Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption5-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create DCR, Type IIS log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. Select the created DCE. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'IIS logs' (Do not enter a path if IIS Logs path is configured by default). Click on 'Add data source'\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "4b1075ed-80f5-4930-bfe1-877e86b48dc1",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt6ExchangeMessageTrackingLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt6ExchangeMessageTrackingLogs.json
new file mode 100644
index 00000000000..932d31bfe5e
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt6ExchangeMessageTrackingLogs.json
@@ -0,0 +1,201 @@
+{
+ "id": "ESI-Opt6ExchangeMessageTrackingLogs",
+ "title": "Microsoft Exchange Message Tracking Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 6] - Using Azure Monitor Agent - You can stream all Exchange Message Tracking from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. Those logs can be used to track the flow of messages in your Exchange environment. This data connector is based on the option 6 of the [Microsoft Exchange Security wiki](https://aka.ms/ESI_DataConnectorOptions).",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Message Tracking logs",
+ "baseQuery": "MessageTrackingLog_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Exchange Message Tracking logs",
+ "query": "MessageTrackingLog_CL | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "MessageTrackingLog_CL",
+ "lastDataReceivedQuery": "MessageTrackingLog_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "MessageTrackingLog_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 6** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "2. Message Tracking of Exchange Servers",
+ "description": "Select how to stream Message Tracking of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule and Custom Table",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption6-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-MessageTrackingCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t\"schema\": {\n\t\t\t\t\t \"name\": \"MessageTrackingLog_CL\",\n\t\t\t\t\t \"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"directionality\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"reference\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"source\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientIP\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"connectorId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"customData\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"eventId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"internalMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"logId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageSubject\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"networkMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalClientIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalServerIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientCount\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"relatedRecipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"returnPath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"serverIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"sourceContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"schemaVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageTrackingTenantId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"totalBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"transportTrafficType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t'@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/MessageTrackingLog_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE, like ESI-ExchangeServers. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option6-MessageTrackingLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter 'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\TransportRoles\\Logs\\MessageTracking\\*.log' in file pattern, 'MessageTrackingLog_CL' in Table Name.\n6.in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend TimeGenerated =todatetime(d[0]) ,clientIP =tostring(d[1]) ,clientHostname =tostring(d[2]) ,serverIp=tostring(d[3]) ,senderHostname=tostring(d[4]) ,sourceContext=tostring(d[5]) ,connectorId =tostring(d[6]) ,source=tostring(d[7]) ,eventId =tostring(d[8]) ,internalMessageId =tostring(d[9]) ,messageId =tostring(d[10]) ,networkMessageId =tostring(d[11]) ,recipientAddress=tostring(d[12]) ,recipientStatus=tostring(d[13]) ,totalBytes=tostring(d[14]) ,recipientCount=tostring(d[15]) ,relatedRecipientAddress=tostring(d[16]) ,reference=tostring(d[17]) ,messageSubject =tostring(d[18]) ,senderAddress=tostring(d[19]) ,returnPath=tostring(d[20]) ,messageInfo =tostring(d[21]) ,directionality=tostring(d[22]) ,messageTrackingTenantId =tostring(d[23]) ,originalClientIp =tostring(d[24]) ,originalServerIp =tostring(d[25]) ,customData=tostring(d[26]) ,transportTrafficType =tostring(d[27]) ,logId =tostring(d[28]) ,schemaVersion=tostring(d[29]) | project-away d,RawData\n and click on 'Destination'.\n6. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n7. Click on 'Add data source'.\n8. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "ababbb06-b977-4259-ab76-87874d353039",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt7ExchangeHTTPProxyLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt7ExchangeHTTPProxyLogs.json
new file mode 100644
index 00000000000..c65ebb89cd5
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/ESI-Opt7ExchangeHTTPProxyLogs.json
@@ -0,0 +1,201 @@
+{
+ "id": "ESI-Opt7ExchangeHTTPProxyLogs",
+ "title": "Microsoft Exchange HTTP Proxy Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 7] - Using Azure Monitor Agent - You can stream HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you create custom alerts, and improve investigation. [Learn more](https://aka.ms/ESI_DataConnectorOptions)",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange HTTPProxy logs",
+ "baseQuery": "ExchangeHttpProxy_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "ExchangeHttpProxy_CL | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "ExchangeHttpProxy_CL",
+ "lastDataReceivedQuery": "ExchangeHttpProxy_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "ExchangeHttpProxy_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 7** of the wiki."
+ },
+ {
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel",
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "2. [Option 7] HTTP Proxy of Exchange Servers",
+ "description": "Select how to stream HTTP Proxy of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption7-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-HTTPProxyCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t \"schema\": {\n\t\t\t\t\t\t\"name\": \"ExchangeHttpProxy_CL\",\n\t\t\t\t\t\t\"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AccountForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ActivityContextLifeTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ADLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AnchorMailbox\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticatedUser\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticationType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthModulePerfContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndCookie\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndGenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendProcessingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BuildVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CalculateTargetBackEndLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientIpAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CoreLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"DatabaseGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"EdgeTraceId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ErrorCode\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericErrors\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GlsLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerCompletionLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerToModuleSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpPipelineLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpProxyOverhead\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"IsAuthenticated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"KerberosAuthHeaderLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MajorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Method\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MinorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ModuleToHandlerSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Organization\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"PartitionEndpointLookupLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Protocol\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProtocolAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestHandlerLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResourceForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResponseBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RevisionVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RouteRefresherLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingHint\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerHostName\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"SharedCacheLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetOutstandingRequests\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServer\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServerVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalAccountForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalGlsLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalRequestTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalResourceForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalSharedCacheLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlQuery\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlStem\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserADObjectGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserAgent\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t }\n\t\t\t }\n\t\t }\n\t\t '@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/ExchangeHttpProxy_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option7-HTTPProxyLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter the following file pattern : \n\t\t'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Autodiscover\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Eas\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ecp\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ews\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Mapi\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Oab\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Owa\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\OwaCalendar\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\PowerShell\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\RpcHttp\\*.log'\n6. Put 'ExchangeHttpProxy_CL' in Table Name.\n7. in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend DateTime=todatetime(d[0]),RequestId=tostring(d[1]) ,MajorVersion=tostring(d[2]) ,MinorVersion=tostring(d[3]) ,BuildVersion=tostring(d[4]) ,RevisionVersion=tostring(d[5]) ,ClientRequestId=tostring(d[6]) ,Protocol=tostring(d[7]) ,UrlHost=tostring(d[8]) ,UrlStem=tostring(d[9]) ,ProtocolAction=tostring(d[10]) ,AuthenticationType=tostring(d[11]) ,IsAuthenticated=tostring(d[12]) ,AuthenticatedUser=tostring(d[13]) ,Organization=tostring(d[14]) ,AnchorMailbox=tostring(d[15]) ,UserAgent=tostring(d[16]) ,ClientIpAddress=tostring(d[17]) ,ServerHostName=tostring(d[18]) ,HttpStatus=tostring(d[19]) ,BackEndStatus=tostring(d[20]) ,ErrorCode=tostring(d[21]) ,Method=tostring(d[22]) ,ProxyAction=tostring(d[23]) ,TargetServer=tostring(d[24]) ,TargetServerVersion=tostring(d[25]) ,RoutingType=tostring(d[26]) ,RoutingHint=tostring(d[27]) ,BackEndCookie=tostring(d[28]) ,ServerLocatorHost=tostring(d[29]) ,ServerLocatorLatency=tostring(d[30]) ,RequestBytes=tostring(d[31]) ,ResponseBytes=tostring(d[32]) ,TargetOutstandingRequests=tostring(d[33]) ,AuthModulePerfContext=tostring(d[34]) ,HttpPipelineLatency=tostring(d[35]) ,CalculateTargetBackEndLatency=tostring(d[36]) ,GlsLatencyBreakup=tostring(d[37]) ,TotalGlsLatency=tostring(d[38]) ,AccountForestLatencyBreakup=tostring(d[39]) ,TotalAccountForestLatency=tostring(d[40]) ,ResourceForestLatencyBreakup=tostring(d[41]) ,TotalResourceForestLatency=tostring(d[42]) ,ADLatency=tostring(d[43]) ,SharedCacheLatencyBreakup=tostring(d[44]) ,TotalSharedCacheLatency=tostring(d[45]) ,ActivityContextLifeTime=tostring(d[46]) ,ModuleToHandlerSwitchingLatency=tostring(d[47]) ,ClientReqStreamLatency=tostring(d[48]) ,BackendReqInitLatency=tostring(d[49]) ,BackendReqStreamLatency=tostring(d[50]) ,BackendProcessingLatency=tostring(d[51]) ,BackendRespInitLatency=tostring(d[52]) ,BackendRespStreamLatency=tostring(d[53]) ,ClientRespStreamLatency=tostring(d[54]) ,KerberosAuthHeaderLatency=tostring(d[55]) ,HandlerCompletionLatency=tostring(d[56]) ,RequestHandlerLatency=tostring(d[57]) ,HandlerToModuleSwitchingLatency=tostring(d[58]) ,ProxyTime=tostring(d[59]) ,CoreLatency=tostring(d[60]) ,RoutingLatency=tostring(d[61]) ,HttpProxyOverhead=tostring(d[62]) ,TotalRequestTime=tostring(d[63]) ,RouteRefresherLatency=tostring(d[64]) ,UrlQuery=tostring(d[65]) ,BackEndGenericInfo=tostring(d[66]) ,GenericInfo=tostring(d[67]) ,GenericErrors=tostring(d[68]) ,EdgeTraceId=tostring(d[69]) ,DatabaseGuid=tostring(d[70]) ,UserADObjectGuid=tostring(d[71]) ,PartitionEndpointLookupLatency=tostring(d[72]) ,RoutingStatus=tostring(d[73]) | extend TimeGenerated = DateTime | project-away d,RawData,DateTime | project-away d,RawData,DateTime\n and click on 'Destination'.\n8. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n9. Click on 'Add data source'.\n10. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "2e63ad0e-84e3-4f01-b210-9db0bc42b8ff",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking-TableOnly.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking-TableOnly.json
new file mode 100644
index 00000000000..da00c86f02b
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking-TableOnly.json
@@ -0,0 +1,160 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "workspacename": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "The log analitycs workspace name"
+ }
+ },
+ "customtablename": {
+ "type": "string",
+ "defaultValue": "MessageTrackingLog_CL",
+ "minLength": 1,
+ "metadata": {
+ "description": "The name of the Custom Table to create. By default uses 'MessageTrackingLog_CL', but you can change it to any other name but do it carefully and with full knowledge of the facts ."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-12-01-preview",
+ "name": "[concat(parameters('workspacename'), '/', parameters('customtablename'))]",
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "[parameters('customtablename')]",
+ "columns": [
+ {
+ "name": "directionality",
+ "type": "string"
+ },
+ {
+ "name": "reference",
+ "type": "string"
+ },
+ {
+ "name": "source",
+ "type": "string"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "clientHostname",
+ "type": "string"
+ },
+ {
+ "name": "clientIP",
+ "type": "string"
+ },
+ {
+ "name": "connectorId",
+ "type": "string"
+ },
+ {
+ "name": "customData",
+ "type": "string"
+ },
+ {
+ "name": "eventId",
+ "type": "string"
+ },
+ {
+ "name": "internalMessageId",
+ "type": "string"
+ },
+ {
+ "name": "logId",
+ "type": "string"
+ },
+ {
+ "name": "messageId",
+ "type": "string"
+ },
+ {
+ "name": "messageInfo",
+ "type": "string"
+ },
+ {
+ "name": "messageSubject",
+ "type": "string"
+ },
+ {
+ "name": "networkMessageId",
+ "type": "string"
+ },
+ {
+ "name": "originalClientIp",
+ "type": "string"
+ },
+ {
+ "name": "originalServerIp",
+ "type": "string"
+ },
+ {
+ "name": "recipientAddress",
+ "type": "string"
+ },
+ {
+ "name": "recipientCount",
+ "type": "string"
+ },
+ {
+ "name": "recipientStatus",
+ "type": "string"
+ },
+ {
+ "name": "relatedRecipientAddress",
+ "type": "string"
+ },
+ {
+ "name": "returnPath",
+ "type": "string"
+ },
+ {
+ "name": "senderAddress",
+ "type": "string"
+ },
+ {
+ "name": "senderHostname",
+ "type": "string"
+ },
+ {
+ "name": "serverIp",
+ "type": "string"
+ },
+ {
+ "name": "sourceContext",
+ "type": "string"
+ },
+ {
+ "name": "schemaVersion",
+ "type": "string"
+ },
+ {
+ "name": "messageTrackingTenantId",
+ "type": "string"
+ },
+ {
+ "name": "totalBytes",
+ "type": "string"
+ },
+ {
+ "name": "transportTrafficType",
+ "type": "string"
+ },
+ {
+ "name": "FilePath",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking.json
index 9404db100a3..f61e15bb767 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option6-MessageTracking.json
@@ -49,7 +49,6 @@
"apiVersion": "2021-12-01-preview",
"name": "[concat(parameters('workspacename'), '/MessageTrackingLog_CL')]",
"properties": {
- "totalRetentionInDays": 90,
"plan": "Analytics",
"schema": {
"name": "MessageTrackingLog_CL",
@@ -173,10 +172,13 @@
{
"name": "transportTrafficType",
"type": "string"
+ },
+ {
+ "name": "FilePath",
+ "type": "string"
}
]
- },
- "retentionInDays": 90
+ }
}
},
{
@@ -194,123 +196,15 @@
"Custom-MessageTrackingLog_CL": {
"columns": [
{
- "name": "date-time",
+ "name": "TimeGenerated",
"type": "datetime"
},
{
- "name": "client-ip",
- "type": "string"
- },
- {
- "name": "client-hostname",
- "type": "string"
- },
- {
- "name": "server-ip",
- "type": "string"
- },
- {
- "name": "server-hostname",
- "type": "string"
- },
- {
- "name": "source-context",
- "type": "string"
- },
- {
- "name": "connector-id",
- "type": "string"
- },
- {
- "name": "source",
- "type": "string"
- },
- {
- "name": "event-id",
- "type": "string"
- },
- {
- "name": "internal-message-id",
- "type": "string"
- },
- {
- "name": "message-id",
- "type": "string"
- },
- {
- "name": "network-message-id",
- "type": "string"
- },
- {
- "name": "recipient-address",
- "type": "string"
- },
- {
- "name": "recipient-status",
- "type": "string"
- },
- {
- "name": "total-bytes",
- "type": "string"
- },
- {
- "name": "recipient-count",
- "type": "string"
- },
- {
- "name": "related-recipient-address",
- "type": "string"
- },
- {
- "name": "reference",
- "type": "string"
- },
- {
- "name": "message-subject",
- "type": "string"
- },
- {
- "name": "sender-address",
- "type": "string"
- },
- {
- "name": "return-path",
- "type": "string"
- },
- {
- "name": "message-info",
- "type": "string"
- },
- {
- "name": "directionality",
- "type": "string"
- },
- {
- "name": "tenant-id",
- "type": "string"
- },
- {
- "name": "original-client-ip",
- "type": "string"
- },
- {
- "name": "original-server-ip",
- "type": "string"
- },
- {
- "name": "custom-data",
- "type": "string"
- },
- {
- "name": "transport-traffic-type",
- "type": "string"
- },
- {
- "name": "log-id",
+ "name": "RawData",
"type": "string"
},
{
- "name": "schema-version",
+ "name": "FilePath",
"type": "string"
}
]
@@ -351,7 +245,7 @@
"destinations": [
"la-data-destination"
],
- "transformKql": "source\n| extend TimeGenerated = todatetime(['date-time'])\n| extend\n clientHostname = ['client-hostname'],\n clientIP = ['client-ip'],\n connectorId = ['connector-id'],\n customData = ['custom-data'],\n eventId = ['event-id'],\n internalMessageId = ['internal-message-id'],\n logId = ['log-id'],\n messageId = ['message-id'],\n messageInfo = ['message-info'],\n messageSubject = ['message-subject'],\n networkMessageId = ['network-message-id'],\n originalClientIp = ['original-client-ip'],\n originalServerIp = ['original-server-ip'],\n recipientAddress= ['recipient-address'],\n recipientCount= ['recipient-count'],\n recipientStatus= ['recipient-status'],\n relatedRecipientAddress= ['related-recipient-address'],\n returnPath= ['return-path'],\n senderAddress= ['sender-address'],\n senderHostname= ['server-hostname'],\n serverIp= ['server-ip'],\n sourceContext= ['source-context'],\n schemaVersion=['schema-version'],\n messageTrackingTenantId = ['tenant-id'],\n totalBytes = ['total-bytes'],\n transportTrafficType = ['transport-traffic-type']\n| project-away\n ['client-ip'],\n ['client-hostname'],\n ['connector-id'],\n ['custom-data'],\n ['date-time'],\n ['event-id'],\n ['internal-message-id'],\n ['log-id'],\n ['message-id'],\n ['message-info'],\n ['message-subject'],\n ['network-message-id'],\n ['original-client-ip'],\n ['original-server-ip'],\n ['recipient-address'],\n ['recipient-count'],\n ['recipient-status'],\n ['related-recipient-address'],\n ['return-path'],\n ['sender-address'],\n ['server-hostname'],\n ['server-ip'],\n ['source-context'],\n ['schema-version'],\n ['tenant-id'],\n ['total-bytes'],\n ['transport-traffic-type']\n\n",
+ "transformKql": "source\n| extend d = split(RawData,',') | extend TimeGenerated =todatetime(d[0]) ,clientIP =tostring(d[1]) ,clientHostname =tostring(d[2]) ,serverIp=tostring(d[3]) ,senderHostname=tostring(d[4]) ,sourceContext=tostring(d[5]) ,connectorId =tostring(d[6]) ,source=tostring(d[7]) ,eventId =tostring(d[8]) ,internalMessageId =tostring(d[9]) ,messageId =tostring(d[10]) ,networkMessageId =tostring(d[11]) ,recipientAddress=tostring(d[12]) ,recipientStatus=tostring(d[13]) ,totalBytes=tostring(d[14]) ,recipientCount=tostring(d[15]) ,relatedRecipientAddress=tostring(d[16]) ,reference=tostring(d[17]) ,messageSubject =tostring(d[18]) ,senderAddress=tostring(d[19]) ,returnPath=tostring(d[20]) ,messageInfo =tostring(d[21]) ,directionality=tostring(d[22]) ,messageTrackingTenantId =tostring(d[23]) ,originalClientIp =tostring(d[24]) ,originalServerIp =tostring(d[25]) ,customData=tostring(d[26]) ,transportTrafficType =tostring(d[27]) ,logId =tostring(d[28]) ,schemaVersion=tostring(d[29]) | project-away d,RawData",
"outputStream": "Custom-MessageTrackingLog_CL"
}
]
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy-Table.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy-Table.json
new file mode 100644
index 00000000000..87a869d2ed2
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy-Table.json
@@ -0,0 +1,336 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "workspacename": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "The log analitycs workspace name"
+ }
+ },
+ "customtablename": {
+ "type": "string",
+ "defaultValue": "ExchangeHttpProxy_CL",
+ "minLength": 1,
+ "metadata": {
+ "description": "The name of the Custom Table to create. By default uses 'ExchangeHttpProxy_CL', but you can change it to any other name but do it carefully and with full knowledge of the facts ."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/tables",
+ "apiVersion": "2021-12-01-preview",
+ "name": "[concat(parameters('workspacename'), '/', parameters('customtablename'))]",
+ "properties": {
+ "plan": "Analytics",
+ "schema": {
+ "name": "[parameters('customtablename')]",
+ "columns": [
+ {
+ "name": "AccountForestLatencyBreakup",
+ "type": "string"
+ },
+ {
+ "name": "ActivityContextLifeTime",
+ "type": "string"
+ },
+ {
+ "name": "ADLatency",
+ "type": "string"
+ },
+ {
+ "name": "AnchorMailbox",
+ "type": "string"
+ },
+ {
+ "name": "AuthenticatedUser",
+ "type": "string"
+ },
+ {
+ "name": "AuthenticationType",
+ "type": "string"
+ },
+ {
+ "name": "AuthModulePerfContext",
+ "type": "string"
+ },
+ {
+ "name": "BackEndCookie",
+ "type": "string"
+ },
+ {
+ "name": "BackEndGenericInfo",
+ "type": "string"
+ },
+ {
+ "name": "BackendProcessingLatency",
+ "type": "string"
+ },
+ {
+ "name": "BackendReqInitLatency",
+ "type": "string"
+ },
+ {
+ "name": "BackendReqStreamLatency",
+ "type": "string"
+ },
+ {
+ "name": "BackendRespInitLatency",
+ "type": "string"
+ },
+ {
+ "name": "BackendRespStreamLatency",
+ "type": "string"
+ },
+ {
+ "name": "BackEndStatus",
+ "type": "string"
+ },
+ {
+ "name": "BuildVersion",
+ "type": "string"
+ },
+ {
+ "name": "CalculateTargetBackEndLatency",
+ "type": "string"
+ },
+ {
+ "name": "ClientIpAddress",
+ "type": "string"
+ },
+ {
+ "name": "ClientReqStreamLatency",
+ "type": "string"
+ },
+ {
+ "name": "ClientRequestId",
+ "type": "string"
+ },
+ {
+ "name": "ClientRespStreamLatency",
+ "type": "string"
+ },
+ {
+ "name": "CoreLatency",
+ "type": "string"
+ },
+ {
+ "name": "DatabaseGuid",
+ "type": "string"
+ },
+ {
+ "name": "EdgeTraceId",
+ "type": "string"
+ },
+ {
+ "name": "ErrorCode",
+ "type": "string"
+ },
+ {
+ "name": "GenericErrors",
+ "type": "string"
+ },
+ {
+ "name": "GenericInfo",
+ "type": "string"
+ },
+ {
+ "name": "GlsLatencyBreakup",
+ "type": "string"
+ },
+ {
+ "name": "HandlerCompletionLatency",
+ "type": "string"
+ },
+ {
+ "name": "HandlerToModuleSwitchingLatency",
+ "type": "string"
+ },
+ {
+ "name": "HttpPipelineLatency",
+ "type": "string"
+ },
+ {
+ "name": "HttpProxyOverhead",
+ "type": "string"
+ },
+ {
+ "name": "HttpStatus",
+ "type": "string"
+ },
+ {
+ "name": "IsAuthenticated",
+ "type": "string"
+ },
+ {
+ "name": "KerberosAuthHeaderLatency",
+ "type": "string"
+ },
+ {
+ "name": "MajorVersion",
+ "type": "string"
+ },
+ {
+ "name": "Method",
+ "type": "string"
+ },
+ {
+ "name": "MinorVersion",
+ "type": "string"
+ },
+ {
+ "name": "ModuleToHandlerSwitchingLatency",
+ "type": "string"
+ },
+ {
+ "name": "Organization",
+ "type": "string"
+ },
+ {
+ "name": "PartitionEndpointLookupLatency",
+ "type": "string"
+ },
+ {
+ "name": "Protocol",
+ "type": "string"
+ },
+ {
+ "name": "ProtocolAction",
+ "type": "string"
+ },
+ {
+ "name": "ProxyAction",
+ "type": "string"
+ },
+ {
+ "name": "ProxyTime",
+ "type": "string"
+ },
+ {
+ "name": "RequestBytes",
+ "type": "string"
+ },
+ {
+ "name": "RequestHandlerLatency",
+ "type": "string"
+ },
+ {
+ "name": "RequestId",
+ "type": "string"
+ },
+ {
+ "name": "ResourceForestLatencyBreakup",
+ "type": "string"
+ },
+ {
+ "name": "ResponseBytes",
+ "type": "string"
+ },
+ {
+ "name": "RevisionVersion",
+ "type": "string"
+ },
+ {
+ "name": "RouteRefresherLatency",
+ "type": "string"
+ },
+ {
+ "name": "RoutingHint",
+ "type": "string"
+ },
+ {
+ "name": "RoutingLatency",
+ "type": "string"
+ },
+ {
+ "name": "RoutingStatus",
+ "type": "string"
+ },
+ {
+ "name": "RoutingType",
+ "type": "string"
+ },
+ {
+ "name": "ServerHostName",
+ "type": "string"
+ },
+ {
+ "name": "ServerLocatorHost",
+ "type": "string"
+ },
+ {
+ "name": "ServerLocatorLatency",
+ "type": "string"
+ },
+ {
+ "name": "SharedCacheLatencyBreakup",
+ "type": "string"
+ },
+ {
+ "name": "TargetOutstandingRequests",
+ "type": "string"
+ },
+ {
+ "name": "TargetServer",
+ "type": "string"
+ },
+ {
+ "name": "TargetServerVersion",
+ "type": "string"
+ },
+ {
+ "name": "TotalAccountForestLatency",
+ "type": "string"
+ },
+ {
+ "name": "TotalGlsLatency",
+ "type": "string"
+ },
+ {
+ "name": "TotalRequestTime",
+ "type": "string"
+ },
+ {
+ "name": "TotalResourceForestLatency",
+ "type": "string"
+ },
+ {
+ "name": "TotalSharedCacheLatency",
+ "type": "string"
+ },
+ {
+ "name": "UrlHost",
+ "type": "string"
+ },
+ {
+ "name": "UrlQuery",
+ "type": "string"
+ },
+ {
+ "name": "UrlStem",
+ "type": "string"
+ },
+ {
+ "name": "UserADObjectGuid",
+ "type": "string"
+ },
+ {
+ "name": "UserAgent",
+ "type": "string"
+ },
+ {
+ "name": "TimeGenerated",
+ "type": "datetime"
+ },
+ {
+ "name": "FilePath",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy.json
index 737dee3b406..72c0dfbc830 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_Option7-HTTPProxy.json
@@ -49,7 +49,6 @@
"apiVersion": "2021-12-01-preview",
"name": "[concat(parameters('workspacename'), '/ExchangeHttpProxy_CL')]",
"properties": {
- "totalRetentionInDays": 90,
"plan": "Analytics",
"schema": {
"name": "ExchangeHttpProxy_CL",
@@ -349,10 +348,13 @@
{
"name": "TimeGenerated",
"type": "datetime"
+ },
+ {
+ "name": "FilePath",
+ "type": "string"
}
]
- },
- "retentionInDays": 90
+ }
}
},
{
@@ -374,299 +376,11 @@
"type": "datetime"
},
{
- "name": "DateTime",
- "type": "string"
- },
- {
- "name": "RequestId",
- "type": "string"
- },
- {
- "name": "MajorVersion",
- "type": "string"
- },
- {
- "name": "MinorVersion",
- "type": "string"
- },
- {
- "name": "BuildVersion",
- "type": "string"
- },
- {
- "name": "RevisionVersion",
- "type": "string"
- },
- {
- "name": "ClientRequestId",
- "type": "string"
- },
- {
- "name": "Protocol",
- "type": "string"
- },
- {
- "name": "UrlHost",
- "type": "string"
- },
- {
- "name": "UrlStem",
- "type": "string"
- },
- {
- "name": "ProtocolAction",
- "type": "string"
- },
- {
- "name": "AuthenticationType",
- "type": "string"
- },
- {
- "name": "IsAuthenticated",
- "type": "string"
- },
- {
- "name": "AuthenticatedUser",
- "type": "string"
- },
- {
- "name": "Organization",
- "type": "string"
- },
- {
- "name": "AnchorMailbox",
- "type": "string"
- },
- {
- "name": "UserAgent",
- "type": "string"
- },
- {
- "name": "ClientIpAddress",
- "type": "string"
- },
- {
- "name": "ServerHostName",
- "type": "string"
- },
- {
- "name": "HttpStatus",
- "type": "string"
- },
- {
- "name": "BackEndStatus",
- "type": "string"
- },
- {
- "name": "ErrorCode",
- "type": "string"
- },
- {
- "name": "Method",
- "type": "string"
- },
- {
- "name": "ProxyAction",
- "type": "string"
- },
- {
- "name": "TargetServer",
- "type": "string"
- },
- {
- "name": "TargetServerVersion",
- "type": "string"
- },
- {
- "name": "RoutingType",
- "type": "string"
- },
- {
- "name": "RoutingHint",
- "type": "string"
- },
- {
- "name": "BackEndCookie",
- "type": "string"
- },
- {
- "name": "ServerLocatorHost",
- "type": "string"
- },
- {
- "name": "ServerLocatorLatency",
- "type": "string"
- },
- {
- "name": "RequestBytes",
- "type": "string"
- },
- {
- "name": "ResponseBytes",
- "type": "string"
- },
- {
- "name": "TargetOutstandingRequests",
- "type": "string"
- },
- {
- "name": "AuthModulePerfContext",
- "type": "string"
- },
- {
- "name": "HttpPipelineLatency",
- "type": "string"
- },
- {
- "name": "CalculateTargetBackEndLatency",
- "type": "string"
- },
- {
- "name": "GlsLatencyBreakup",
- "type": "string"
- },
- {
- "name": "TotalGlsLatency",
- "type": "string"
- },
- {
- "name": "AccountForestLatencyBreakup",
- "type": "string"
- },
- {
- "name": "TotalAccountForestLatency",
- "type": "string"
- },
- {
- "name": "ResourceForestLatencyBreakup",
- "type": "string"
- },
- {
- "name": "TotalResourceForestLatency",
- "type": "string"
- },
- {
- "name": "ADLatency",
- "type": "string"
- },
- {
- "name": "SharedCacheLatencyBreakup",
- "type": "string"
- },
- {
- "name": "TotalSharedCacheLatency",
- "type": "string"
- },
- {
- "name": "ActivityContextLifeTime",
- "type": "string"
- },
- {
- "name": "ModuleToHandlerSwitchingLatency",
- "type": "string"
- },
- {
- "name": "ClientReqStreamLatency",
- "type": "string"
- },
- {
- "name": "BackendReqInitLatency",
- "type": "string"
- },
- {
- "name": "BackendReqStreamLatency",
- "type": "string"
- },
- {
- "name": "BackendProcessingLatency",
- "type": "string"
- },
- {
- "name": "BackendRespInitLatency",
- "type": "string"
- },
- {
- "name": "BackendRespStreamLatency",
- "type": "string"
- },
- {
- "name": "ClientRespStreamLatency",
- "type": "string"
- },
- {
- "name": "KerberosAuthHeaderLatency",
- "type": "string"
- },
- {
- "name": "HandlerCompletionLatency",
- "type": "string"
- },
- {
- "name": "RequestHandlerLatency",
- "type": "string"
- },
- {
- "name": "HandlerToModuleSwitchingLatency",
- "type": "string"
- },
- {
- "name": "ProxyTime",
- "type": "string"
- },
- {
- "name": "CoreLatency",
- "type": "string"
- },
- {
- "name": "RoutingLatency",
- "type": "string"
- },
- {
- "name": "HttpProxyOverhead",
- "type": "string"
- },
- {
- "name": "TotalRequestTime",
- "type": "string"
- },
- {
- "name": "RouteRefresherLatency",
- "type": "string"
- },
- {
- "name": "UrlQuery",
- "type": "string"
- },
- {
- "name": "BackEndGenericInfo",
- "type": "string"
- },
- {
- "name": "GenericInfo",
- "type": "string"
- },
- {
- "name": "GenericErrors",
- "type": "string"
- },
- {
- "name": "EdgeTraceId",
- "type": "string"
- },
- {
- "name": "DatabaseGuid",
- "type": "string"
- },
- {
- "name": "UserADObjectGuid",
- "type": "string"
- },
- {
- "name": "PartitionEndpointLookupLatency",
+ "name": "RawData",
"type": "string"
},
{
- "name": "RoutingStatus",
+ "name": "FilePath",
"type": "string"
}
]
@@ -716,7 +430,7 @@
"destinations": [
"la-data-destination"
],
- "transformKql": "source\n| extend TimeGenerated = todatetime(DateTime)\n| project-away DateTime\n\n",
+ "transformKql": "source | extend d = split(RawData,',') | extend DateTime=todatetime(d[0]),RequestId=tostring(d[1]) ,MajorVersion=tostring(d[2]) ,MinorVersion=tostring(d[3]) ,BuildVersion=tostring(d[4]) ,RevisionVersion=tostring(d[5]) ,ClientRequestId=tostring(d[6]) ,Protocol=tostring(d[7]) ,UrlHost=tostring(d[8]) ,UrlStem=tostring(d[9]) ,ProtocolAction=tostring(d[10]) ,AuthenticationType=tostring(d[11]) ,IsAuthenticated=tostring(d[12]) ,AuthenticatedUser=tostring(d[13]) ,Organization=tostring(d[14]) ,AnchorMailbox=tostring(d[15]) ,UserAgent=tostring(d[16]) ,ClientIpAddress=tostring(d[17]) ,ServerHostName=tostring(d[18]) ,HttpStatus=tostring(d[19]) ,BackEndStatus=tostring(d[20]) ,ErrorCode=tostring(d[21]) ,Method=tostring(d[22]) ,ProxyAction=tostring(d[23]) ,TargetServer=tostring(d[24]) ,TargetServerVersion=tostring(d[25]) ,RoutingType=tostring(d[26]) ,RoutingHint=tostring(d[27]) ,BackEndCookie=tostring(d[28]) ,ServerLocatorHost=tostring(d[29]) ,ServerLocatorLatency=tostring(d[30]) ,RequestBytes=tostring(d[31]) ,ResponseBytes=tostring(d[32]) ,TargetOutstandingRequests=tostring(d[33]) ,AuthModulePerfContext=tostring(d[34]) ,HttpPipelineLatency=tostring(d[35]) ,CalculateTargetBackEndLatency=tostring(d[36]) ,GlsLatencyBreakup=tostring(d[37]) ,TotalGlsLatency=tostring(d[38]) ,AccountForestLatencyBreakup=tostring(d[39]) ,TotalAccountForestLatency=tostring(d[40]) ,ResourceForestLatencyBreakup=tostring(d[41]) ,TotalResourceForestLatency=tostring(d[42]) ,ADLatency=tostring(d[43]) ,SharedCacheLatencyBreakup=tostring(d[44]) ,TotalSharedCacheLatency=tostring(d[45]) ,ActivityContextLifeTime=tostring(d[46]) ,ModuleToHandlerSwitchingLatency=tostring(d[47]) ,ClientReqStreamLatency=tostring(d[48]) ,BackendReqInitLatency=tostring(d[49]) ,BackendReqStreamLatency=tostring(d[50]) ,BackendProcessingLatency=tostring(d[51]) ,BackendRespInitLatency=tostring(d[52]) ,BackendRespStreamLatency=tostring(d[53]) ,ClientRespStreamLatency=tostring(d[54]) ,KerberosAuthHeaderLatency=tostring(d[55]) ,HandlerCompletionLatency=tostring(d[56]) ,RequestHandlerLatency=tostring(d[57]) ,HandlerToModuleSwitchingLatency=tostring(d[58]) ,ProxyTime=tostring(d[59]) ,CoreLatency=tostring(d[60]) ,RoutingLatency=tostring(d[61]) ,HttpProxyOverhead=tostring(d[62]) ,TotalRequestTime=tostring(d[63]) ,RouteRefresherLatency=tostring(d[64]) ,UrlQuery=tostring(d[65]) ,BackEndGenericInfo=tostring(d[66]) ,GenericInfo=tostring(d[67]) ,GenericErrors=tostring(d[68]) ,EdgeTraceId=tostring(d[69]) ,DatabaseGuid=tostring(d[70]) ,UserADObjectGuid=tostring(d[71]) ,PartitionEndpointLookupLatency=tostring(d[72]) ,RoutingStatus=tostring(d[73]) | extend TimeGenerated = DateTime | project-away d,RawData,DateTime | project-away d,RawData,DateTime",
"outputStream": "Custom-ExchangeHttpProxy_CL"
}
]
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data/Solution_MicrosoftExchangeSecurity.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data/Solution_MicrosoftExchangeSecurity.json
index 00c0c0a44c9..c7462b84ea1 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data/Solution_MicrosoftExchangeSecurity.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data/Solution_MicrosoftExchangeSecurity.json
@@ -5,13 +5,20 @@
"Description": "The Exchange Security Audit and Configuration Insight solution analyze Exchange On-Premises configuration and logs from a security lens to provide insights and alerts.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Windows Event logs collection, including MS Exchange Management Event logs](https://learn.microsoft.com/azure/azure-monitor/agents/data-sources-windows-events)\n\nb. [Custom logs ingestion via Data Collector REST API](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=powershell)",
"Data Connectors": [
"Data Connectors/ESI-ExchangeAdminAuditLogEvents.json",
- "Data Connectors/ESI-ExchangeOnPremisesCollector.json"
+ "Data Connectors/ESI-ExchangeOnPremisesCollector.json",
+ "Data Connectors/ESI-Opt1ExchangeAdminAuditLogsByEventLogs.json",
+ "Data Connectors/ESI-Opt2ExchangeServersEventLogs.json",
+ "Data Connectors/ESI-Opt34DomainControllersSecurityEventLogs.json",
+ "Data Connectors/ESI-Opt5ExchangeIISLogs.json",
+ "Data Connectors/ESI-Opt6ExchangeMessageTrackingLogs.json",
+ "Data Connectors/ESI-Opt7ExchangeHTTPProxyLogs.json"
],
"Parsers": [
"Parsers/ExchangeAdminAuditLogs.yaml",
"Parsers/ExchangeConfiguration.yaml",
"Parsers/ExchangeEnvironmentList.yaml",
- "Parsers/MESCheckVIP.yaml"
+ "Parsers/MESCheckVIP.yaml",
+ "Parsers/MESCompareDataOnPMRA.yaml"
],
"Workbooks": [
"Workbooks/Microsoft Exchange Least Privilege with RBAC.json",
@@ -28,7 +35,7 @@
"Watchlists/ExchangeVIP.json"
],
"BasePath": "C:\\Git Repositories\\Azure-Sentinel\\Solutions\\Microsoft Exchange Security - Exchange On-Premises\\",
- "Version": "3.1.5",
+ "Version": "3.3.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.3.0.zip b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.3.0.zip
new file mode 100644
index 00000000000..2d56ee0620f
Binary files /dev/null and b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.3.0.zip differ
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json
index 354722fba77..20ce28013be 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/createUiDefinition.json
@@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
- "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange On-Premises configuration and logs from a security lens to provide insights and alerts.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Windows Event logs collection, including MS Exchange Management Event logs](https://learn.microsoft.com/azure/azure-monitor/agents/data-sources-windows-events)\n\nb. [Custom logs ingestion via Data Collector REST API](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=powershell)\n\n**Data Connectors:** 2, **Parsers:** 4, **Workbooks:** 4, **Analytic Rules:** 2, **Watchlists:** 2\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange On-Premises configuration and logs from a security lens to provide insights and alerts.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Windows Event logs collection, including MS Exchange Management Event logs](https://learn.microsoft.com/azure/azure-monitor/agents/data-sources-windows-events)\n\nb. [Custom logs ingestion via Data Collector REST API](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=powershell)\n\n**Data Connectors:** 8, **Parsers:** 5, **Workbooks:** 4, **Analytic Rules:** 2, **Watchlists:** 2\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@@ -60,57 +60,64 @@
"name": "dataconnectors1-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "This solution installs two (2) data connectors for ingesting Microsoft Exchange on-premises events to provide security insights. Each of these data connectors help ingest a different set of logs/events."
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
}
},
{
"name": "dataconnectors2-text",
- "type": "Microsoft.Common.Section",
- "label": "1. Exchange Security Insights On-Premises Collector",
- "elements": [
- {
- "name": "dataconnectors3-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "This data connector collects security configuration, RBAC information and audit information from your on-premises Exchange environment(s). It uses a scheduled script that needs to be manually deployed in your environment. This connects directly (via proxy if needed) to Log Analytics/Microsoft Sentinel to ingest data."
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
+ {
+ "name": "dataconnectors3-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
}
- }
- ]
},
{
"name": "dataconnectors4-text",
- "type": "Microsoft.Common.Section",
- "label": "2. Exchange Audit Event logs via Legacy Agent",
- "elements": [
- {
- "name": "dataconnectors5-text",
- "type": "Microsoft.Common.TextBlock",
- "options": {
- "text": "This data connector uses Log Analytics Agent or Azure Monitor Agent to collect MSExchange Management Eventlogs, Exchange Security logs, Domain Controllers Security logs, IIS Logs, Exchange logs. Not all logs are required but it depends on your needs and on what you want to collect and secure for hunting in case of compromise. The first important logs consumed by this solution are “MSExchange Management” Event logs."
- }
- }
- ]
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
+ {
+ "name": "dataconnectors5-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
},
{
"name": "dataconnectors6-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "After installing the solution, configure and enable the data connector that’s most relevant to your Exchange environment by following guidance in Manage solution view."
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
+ {
+ "name": "dataconnectors7-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
}
},
{
- "name": "dataconnectors-parser",
- "type": "Microsoft.Common.Section",
- "label": "Parsers",
- "elements": [
+ "name": "dataconnectors8-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This Solution installs the data connector for Microsoft Exchange Security - Exchange On-Premises. You can get Microsoft Exchange Security - Exchange On-Premises custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view."
+ }
+ },
{
"name": "dataconnectors-parser-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "The solution installs four (4) parsers that transform ingested data. The transformed logs can be accessed using the ExchangeConfiguration, ExchangeAdminAuditLogs, MESCheckVIP and ExchangeEnvironmentList Kusto Function aliases."
+ "text": "The Solution installs a parser that transforms the ingested data into Microsoft Sentinel normalized format. The normalized format enables better correlation of different types of data from different data sources to drive end-to-end outcomes seamlessly in security monitoring, hunting, incident investigation and response scenarios in Microsoft Sentinel."
}
- }
- ]
},
{
"name": "dataconnectors-link2",
@@ -321,4 +328,4 @@
"workspace": "[basics('workspace')]"
}
}
-}
\ No newline at end of file
+}
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json
index b2e9d5ed6cd..8161f1dc1f8 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json
@@ -81,7 +81,7 @@
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Microsoft Exchange Security - Exchange On-Premises",
- "_solutionVersion": "3.1.5",
+ "_solutionVersion": "3.3.0",
"solutionId": "microsoftsentinelcommunity.azure-sentinel-solution-exchangesecurityinsights",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "ESI-ExchangeAdminAuditLogEvents",
@@ -91,7 +91,7 @@
"dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]",
"_dataConnectorId1": "[variables('dataConnectorId1')]",
"dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]",
- "dataConnectorVersion1": "2.2.1",
+ "dataConnectorVersion1": "2.2.2",
"_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
"uiConfigId2": "ESI-ExchangeOnPremisesCollector",
"_uiConfigId2": "[variables('uiConfigId2')]",
@@ -100,8 +100,62 @@
"dataConnectorId2": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId2'))]",
"_dataConnectorId2": "[variables('dataConnectorId2')]",
"dataConnectorTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId2'))))]",
- "dataConnectorVersion2": "1.2.1",
+ "dataConnectorVersion2": "1.2.2",
"_dataConnectorcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId2'),'-', variables('dataConnectorVersion2'))))]",
+ "uiConfigId3": "ESI-Opt1ExchangeAdminAuditLogsByEventLogs",
+ "_uiConfigId3": "[variables('uiConfigId3')]",
+ "dataConnectorContentId3": "ESI-Opt1ExchangeAdminAuditLogsByEventLogs",
+ "_dataConnectorContentId3": "[variables('dataConnectorContentId3')]",
+ "dataConnectorId3": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId3'))]",
+ "_dataConnectorId3": "[variables('dataConnectorId3')]",
+ "dataConnectorTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId3'))))]",
+ "dataConnectorVersion3": "1.0.0",
+ "_dataConnectorcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId3'),'-', variables('dataConnectorVersion3'))))]",
+ "uiConfigId4": "ESI-Opt2ExchangeServersEventLogs",
+ "_uiConfigId4": "[variables('uiConfigId4')]",
+ "dataConnectorContentId4": "ESI-Opt2ExchangeServersEventLogs",
+ "_dataConnectorContentId4": "[variables('dataConnectorContentId4')]",
+ "dataConnectorId4": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "_dataConnectorId4": "[variables('dataConnectorId4')]",
+ "dataConnectorTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId4'))))]",
+ "dataConnectorVersion4": "1.0.0",
+ "_dataConnectorcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId4'),'-', variables('dataConnectorVersion4'))))]",
+ "uiConfigId5": "ESI-Opt34DomainControllersSecurityEventLogs",
+ "_uiConfigId5": "[variables('uiConfigId5')]",
+ "dataConnectorContentId5": "ESI-Opt34DomainControllersSecurityEventLogs",
+ "_dataConnectorContentId5": "[variables('dataConnectorContentId5')]",
+ "dataConnectorId5": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "_dataConnectorId5": "[variables('dataConnectorId5')]",
+ "dataConnectorTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId5'))))]",
+ "dataConnectorVersion5": "1.0.0",
+ "_dataConnectorcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId5'),'-', variables('dataConnectorVersion5'))))]",
+ "uiConfigId6": "ESI-Opt5ExchangeIISLogs",
+ "_uiConfigId6": "[variables('uiConfigId6')]",
+ "dataConnectorContentId6": "ESI-Opt5ExchangeIISLogs",
+ "_dataConnectorContentId6": "[variables('dataConnectorContentId6')]",
+ "dataConnectorId6": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "_dataConnectorId6": "[variables('dataConnectorId6')]",
+ "dataConnectorTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId6'))))]",
+ "dataConnectorVersion6": "1.0.0",
+ "_dataConnectorcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId6'),'-', variables('dataConnectorVersion6'))))]",
+ "uiConfigId7": "ESI-Opt6ExchangeMessageTrackingLogs",
+ "_uiConfigId7": "[variables('uiConfigId7')]",
+ "dataConnectorContentId7": "ESI-Opt6ExchangeMessageTrackingLogs",
+ "_dataConnectorContentId7": "[variables('dataConnectorContentId7')]",
+ "dataConnectorId7": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "_dataConnectorId7": "[variables('dataConnectorId7')]",
+ "dataConnectorTemplateSpecName7": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId7'))))]",
+ "dataConnectorVersion7": "1.0.0",
+ "_dataConnectorcontentProductId7": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId7'),'-', variables('dataConnectorVersion7'))))]",
+ "uiConfigId8": "ESI-Opt7ExchangeHTTPProxyLogs",
+ "_uiConfigId8": "[variables('uiConfigId8')]",
+ "dataConnectorContentId8": "ESI-Opt7ExchangeHTTPProxyLogs",
+ "_dataConnectorContentId8": "[variables('dataConnectorContentId8')]",
+ "dataConnectorId8": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "_dataConnectorId8": "[variables('dataConnectorId8')]",
+ "dataConnectorTemplateSpecName8": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId8'))))]",
+ "dataConnectorVersion8": "1.0.0",
+ "_dataConnectorcontentProductId8": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId8'),'-', variables('dataConnectorVersion8'))))]",
"parserObject1": {
"_parserName1": "[concat(parameters('workspace'),'/','ExchangeAdminAuditLogs Data Parser')]",
"_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ExchangeAdminAuditLogs Data Parser')]",
@@ -130,6 +184,13 @@
"parserVersion4": "1.0.0",
"parserContentId4": "MESCheckVIP-Parser"
},
+ "parserObject5": {
+ "_parserName5": "[concat(parameters('workspace'),'/','MESCompareDataOnPMRA')]",
+ "_parserId5": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'MESCompareDataOnPMRA')]",
+ "parserTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('MESCompareDataOnPMRA-Parser')))]",
+ "parserVersion5": "1.0.0",
+ "parserContentId5": "MESCompareDataOnPMRA-Parser"
+ },
"workbookVersion1": "1.0.1",
"workbookContentId1": "MicrosoftExchangeLeastPrivilegewithRBAC",
"workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
@@ -149,7 +210,7 @@
"workbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId3'))))]",
"_workbookContentId3": "[variables('workbookContentId3')]",
"_workbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId3'),'-', variables('workbookVersion3'))))]",
- "workbookVersion4": "1.0.1",
+ "workbookVersion4": "2.0.0",
"workbookContentId4": "MicrosoftExchangeSecurityReview",
"workbookId4": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId4'))]",
"workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
@@ -185,7 +246,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.1.5",
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -201,9 +262,9 @@
"properties": {
"connectorUiConfig": {
"id": "[variables('_uiConfigId1')]",
- "title": "Microsoft Exchange Logs and Events",
+ "title": "[Deprecated] Microsoft Exchange Logs and Events",
"publisher": "Microsoft",
- "descriptionMarkdown": "You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "descriptionMarkdown": "Deprecated, use the 'ESI-Opt' dataconnectors. You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
"graphQueries": [
{
"metricName": "Total data received",
@@ -301,35 +362,14 @@
"customs": [
{
"description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
}
]
},
"instructionSteps": [
- {
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)",
- "instructionSteps": [
- {
- "title": "1. Download the Parser file",
- "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
- "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- },
{
"description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)"
},
@@ -409,7 +449,7 @@
"instructionSteps": [
{
"title": "A. Create DCR, Type Event log",
- "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MS Exchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
}
]
},
@@ -429,7 +469,7 @@
},
{
"title": "Data Collection Rules - When the legacy Azure Log Analytics Agent is used",
- "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
+ "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MSExchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -890,15 +930,52 @@
}
],
"title": "2. Deploy log injestion following choosed options"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"metadata": {
"id": "5738bef7-b6c0-4fec-ba0b-ac728bef83a9",
- "version": "2.2.1",
+ "version": "2.2.2",
"kind": "dataConnector",
"source": {
"kind": "solution",
- "name": "ESI - Exchange Security Configuration Analyzer"
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
},
"support": {
"name": "Community",
@@ -946,7 +1023,7 @@
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_dataConnectorContentId1')]",
"contentKind": "DataConnector",
- "displayName": "Microsoft Exchange Logs and Events",
+ "displayName": "[Deprecated] Microsoft Exchange Logs and Events",
"contentProductId": "[variables('_dataConnectorcontentProductId1')]",
"id": "[variables('_dataConnectorcontentProductId1')]",
"version": "[variables('dataConnectorVersion1')]"
@@ -989,9 +1066,9 @@
"kind": "GenericUI",
"properties": {
"connectorUiConfig": {
- "title": "Microsoft Exchange Logs and Events",
+ "title": "[Deprecated] Microsoft Exchange Logs and Events",
"publisher": "Microsoft",
- "descriptionMarkdown": "You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "descriptionMarkdown": "Deprecated, use the 'ESI-Opt' dataconnectors. You can stream all Exchange Audit events, IIS Logs, HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
"graphQueries": [
{
"metricName": "Total data received",
@@ -1089,35 +1166,14 @@
"customs": [
{
"description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
}
]
},
"instructionSteps": [
- {
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)",
- "instructionSteps": [
- {
- "title": "1. Download the Parser file",
- "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
- "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ]
- },
{
"description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)"
},
@@ -1197,7 +1253,7 @@
"instructionSteps": [
{
"title": "A. Create DCR, Type Event log",
- "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MS Exchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
}
]
},
@@ -1217,7 +1273,7 @@
},
{
"title": "Data Collection Rules - When the legacy Azure Log Analytics Agent is used",
- "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
+ "description": "**Configure the logs to be collected**\n\nConfigure the Events you want to collect and their severities.\n\n1. Under workspace **Legacy agents management**, select **Windows Event logs**.\n2. Click **Add Windows event log** and enter **MSExchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -1678,6 +1734,43 @@
}
],
"title": "2. Deploy log injestion following choosed options"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"id": "[variables('_uiConfigId1')]"
@@ -1693,7 +1786,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.1.5",
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -1709,7 +1802,7 @@
"properties": {
"connectorUiConfig": {
"id": "[variables('_uiConfigId2')]",
- "title": "Exchange Security Insights On-Premise Collector",
+ "title": "Exchange Security Insights On-Premises Collector",
"publisher": "Microsoft",
"descriptionMarkdown": "Connector used to push Exchange On-Premises Security configuration for Microsoft Sentinel Analysis",
"graphQueries": [
@@ -1728,7 +1821,7 @@
"dataTypes": [
{
"name": "ESIExchangeConfig_CL",
- "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time)"
+ "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time) |summarize Time = max(Time) | project Time"
}
],
"connectivityCriterias": [
@@ -1770,40 +1863,14 @@
{
"name": "Service Account with Organization Management role",
"description": "The service Account that launch the script as scheduled task needs to be Organization Management to be able to retrieve all the needed security Information."
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
}
]
},
"instructionSteps": [
- {
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps for each Parser to create the Kusto Functions alias : [**ExchangeConfiguration**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parsers deployment",
- "instructionSteps": [
- {
- "title": "1. Download the Parser files",
- "description": "The latest version of the 2 files [**ExchangeConfiguration.yaml**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList.yaml**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeConfiguration** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeConfiguration** function",
- "description": "Click on save button.\n Define the parameters as asked on the header of the parser file.\nClick save again."
- },
- {
- "title": "4. Reproduce the same steps for Parser **ExchangeEnvironmentList**",
- "description": "Reproduce the step 2 and 3 with the content of 'ExchangeEnvironmentList.yaml' file"
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ],
- "title": "Parser deployment **(When using Microsoft Exchange Security Solution, Parsers are automatically deployed)**"
- },
{
"description": "This is the script that will collect Exchange Information to push content in Microsoft Sentinel.\n ",
"instructions": [
@@ -1861,11 +1928,48 @@
{
"description": "The script needs to be scheduled to send Exchange configuration to Microsoft Sentinel.\n We recommend to schedule the script once a day.\n The account used to launch the Script needs to be member of the group Organization Management",
"title": "3. Schedule the ESI Collector Script (If not done by the Install Script due to lack of permission or ignored during installation)"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"metadata": {
"id": "ed950fd7-e457-4a59-88f0-b9c949aa280d",
- "version": "1.2.1",
+ "version": "1.2.2",
"kind": "dataConnector",
"source": {
"kind": "solution",
@@ -1917,7 +2021,7 @@
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_dataConnectorContentId2')]",
"contentKind": "DataConnector",
- "displayName": "Exchange Security Insights On-Premise Collector",
+ "displayName": "Exchange Security Insights On-Premises Collector",
"contentProductId": "[variables('_dataConnectorcontentProductId2')]",
"id": "[variables('_dataConnectorcontentProductId2')]",
"version": "[variables('dataConnectorVersion2')]"
@@ -1960,7 +2064,7 @@
"kind": "GenericUI",
"properties": {
"connectorUiConfig": {
- "title": "Exchange Security Insights On-Premise Collector",
+ "title": "Exchange Security Insights On-Premises Collector",
"publisher": "Microsoft",
"descriptionMarkdown": "Connector used to push Exchange On-Premises Security configuration for Microsoft Sentinel Analysis",
"graphQueries": [
@@ -1973,7 +2077,7 @@
"dataTypes": [
{
"name": "ESIExchangeConfig_CL",
- "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time)"
+ "lastDataReceivedQuery": "ESIExchangeConfig_CL | summarize Time = max(todatetime(EntryDate_s)) by GenerationInstanceID_g, ESIEnvironment_s | where isnotempty(Time) |summarize Time = max(Time) | project Time"
}
],
"connectivityCriterias": [
@@ -2021,40 +2125,14 @@
{
"name": "Service Account with Organization Management role",
"description": "The service Account that launch the script as scheduled task needs to be Organization Management to be able to retrieve all the needed security Information."
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
}
]
},
"instructionSteps": [
- {
- "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Follow the steps for each Parser to create the Kusto Functions alias : [**ExchangeConfiguration**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)",
- "instructions": [
- {
- "parameters": {
- "title": "Parsers deployment",
- "instructionSteps": [
- {
- "title": "1. Download the Parser files",
- "description": "The latest version of the 2 files [**ExchangeConfiguration.yaml**](https://aka.ms/sentinel-ESI-ExchangeConfiguration-OnPrem-parser) and [**ExchangeEnvironmentList.yaml**](https://aka.ms/sentinel-ESI-ExchangeEnvironmentList-OnPrem-parser)"
- },
- {
- "title": "2. Create Parser **ExchangeConfiguration** function",
- "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
- },
- {
- "title": "3. Save Parser **ExchangeConfiguration** function",
- "description": "Click on save button.\n Define the parameters as asked on the header of the parser file.\nClick save again."
- },
- {
- "title": "4. Reproduce the same steps for Parser **ExchangeEnvironmentList**",
- "description": "Reproduce the step 2 and 3 with the content of 'ExchangeEnvironmentList.yaml' file"
- }
- ]
- },
- "type": "InstructionStepsGroup"
- }
- ],
- "title": "Parser deployment **(When using Microsoft Exchange Security Solution, Parsers are automatically deployed)**"
- },
{
"description": "This is the script that will collect Exchange Information to push content in Microsoft Sentinel.\n ",
"instructions": [
@@ -2112,6 +2190,43 @@
{
"description": "The script needs to be scheduled to send Exchange configuration to Microsoft Sentinel.\n We recommend to schedule the script once a day.\n The account used to launch the Script needs to be member of the group Organization Management",
"title": "3. Schedule the ESI Collector Script (If not done by the Install Script due to lack of permission or ignored during installation)"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
}
],
"id": "[variables('_uiConfigId2')]"
@@ -2121,76 +2236,2828 @@
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
- "name": "[variables('parserObject1').parserTemplateSpecName1]",
+ "name": "[variables('dataConnectorTemplateSpecName3')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeAdminAuditLogs Data Parser with template version 3.1.5",
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
- "contentVersion": "[variables('parserObject1').parserVersion1]",
+ "contentVersion": "[variables('dataConnectorVersion3')]",
"parameters": {},
"variables": {},
"resources": [
{
- "name": "[variables('parserObject1')._parserName1]",
- "apiVersion": "2022-10-01",
- "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId3'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
"location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
"properties": {
- "eTag": "*",
- "displayName": "Parser for ExchangeAdminAuditLogs",
- "category": "Microsoft Sentinel Parser",
- "functionAlias": "ExchangeAdminAuditLogs",
- "query": "let CmdletCheck = externaldata (Cmdlet:string, UserOriented:string, RestrictToParameter:string, Parameters:string)[h\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/CmdletWatchlist.csv\"]with(format=\"csv\",ignoreFirstRecord=true);\nlet SensitiveCmdlets = CmdletCheck | project tostring(Cmdlet) ;\nlet Check = (T:(*)) {\n let fuzzyWatchlist = datatable(displayName:string, userPrincipalName:string, sAMAccountName:string, objectSID:string, objectGUID:guid, canonicalName:string, comment:string) [\n \"NONE\",\"NONE\",\"NONE\",\"NONE\",\"00000001-0000-1000-0000-100000000000\",\"NONE\",\"NONE\"];\n let Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != \"00000001-0000-1000-0000-100000000000\" | project-away TableName;\n let SearchUserDisplayName = T | join Watchlist on $left.TargetObject == $right.displayName | project TargetObject,SearchKey;\n let SearchUserUPN = T | join Watchlist on $left.TargetObject == $right.userPrincipalName | project TargetObject,SearchKey;\n let SearchUserCanonicalName = T | join Watchlist on $left.TargetObject == $right.canonicalName | project TargetObject,SearchKey;\n let SearchUserSAMAccountName = T | join Watchlist on $left.TargetObject == $right.sAMAccountName | project TargetObject,SearchKey;\n let SearchUserObjectSID = T | join Watchlist on $left.TargetObject == $right.objectSID | project TargetObject,SearchKey;\n let SearchUserObjectGUID = T | join (Watchlist | extend objectGuidString = tostring(objectGUID)) on $left.TargetObject == $right.objectGuidString | project TargetObject,SearchKey;\n let SearchUserDistinguishedName = T | join Watchlist on $left.TargetObject == $right.distinguishedName | project TargetObject,SearchKey;\n union isfuzzy=true withsource=TableName \n SearchUserDisplayName, \n SearchUserUPN, \n SearchUserCanonicalName, \n SearchUserSAMAccountName,\n SearchUserObjectSID,\n SearchUserObjectGUID,\n SearchUserDistinguishedName\n };\nlet Env = ExchangeConfiguration(SpecificSectionList=\"ESIEnvironment\")\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\n| project DomainFQDN_, ESIEnvironment;\nlet EventList = Event\n | where EventLog == 'MSExchange Management'\n | where EventID in (1,6) // 1 = Success, 6 = Failure\n | parse ParameterXml with '' CmdletName '' CmdletParameters '' Caller '' *\n | extend TargetObject = iif( CmdletParameters has \"-Identity \", split(split(CmdletParameters,'-Identity ')[1],'\"')[1], iif( CmdletParameters has \"-Name \", split(split(CmdletParameters,'-Name ')[1],'\"')[1], \"\"));\nlet MSExchange_Management = (){\nEventList\n | extend Status = case( EventID == 1, 'Success', 'Failure')\n | join kind=leftouter (EventList | project TargetObject | invoke Check()) on TargetObject\n | extend IsVIP = iif(SearchKey == \"\", false, true)\n | join kind=leftouter ( \n MESCheckVIP() ) on SearchKey\n | extend CmdletNameJoin = tolower(CmdletName)\n | join kind=leftouter ( \n CmdletCheck\n | extend CmdletNameJoin = tolower(Cmdlet)\n ) on CmdletNameJoin\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\n | join kind=leftouter ( \n Env\n ) on $left.DomainEnv == $right.DomainFQDN_\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\"Unknown-\",DomainEnv))\n | extend IsSenstiveCmdlet = iif( isnotempty(CmdletNameJoin1) , true, false) \n | extend IsRestrictedCmdLet = iif(IsSenstiveCmdlet == true, iif( RestrictToParameter == \"Yes\", true, false), dynamic(null))\n | extend RestrictedParameters = iif(IsSenstiveCmdlet == true, split(tolower(Parameters),';'), dynamic(null))\n | extend ExtractedParameters = iif(IsSenstiveCmdlet == true,extract_all(@\"\\B(-\\w+)\", tolower(CmdletParameters)), dynamic(null))\n | extend IsSenstiveCmdletParameters = iif(IsSenstiveCmdlet == true,iif( array_length(set_difference(ExtractedParameters,RestrictedParameters)) == array_length(ExtractedParameters), false, true ) , false)\n | extend IsSensitive = iif( ( IsSenstiveCmdlet == true and IsRestrictedCmdLet == false ) or (IsSenstiveCmdlet == true and IsRestrictedCmdLet == true and IsSenstiveCmdletParameters == true ), true, false )\n | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,canonicalName,displayName,distinguishedName,objectGUID,objectSID,sAMAccountName,userPrincipalName,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment\n};\nMSExchange_Management\n",
- "functionParameters": "",
- "version": 2,
- "tags": [
- {
- "name": "description",
- "value": ""
- }
- ]
- }
- },
- {
- "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
- "apiVersion": "2022-01-01-preview",
- "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
- "dependsOn": [
- "[variables('parserObject1')._parserId1]"
- ],
- "properties": {
- "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ExchangeAdminAuditLogs Data Parser')]",
- "contentId": "[variables('parserObject1').parserContentId1]",
- "kind": "Parser",
- "version": "[variables('parserObject1').parserVersion1]",
- "source": {
- "name": "Microsoft Exchange Security - Exchange On-Premises",
- "kind": "Solution",
- "sourceId": "[variables('_solutionId')]"
- },
- "author": {
- "name": "Microsoft",
- "email": "[variables('_email')]"
- },
- "support": {
- "name": "Community",
- "tier": "Community",
- "link": "https://github.com/Azure/Azure-Sentinel/issues"
- }
- }
- }
- ]
- },
- "packageKind": "Solution",
- "packageVersion": "[variables('_solutionVersion')]",
- "packageName": "[variables('_solutionName')]",
- "packageId": "[variables('_solutionId')]",
- "contentSchemaVersion": "3.0.0",
- "contentId": "[variables('parserObject1').parserContentId1]",
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId3')]",
+ "title": "Microsoft Exchange Admin Audit Logs by Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 1] - Using Azure Monitor Agent - You can stream all Exchange Audit events from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "ExchangeAuditLogs",
+ "baseQuery": "Event | where EventLog == 'MSExchange Management'"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'MSExchange Management' | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'MSExchange Management' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'MSExchange Management' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 1** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "The MS Exchange Admin Audit event logs are collected using Data Collection Rules (DCR) and allow to store all Administrative Cmdlets executed in an Exchange environment.",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "DCR",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules Deployment",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption1-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 1] MS Exchange Management Log collection - MS Exchange Admin Audit event logs by Data Collection Rules"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "metadata": {
+ "id": "dfa2e270-b24f-4d76-b9a5-cd4a878596bf",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId3'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId3'))]",
+ "contentId": "[variables('_dataConnectorContentId3')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion3')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId3')]",
+ "contentKind": "DataConnector",
+ "displayName": "Microsoft Exchange Admin Audit Logs by Event Logs",
+ "contentProductId": "[variables('_dataConnectorcontentProductId3')]",
+ "id": "[variables('_dataConnectorcontentProductId3')]",
+ "version": "[variables('dataConnectorVersion3')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId3'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId3')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId3'))]",
+ "contentId": "[variables('_dataConnectorContentId3')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion3')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId3'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Microsoft Exchange Admin Audit Logs by Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 1] - Using Azure Monitor Agent - You can stream all Exchange Audit events from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to view dashboards, create custom alerts, and improve investigation. This is used by Microsoft Exchange Security Workbooks to provide security insights of your On-Premises Exchange environment",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "ExchangeAuditLogs",
+ "baseQuery": "Event | where EventLog == 'MSExchange Management'"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'MSExchange Management' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'MSExchange Management' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'MSExchange Management' | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 1** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "The MS Exchange Admin Audit event logs are collected using Data Collection Rules (DCR) and allow to store all Administrative Cmdlets executed in an Exchange environment.",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "DCR",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules Deployment",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption1-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Custom' option, enter 'MSExchange Management' as expression and Add it.\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 1] MS Exchange Management Log collection - MS Exchange Admin Audit event logs by Data Collection Rules"
+ },
+ {
+ "description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. Parsers are automatically deployed with the solution. Follow the steps to create the Kusto Functions alias : [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Parsers are automatically deployed during Solution deployment. If you want to deploy manually, follow the steps below",
+ "instructionSteps": [
+ {
+ "title": "Manual Parser Deployment",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "1. Download the Parser file",
+ "description": "The latest version of the file [**ExchangeAdminAuditLogs**](https://aka.ms/sentinel-ESI-ExchangeCollector-ExchangeAdminAuditLogs-parser)"
+ },
+ {
+ "title": "2. Create Parser **ExchangeAdminAuditLogs** function",
+ "description": "In 'Logs' explorer of your Microsoft Sentinel's log analytics, copy the content of the file to Log explorer"
+ },
+ {
+ "title": "3. Save Parser **ExchangeAdminAuditLogs** function",
+ "description": "Click on save button.\n No parameter is needed for this parser.\nClick save again."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ],
+ "id": "[variables('_uiConfigId3')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion4')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId4')]",
+ "title": "Microsoft Exchange Logs and Events",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 2] - Using Azure Monitor Agent - You can stream all Exchange Security & Application Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Eventlogs",
+ "baseQuery": "Event | where EventLog == 'Application'"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'Application' | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'Application' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'Application' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 2** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "The Security/Application/System logs of Exchange Servers are collected using Data Collection Rules (DCR).",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add Exchange Servers on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Application and System Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> Application and System Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered method)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption2-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Basic' option.\n6. For Application, select 'Critical', 'Error' and 'Warning'. For System, select Critical/Error/Warning/Information. \n7. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 2] Security/Application/System logs of Exchange Servers"
+ }
+ ],
+ "metadata": {
+ "id": "22e0234b-278d-40f4-8be8-c2968faeaf91",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion4')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "contentKind": "DataConnector",
+ "displayName": "Microsoft Exchange Logs and Events",
+ "contentProductId": "[variables('_dataConnectorcontentProductId4')]",
+ "id": "[variables('_dataConnectorcontentProductId4')]",
+ "version": "[variables('dataConnectorVersion4')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId4'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId4')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId4'))]",
+ "contentId": "[variables('_dataConnectorContentId4')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion4')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId4'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Microsoft Exchange Logs and Events",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 2] - Using Azure Monitor Agent - You can stream all Exchange Security & Application Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Eventlogs",
+ "baseQuery": "Event | where EventLog == 'Application'"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "Event",
+ "lastDataReceivedQuery": "Event | where EventLog == 'Application' | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "Event | where EventLog == 'Application' | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "Event | where EventLog == 'Application' | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 2** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "The Security/Application/System logs of Exchange Servers are collected using Data Collection Rules (DCR).",
+ "instructions": [
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add Exchange Servers on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Application and System Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> Application and System Events logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered method)",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption2-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace Name** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCR, Type Event log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'Windows Event logs' and select 'Basic' option.\n6. For Application, select 'Critical', 'Error' and 'Warning'. For System, select Critical/Error/Warning/Information. \n7. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 2] Security/Application/System logs of Exchange Servers"
+ }
+ ],
+ "id": "[variables('_uiConfigId4')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName5')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion5')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId5'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId5')]",
+ "title": " Microsoft Active-Directory Domain Controllers Security Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 3 & 4] - Using Azure Monitor Agent -You can stream a part or all Domain Controllers Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Domain Controllers Security Logs",
+ "baseQuery": "SecurityEvent"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "SecurityEvent | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "SecurityEvent",
+ "lastDataReceivedQuery": "SecurityEvent | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "SecurityEvent | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 3 and 4** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream Security logs of Domain Controllers. If you want to implement Option 3, you just need to select DC on same site as Exchange Servers. If you want to implement Option 4, you can select all DCs of your forest.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "[Option 3] List only Domain Controllers on the same site as Exchange Servers for next step",
+ "description": "**This limits the quantity of data injested but some incident can't be detected.**"
+ },
+ {
+ "title": "[Option 4] List all Domain Controllers of your Active-Directory Forest for next step",
+ "description": "**This allows collecting all security events**"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add chosen DCs on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "Security logs of Domain Controllers"
+ }
+ ],
+ "metadata": {
+ "id": "036e16af-5a27-465a-8662-b7ac385a8d45",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId5'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "contentKind": "DataConnector",
+ "displayName": " Microsoft Active-Directory Domain Controllers Security Event Logs",
+ "contentProductId": "[variables('_dataConnectorcontentProductId5')]",
+ "id": "[variables('_dataConnectorcontentProductId5')]",
+ "version": "[variables('dataConnectorVersion5')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId5'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId5')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId5'))]",
+ "contentId": "[variables('_dataConnectorContentId5')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId5'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": " Microsoft Active-Directory Domain Controllers Security Event Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 3 & 4] - Using Azure Monitor Agent -You can stream a part or all Domain Controllers Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Domain Controllers Security Logs",
+ "baseQuery": "SecurityEvent"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "SecurityEvent",
+ "lastDataReceivedQuery": "SecurityEvent | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "SecurityEvent | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "SecurityEvent | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 3 and 4** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream Security logs of Domain Controllers. If you want to implement Option 3, you just need to select DC on same site as Exchange Servers. If you want to implement Option 4, you can select all DCs of your forest.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "[Option 3] List only Domain Controllers on the same site as Exchange Servers for next step",
+ "description": "**This limits the quantity of data injested but some incident can't be detected.**"
+ },
+ {
+ "title": "[Option 4] List all Domain Controllers of your Active-Directory Forest for next step",
+ "description": "**This allows collecting all security events**"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "title": "Security Event log collection",
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - Security Event logs",
+ "description": "**Enable data collection rule for Security Logs**\nSecurity Events logs are collected only from **Windows** agents.\n1. Add chosen DCs on *Resources* tab.\n2. Select Security log level\n\n> **Common level** is the minimum required. Please select 'Common' or 'All Security Events' on DCR definition.",
+ "instructions": [
+ {
+ "parameters": {
+ "linkType": "OpenCreateDataCollectionRule",
+ "dataCollectionRuleType": 0
+ },
+ "type": "InstallAgent"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "Security logs of Domain Controllers"
+ }
+ ],
+ "id": "[variables('_uiConfigId5')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName6')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion6')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId6'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId6')]",
+ "title": "IIS Logs of Microsoft Exchange Servers",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 5] - Using Azure Monitor Agent - You can stream all IIS Logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange IIS logs",
+ "baseQuery": "W3CIISLog"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "W3CIISLog | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "W3CIISLog",
+ "lastDataReceivedQuery": "W3CIISLog | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "W3CIISLog | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 5** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream IIS logs of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> IIS logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "type": "AdminAuditEvents"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Preferred Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption5-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create DCR, Type IIS log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. Select the created DCE. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'IIS logs' (Do not enter a path if IIS Logs path is configured by default). Click on 'Add data source'\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "[Option 5] IIS logs of Exchange Servers"
+ }
+ ],
+ "metadata": {
+ "id": "4b1075ed-80f5-4930-bfe1-877e86b48dc1",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId6'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion6')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "contentKind": "DataConnector",
+ "displayName": "IIS Logs of Microsoft Exchange Servers",
+ "contentProductId": "[variables('_dataConnectorcontentProductId6')]",
+ "id": "[variables('_dataConnectorcontentProductId6')]",
+ "version": "[variables('dataConnectorVersion6')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId6'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId6')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId6'))]",
+ "contentId": "[variables('_dataConnectorContentId6')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion6')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId6'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "IIS Logs of Microsoft Exchange Servers",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 5] - Using Azure Monitor Agent - You can stream all IIS Logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you to create custom alerts, and improve investigation.",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange IIS logs",
+ "baseQuery": "W3CIISLog"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "W3CIISLog",
+ "lastDataReceivedQuery": "W3CIISLog | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "W3CIISLog | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "W3CIISLog | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 5** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream IIS logs of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Enable data collection rule",
+ "description": "> IIS logs are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "type": "AdminAuditEvents"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Preferred Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption5-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create DCR, Type IIS log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields, Select Windows as platform type and give a name to the DCR. Select the created DCE. \n4. In the **Resources** tab, enter you Exchange Servers.\n5. In 'Collect and deliver', add a Data Source type 'IIS logs' (Do not enter a path if IIS Logs path is configured by default). Click on 'Add data source'\n6. 'Make other preferable configuration changes', if needed, then click **Create**."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "[Option 5] IIS logs of Exchange Servers"
+ }
+ ],
+ "id": "[variables('_uiConfigId6')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName7')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion7')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId7'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId7')]",
+ "title": "Microsoft Exchange Message Tracking Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 6] - Using Azure Monitor Agent - You can stream all Exchange Message Tracking from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. Those logs can be used to track the flow of messages in your Exchange environment. This data connector is based on the option 6 of the [Microsoft Exchange Security wiki](https://aka.ms/ESI_DataConnectorOptions).",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Message Tracking logs",
+ "baseQuery": "MessageTrackingLog_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Exchange Message Tracking logs",
+ "query": "MessageTrackingLog_CL | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "MessageTrackingLog_CL",
+ "lastDataReceivedQuery": "MessageTrackingLog_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "MessageTrackingLog_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 6** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream Message Tracking of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule and Custom Table",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption6-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-MessageTrackingCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t\"schema\": {\n\t\t\t\t\t \"name\": \"MessageTrackingLog_CL\",\n\t\t\t\t\t \"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"directionality\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"reference\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"source\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientIP\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"connectorId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"customData\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"eventId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"internalMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"logId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageSubject\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"networkMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalClientIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalServerIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientCount\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"relatedRecipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"returnPath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"serverIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"sourceContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"schemaVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageTrackingTenantId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"totalBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"transportTrafficType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t'@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/MessageTrackingLog_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE, like ESI-ExchangeServers. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option6-MessageTrackingLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter 'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\TransportRoles\\Logs\\MessageTracking\\*.log' in file pattern, 'MessageTrackingLog_CL' in Table Name.\n6.in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend TimeGenerated =todatetime(d[0]) ,clientIP =tostring(d[1]) ,clientHostname =tostring(d[2]) ,serverIp=tostring(d[3]) ,senderHostname=tostring(d[4]) ,sourceContext=tostring(d[5]) ,connectorId =tostring(d[6]) ,source=tostring(d[7]) ,eventId =tostring(d[8]) ,internalMessageId =tostring(d[9]) ,messageId =tostring(d[10]) ,networkMessageId =tostring(d[11]) ,recipientAddress=tostring(d[12]) ,recipientStatus=tostring(d[13]) ,totalBytes=tostring(d[14]) ,recipientCount=tostring(d[15]) ,relatedRecipientAddress=tostring(d[16]) ,reference=tostring(d[17]) ,messageSubject =tostring(d[18]) ,senderAddress=tostring(d[19]) ,returnPath=tostring(d[20]) ,messageInfo =tostring(d[21]) ,directionality=tostring(d[22]) ,messageTrackingTenantId =tostring(d[23]) ,originalClientIp =tostring(d[24]) ,originalServerIp =tostring(d[25]) ,customData=tostring(d[26]) ,transportTrafficType =tostring(d[27]) ,logId =tostring(d[28]) ,schemaVersion=tostring(d[29]) | project-away d,RawData\n and click on 'Destination'.\n6. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n7. Click on 'Add data source'.\n8. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. Message Tracking of Exchange Servers"
+ }
+ ],
+ "metadata": {
+ "id": "ababbb06-b977-4259-ab76-87874d353039",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId7'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion7')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "contentKind": "DataConnector",
+ "displayName": "Microsoft Exchange Message Tracking Logs",
+ "contentProductId": "[variables('_dataConnectorcontentProductId7')]",
+ "id": "[variables('_dataConnectorcontentProductId7')]",
+ "version": "[variables('dataConnectorVersion7')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId7'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId7')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId7'))]",
+ "contentId": "[variables('_dataConnectorContentId7')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion7')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId7'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Microsoft Exchange Message Tracking Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 6] - Using Azure Monitor Agent - You can stream all Exchange Message Tracking from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. Those logs can be used to track the flow of messages in your Exchange environment. This data connector is based on the option 6 of the [Microsoft Exchange Security wiki](https://aka.ms/ESI_DataConnectorOptions).",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange Message Tracking logs",
+ "baseQuery": "MessageTrackingLog_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "MessageTrackingLog_CL",
+ "lastDataReceivedQuery": "MessageTrackingLog_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "MessageTrackingLog_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "Exchange Message Tracking logs",
+ "query": "MessageTrackingLog_CL | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 6** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream Message Tracking of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule and Custom Table",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption6-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-MessageTrackingCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t\"schema\": {\n\t\t\t\t\t \"name\": \"MessageTrackingLog_CL\",\n\t\t\t\t\t \"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"directionality\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"reference\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"source\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"clientIP\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"connectorId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"customData\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"eventId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"internalMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"logId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageSubject\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"networkMessageId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalClientIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"originalServerIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientCount\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"recipientStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"relatedRecipientAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"returnPath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"senderHostname\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"serverIp\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"sourceContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"schemaVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"messageTrackingTenantId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"totalBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"transportTrafficType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t'@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/MessageTrackingLog_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE, like ESI-ExchangeServers. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option6-MessageTrackingLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter 'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\TransportRoles\\Logs\\MessageTracking\\*.log' in file pattern, 'MessageTrackingLog_CL' in Table Name.\n6.in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend TimeGenerated =todatetime(d[0]) ,clientIP =tostring(d[1]) ,clientHostname =tostring(d[2]) ,serverIp=tostring(d[3]) ,senderHostname=tostring(d[4]) ,sourceContext=tostring(d[5]) ,connectorId =tostring(d[6]) ,source=tostring(d[7]) ,eventId =tostring(d[8]) ,internalMessageId =tostring(d[9]) ,messageId =tostring(d[10]) ,networkMessageId =tostring(d[11]) ,recipientAddress=tostring(d[12]) ,recipientStatus=tostring(d[13]) ,totalBytes=tostring(d[14]) ,recipientCount=tostring(d[15]) ,relatedRecipientAddress=tostring(d[16]) ,reference=tostring(d[17]) ,messageSubject =tostring(d[18]) ,senderAddress=tostring(d[19]) ,returnPath=tostring(d[20]) ,messageInfo =tostring(d[21]) ,directionality=tostring(d[22]) ,messageTrackingTenantId =tostring(d[23]) ,originalClientIp =tostring(d[24]) ,originalServerIp =tostring(d[25]) ,customData=tostring(d[26]) ,transportTrafficType =tostring(d[27]) ,logId =tostring(d[28]) ,schemaVersion=tostring(d[29]) | project-away d,RawData\n and click on 'Destination'.\n6. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n7. Click on 'Add data source'.\n8. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. Message Tracking of Exchange Servers"
+ }
+ ],
+ "id": "[variables('_uiConfigId7')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('dataConnectorTemplateSpecName8')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('dataConnectorVersion8')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId8'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "id": "[variables('_uiConfigId8')]",
+ "title": "Microsoft Exchange HTTP Proxy Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 7] - Using Azure Monitor Agent - You can stream HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you create custom alerts, and improve investigation. [Learn more](https://aka.ms/ESI_DataConnectorOptions)",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange HTTPProxy logs",
+ "baseQuery": "ExchangeHttpProxy_CL"
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "ExchangeHttpProxy_CL | sort by TimeGenerated"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "ExchangeHttpProxy_CL",
+ "lastDataReceivedQuery": "ExchangeHttpProxy_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "ExchangeHttpProxy_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 7** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream HTTP Proxy of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption7-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-HTTPProxyCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t \"schema\": {\n\t\t\t\t\t\t\"name\": \"ExchangeHttpProxy_CL\",\n\t\t\t\t\t\t\"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AccountForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ActivityContextLifeTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ADLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AnchorMailbox\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticatedUser\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticationType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthModulePerfContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndCookie\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndGenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendProcessingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BuildVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CalculateTargetBackEndLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientIpAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CoreLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"DatabaseGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"EdgeTraceId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ErrorCode\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericErrors\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GlsLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerCompletionLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerToModuleSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpPipelineLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpProxyOverhead\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"IsAuthenticated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"KerberosAuthHeaderLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MajorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Method\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MinorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ModuleToHandlerSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Organization\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"PartitionEndpointLookupLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Protocol\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProtocolAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestHandlerLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResourceForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResponseBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RevisionVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RouteRefresherLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingHint\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerHostName\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"SharedCacheLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetOutstandingRequests\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServer\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServerVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalAccountForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalGlsLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalRequestTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalResourceForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalSharedCacheLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlQuery\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlStem\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserADObjectGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserAgent\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t }\n\t\t\t }\n\t\t }\n\t\t '@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/ExchangeHttpProxy_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option7-HTTPProxyLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter the following file pattern : \n\t\t'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Autodiscover\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Eas\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ecp\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ews\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Mapi\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Oab\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Owa\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\OwaCalendar\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\PowerShell\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\RpcHttp\\*.log'\n6. Put 'ExchangeHttpProxy_CL' in Table Name.\n7. in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend DateTime=todatetime(d[0]),RequestId=tostring(d[1]) ,MajorVersion=tostring(d[2]) ,MinorVersion=tostring(d[3]) ,BuildVersion=tostring(d[4]) ,RevisionVersion=tostring(d[5]) ,ClientRequestId=tostring(d[6]) ,Protocol=tostring(d[7]) ,UrlHost=tostring(d[8]) ,UrlStem=tostring(d[9]) ,ProtocolAction=tostring(d[10]) ,AuthenticationType=tostring(d[11]) ,IsAuthenticated=tostring(d[12]) ,AuthenticatedUser=tostring(d[13]) ,Organization=tostring(d[14]) ,AnchorMailbox=tostring(d[15]) ,UserAgent=tostring(d[16]) ,ClientIpAddress=tostring(d[17]) ,ServerHostName=tostring(d[18]) ,HttpStatus=tostring(d[19]) ,BackEndStatus=tostring(d[20]) ,ErrorCode=tostring(d[21]) ,Method=tostring(d[22]) ,ProxyAction=tostring(d[23]) ,TargetServer=tostring(d[24]) ,TargetServerVersion=tostring(d[25]) ,RoutingType=tostring(d[26]) ,RoutingHint=tostring(d[27]) ,BackEndCookie=tostring(d[28]) ,ServerLocatorHost=tostring(d[29]) ,ServerLocatorLatency=tostring(d[30]) ,RequestBytes=tostring(d[31]) ,ResponseBytes=tostring(d[32]) ,TargetOutstandingRequests=tostring(d[33]) ,AuthModulePerfContext=tostring(d[34]) ,HttpPipelineLatency=tostring(d[35]) ,CalculateTargetBackEndLatency=tostring(d[36]) ,GlsLatencyBreakup=tostring(d[37]) ,TotalGlsLatency=tostring(d[38]) ,AccountForestLatencyBreakup=tostring(d[39]) ,TotalAccountForestLatency=tostring(d[40]) ,ResourceForestLatencyBreakup=tostring(d[41]) ,TotalResourceForestLatency=tostring(d[42]) ,ADLatency=tostring(d[43]) ,SharedCacheLatencyBreakup=tostring(d[44]) ,TotalSharedCacheLatency=tostring(d[45]) ,ActivityContextLifeTime=tostring(d[46]) ,ModuleToHandlerSwitchingLatency=tostring(d[47]) ,ClientReqStreamLatency=tostring(d[48]) ,BackendReqInitLatency=tostring(d[49]) ,BackendReqStreamLatency=tostring(d[50]) ,BackendProcessingLatency=tostring(d[51]) ,BackendRespInitLatency=tostring(d[52]) ,BackendRespStreamLatency=tostring(d[53]) ,ClientRespStreamLatency=tostring(d[54]) ,KerberosAuthHeaderLatency=tostring(d[55]) ,HandlerCompletionLatency=tostring(d[56]) ,RequestHandlerLatency=tostring(d[57]) ,HandlerToModuleSwitchingLatency=tostring(d[58]) ,ProxyTime=tostring(d[59]) ,CoreLatency=tostring(d[60]) ,RoutingLatency=tostring(d[61]) ,HttpProxyOverhead=tostring(d[62]) ,TotalRequestTime=tostring(d[63]) ,RouteRefresherLatency=tostring(d[64]) ,UrlQuery=tostring(d[65]) ,BackEndGenericInfo=tostring(d[66]) ,GenericInfo=tostring(d[67]) ,GenericErrors=tostring(d[68]) ,EdgeTraceId=tostring(d[69]) ,DatabaseGuid=tostring(d[70]) ,UserADObjectGuid=tostring(d[71]) ,PartitionEndpointLookupLatency=tostring(d[72]) ,RoutingStatus=tostring(d[73]) | extend TimeGenerated = DateTime | project-away d,RawData,DateTime | project-away d,RawData,DateTime\n and click on 'Destination'.\n8. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n9. Click on 'Add data source'.\n10. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 7] HTTP Proxy of Exchange Servers"
+ }
+ ],
+ "metadata": {
+ "id": "2e63ad0e-84e3-4f01-b210-9db0bc42b8ff",
+ "version": "1.0.0",
+ "kind": "dataConnector",
+ "source": {
+ "kind": "solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ },
+ "author": {
+ "name": "Microsoft"
+ }
+ }
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId8'),'/'))))]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion8')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "contentKind": "DataConnector",
+ "displayName": "Microsoft Exchange HTTP Proxy Logs",
+ "contentProductId": "[variables('_dataConnectorcontentProductId8')]",
+ "id": "[variables('_dataConnectorcontentProductId8')]",
+ "version": "[variables('dataConnectorVersion8')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId8'),'/'))))]",
+ "dependsOn": [
+ "[variables('_dataConnectorId8')]"
+ ],
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId8'))]",
+ "contentId": "[variables('_dataConnectorContentId8')]",
+ "kind": "DataConnector",
+ "version": "[variables('dataConnectorVersion8')]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId8'))]",
+ "apiVersion": "2021-03-01-preview",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors",
+ "location": "[parameters('workspace-location')]",
+ "kind": "GenericUI",
+ "properties": {
+ "connectorUiConfig": {
+ "title": "Microsoft Exchange HTTP Proxy Logs",
+ "publisher": "Microsoft",
+ "descriptionMarkdown": "[Option 7] - Using Azure Monitor Agent - You can stream HTTP Proxy logs and Security Event logs from the Windows machines connected to your Microsoft Sentinel workspace using the Windows agent. This connection enables you create custom alerts, and improve investigation. [Learn more](https://aka.ms/ESI_DataConnectorOptions)",
+ "graphQueries": [
+ {
+ "metricName": "Total data received",
+ "legend": "Exchange HTTPProxy logs",
+ "baseQuery": "ExchangeHttpProxy_CL"
+ }
+ ],
+ "dataTypes": [
+ {
+ "name": "ExchangeHttpProxy_CL",
+ "lastDataReceivedQuery": "ExchangeHttpProxy_CL | summarize Time = max(TimeGenerated) | where isnotempty(Time)"
+ }
+ ],
+ "connectivityCriterias": [
+ {
+ "type": "IsConnectedQuery",
+ "value": [
+ "ExchangeHttpProxy_CL | summarize LastLogReceived = max(TimeGenerated) | project IsConnected = LastLogReceived > ago(7h)"
+ ]
+ }
+ ],
+ "sampleQueries": [
+ {
+ "description": "All Audit logs",
+ "query": "ExchangeHttpProxy_CL | sort by TimeGenerated"
+ }
+ ],
+ "availability": {
+ "status": 1,
+ "isPreview": false
+ },
+ "permissions": {
+ "resourceProvider": [
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces",
+ "permissionsDisplayText": "read and write permissions.",
+ "providerDisplayName": "Workspace",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "read": true,
+ "write": true,
+ "delete": true
+ }
+ },
+ {
+ "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys",
+ "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).",
+ "providerDisplayName": "Keys",
+ "scope": "Workspace",
+ "requiredPermissions": {
+ "action": true
+ }
+ }
+ ],
+ "customs": [
+ {
+ "name": "Azure Log Analytics will be deprecated",
+ "description": "Azure Log Analytics will be deprecated, to collect data from non-Azure VMs, Azure Arc is recommended. [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ },
+ {
+ "name": "Detailled documentation",
+ "description": ">**NOTE:** Detailled documentation on Installation procedure and usage can be found [here](https://aka.ms/MicrosoftExchangeSecurityGithub)"
+ }
+ ]
+ },
+ "instructionSteps": [
+ {
+ "description": ">**NOTE:** This solution is based on options. This allows you to choose which data will be ingest as some options can generate a very high volume of data. Depending on what you want to collect, track in your Workbooks, Analytics Rules, Hunting capabilities you will choose the option(s) you will deploy. Each options are independant for one from the other. To learn more about each option: ['Microsoft Exchange Security' wiki](https://aka.ms/ESI_DataConnectorOptions)\n\n>This Data Connector is the **option 7** of the wiki."
+ },
+ {
+ "description": "Type of servers (Exchange Servers, Domain Controllers linked to Exchange Servers or all Domain Controllers) depends on the option you want to deploy.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Deploy Monitor Agents",
+ "description": "This step is required only if it's the first time you onboard your Exchange Servers/Domain Controllers\n**Deploy the Azure Arc Agent**\n> [Learn more](https://docs.microsoft.com/azure/azure-monitor/agents/azure-monitor-agent-install?tabs=ARMAgentPowerShell,PowerShellWindows,PowerShellWindowsArc,CLIWindows,CLIWindowsArc)"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "1. Download and install the agents needed to collect logs for Microsoft Sentinel"
+ },
+ {
+ "description": "Select how to stream HTTP Proxy of Exchange Servers",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Data Collection Rules - When Azure Monitor Agent is used",
+ "description": "**Enable data collection rule**\n> Message Tracking are collected only from **Windows** agents.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template (Prefered Method)",
+ "description": "Use this method for automated deployment of the DCE and DCR.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCEExchangeServers)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. You can change the proposed name of the DCE.\n5. Click **Create** to deploy."
+ },
+ {
+ "title": "B. Deploy Data Connection Rule",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-DCROption7-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID** 'and/or Other required fields'.\n>4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Option 2 - Manual Deployment of Azure Automation",
+ "description": "Use the following step-by-step instructions to deploy manually a Data Collection Rule.",
+ "instructions": [
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "Create Custom Table - Explanation",
+ "description": "The Custom Table can't be created using the Azure Portal. You need to use an ARM template, a PowerShell Script or another method [described here](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/create-custom-table?tabs=azure-powershell-1%2Cazure-portal-2%2Cazure-portal-3#create-a-custom-table)."
+ },
+ {
+ "title": "Create Custom Table using an ARM Template",
+ "description": "1. Click the **Deploy to Azure** button below. \n\n\t[](https://aka.ms/sentinel-ESI-HTTPProxyCustomTable)\n2. Select the preferred **Subscription**, **Resource Group**, **Location** and **Analytic Workspace Name**. \n3. Click **Create** to deploy."
+ },
+ {
+ "title": "Create Custom Table using PowerShell in Cloud Shell",
+ "description": "1. From the Azure Portal, open a Cloud Shell.\n2. Copy and paste and Execute the following script in the Cloud Shell to create the table.\n\t\t$tableParams = @'\n\t\t{\n\t\t\t\"properties\": {\n\t\t\t\t \"schema\": {\n\t\t\t\t\t\t\"name\": \"ExchangeHttpProxy_CL\",\n\t\t\t\t\t\t\"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AccountForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ActivityContextLifeTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ADLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AnchorMailbox\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticatedUser\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthenticationType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"AuthModulePerfContext\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndCookie\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndGenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendProcessingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespInitLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackendRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BackEndStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"BuildVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CalculateTargetBackEndLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientIpAddress\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientReqStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ClientRespStreamLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"CoreLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"DatabaseGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"EdgeTraceId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ErrorCode\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericErrors\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GenericInfo\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"GlsLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerCompletionLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HandlerToModuleSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpPipelineLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpProxyOverhead\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"HttpStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"IsAuthenticated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"KerberosAuthHeaderLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MajorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Method\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"MinorVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ModuleToHandlerSwitchingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Organization\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"PartitionEndpointLookupLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"Protocol\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProtocolAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyAction\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ProxyTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestHandlerLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RequestId\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResourceForestLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ResponseBytes\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RevisionVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RouteRefresherLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingHint\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingStatus\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"RoutingType\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerHostName\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"ServerLocatorLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"SharedCacheLatencyBreakup\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetOutstandingRequests\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServer\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TargetServerVersion\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalAccountForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalGlsLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalRequestTime\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalResourceForestLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TotalSharedCacheLatency\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlHost\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlQuery\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UrlStem\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserADObjectGuid\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"UserAgent\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"TimeGenerated\",\n\t\t\t\t\t\t\t\t\t\"type\": \"datetime\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"name\": \"FilePath\",\n\t\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t }\n\t\t\t }\n\t\t }\n\t\t '@\n3. Copy, Replace, Paste and execute the following parameters with your own values:\n\t\t$SubscriptionID = 'YourGUID'\n\t\t$ResourceGroupName = 'YourResourceGroupName'\n\t\t$WorkspaceName = 'YourWorkspaceName'\n4. Execute the Following Cmdlet to create the table:\n\t\tInvoke-AzRestMethod -Path \"/subscriptions/$SubscriptionID/resourcegroups/$ResourceGroupName/providers/microsoft.operationalinsights/workspaces/$WorkspaceName/tables/ExchangeHttpProxy_CL?api-version=2021-12-01-preview\" -Method PUT -payload $tableParams"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ },
+ {
+ "parameters": {
+ "instructionSteps": [
+ {
+ "title": "A. Create DCE (If not already created for Exchange Servers)",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionEndpoints).\n2. Click **+ Create** at the top.\n3. In the **Basics** tab, fill the required fields and give a name to the DCE. \n3. 'Make other preferable configuration changes', if needed, then click **Create**."
+ },
+ {
+ "title": "B. Create a DCR, Type Custom log",
+ "description": "1. From the Azure Portal, navigate to [Azure Data collection rules](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/dataCollectionRules).\n2. Click on 'Create' button.\n3. On 'Basics' tab, fill the Rule name like **DCR-Option7-HTTPProxyLogs**, select the 'Data Collection Endpoint' with the previously created endpoint and fill other parameters.\n4. In the **Resources** tab, add your Exchange Servers.\n5. In **Collect and Deliver**, add a Data Source type 'Custom Text logs' and enter the following file pattern : \n\t\t'C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Autodiscover\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Eas\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ecp\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Ews\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Mapi\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Oab\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\Owa\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\OwaCalendar\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\PowerShell\\*.log','C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\HttpProxy\\RpcHttp\\*.log'\n6. Put 'ExchangeHttpProxy_CL' in Table Name.\n7. in Transform field, enter the following KQL request :\n\t\tsource | extend d = split(RawData,',') | extend DateTime=todatetime(d[0]),RequestId=tostring(d[1]) ,MajorVersion=tostring(d[2]) ,MinorVersion=tostring(d[3]) ,BuildVersion=tostring(d[4]) ,RevisionVersion=tostring(d[5]) ,ClientRequestId=tostring(d[6]) ,Protocol=tostring(d[7]) ,UrlHost=tostring(d[8]) ,UrlStem=tostring(d[9]) ,ProtocolAction=tostring(d[10]) ,AuthenticationType=tostring(d[11]) ,IsAuthenticated=tostring(d[12]) ,AuthenticatedUser=tostring(d[13]) ,Organization=tostring(d[14]) ,AnchorMailbox=tostring(d[15]) ,UserAgent=tostring(d[16]) ,ClientIpAddress=tostring(d[17]) ,ServerHostName=tostring(d[18]) ,HttpStatus=tostring(d[19]) ,BackEndStatus=tostring(d[20]) ,ErrorCode=tostring(d[21]) ,Method=tostring(d[22]) ,ProxyAction=tostring(d[23]) ,TargetServer=tostring(d[24]) ,TargetServerVersion=tostring(d[25]) ,RoutingType=tostring(d[26]) ,RoutingHint=tostring(d[27]) ,BackEndCookie=tostring(d[28]) ,ServerLocatorHost=tostring(d[29]) ,ServerLocatorLatency=tostring(d[30]) ,RequestBytes=tostring(d[31]) ,ResponseBytes=tostring(d[32]) ,TargetOutstandingRequests=tostring(d[33]) ,AuthModulePerfContext=tostring(d[34]) ,HttpPipelineLatency=tostring(d[35]) ,CalculateTargetBackEndLatency=tostring(d[36]) ,GlsLatencyBreakup=tostring(d[37]) ,TotalGlsLatency=tostring(d[38]) ,AccountForestLatencyBreakup=tostring(d[39]) ,TotalAccountForestLatency=tostring(d[40]) ,ResourceForestLatencyBreakup=tostring(d[41]) ,TotalResourceForestLatency=tostring(d[42]) ,ADLatency=tostring(d[43]) ,SharedCacheLatencyBreakup=tostring(d[44]) ,TotalSharedCacheLatency=tostring(d[45]) ,ActivityContextLifeTime=tostring(d[46]) ,ModuleToHandlerSwitchingLatency=tostring(d[47]) ,ClientReqStreamLatency=tostring(d[48]) ,BackendReqInitLatency=tostring(d[49]) ,BackendReqStreamLatency=tostring(d[50]) ,BackendProcessingLatency=tostring(d[51]) ,BackendRespInitLatency=tostring(d[52]) ,BackendRespStreamLatency=tostring(d[53]) ,ClientRespStreamLatency=tostring(d[54]) ,KerberosAuthHeaderLatency=tostring(d[55]) ,HandlerCompletionLatency=tostring(d[56]) ,RequestHandlerLatency=tostring(d[57]) ,HandlerToModuleSwitchingLatency=tostring(d[58]) ,ProxyTime=tostring(d[59]) ,CoreLatency=tostring(d[60]) ,RoutingLatency=tostring(d[61]) ,HttpProxyOverhead=tostring(d[62]) ,TotalRequestTime=tostring(d[63]) ,RouteRefresherLatency=tostring(d[64]) ,UrlQuery=tostring(d[65]) ,BackEndGenericInfo=tostring(d[66]) ,GenericInfo=tostring(d[67]) ,GenericErrors=tostring(d[68]) ,EdgeTraceId=tostring(d[69]) ,DatabaseGuid=tostring(d[70]) ,UserADObjectGuid=tostring(d[71]) ,PartitionEndpointLookupLatency=tostring(d[72]) ,RoutingStatus=tostring(d[73]) | extend TimeGenerated = DateTime | project-away d,RawData,DateTime | project-away d,RawData,DateTime\n and click on 'Destination'.\n8. In 'Destination', add a destination and select the Workspace where you have previously created the Custom Table \n9. Click on 'Add data source'.\n10. Fill other required parameters and tags and create the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ]
+ }
+ ]
+ },
+ "type": "InstructionStepsGroup"
+ }
+ ],
+ "title": "2. [Option 7] HTTP Proxy of Exchange Servers"
+ }
+ ],
+ "id": "[variables('_uiConfigId8')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject1').parserTemplateSpecName1]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "ExchangeAdminAuditLogs Data Parser with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserObject1').parserVersion1]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('parserObject1')._parserName1]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for ExchangeAdminAuditLogs",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "ExchangeAdminAuditLogs",
+ "query": "let CmdletCheck = externaldata (Cmdlet:string, UserOriented:string, RestrictToParameter:string, Parameters:string)[h\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/CmdletWatchlist.csv\"]with(format=\"csv\",ignoreFirstRecord=true);\nlet SensitiveCmdlets = CmdletCheck | project tostring(Cmdlet) ;\nlet Check = (T:(*)) {\n let fuzzyWatchlist = datatable(displayName:string, userPrincipalName:string, sAMAccountName:string, objectSID:string, objectGUID:guid, canonicalName:string, comment:string) [\n \"NONE\",\"NONE\",\"NONE\",\"NONE\",\"00000001-0000-1000-0000-100000000000\",\"NONE\",\"NONE\"];\n let Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != \"00000001-0000-1000-0000-100000000000\" | project-away TableName;\n let SearchUserDisplayName = T | join Watchlist on $left.TargetObject == $right.displayName | project TargetObject,SearchKey;\n let SearchUserUPN = T | join Watchlist on $left.TargetObject == $right.userPrincipalName | project TargetObject,SearchKey;\n let SearchUserCanonicalName = T | join Watchlist on $left.TargetObject == $right.canonicalName | project TargetObject,SearchKey;\n let SearchUserSAMAccountName = T | join Watchlist on $left.TargetObject == $right.sAMAccountName | project TargetObject,SearchKey;\n let SearchUserObjectSID = T | join Watchlist on $left.TargetObject == $right.objectSID | project TargetObject,SearchKey;\n let SearchUserObjectGUID = T | join (Watchlist | extend objectGuidString = tostring(objectGUID)) on $left.TargetObject == $right.objectGuidString | project TargetObject,SearchKey;\n let SearchUserDistinguishedName = T | join Watchlist on $left.TargetObject == $right.distinguishedName | project TargetObject,SearchKey;\n union isfuzzy=true withsource=TableName \n SearchUserDisplayName, \n SearchUserUPN, \n SearchUserCanonicalName, \n SearchUserSAMAccountName,\n SearchUserObjectSID,\n SearchUserObjectGUID,\n SearchUserDistinguishedName\n };\nlet Env = ExchangeConfiguration(SpecificSectionList=\"ESIEnvironment\")\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\n| project DomainFQDN_, ESIEnvironment;\nlet EventList = Event\n | where EventLog == 'MSExchange Management'\n | where EventID in (1,6) // 1 = Success, 6 = Failure\n | parse ParameterXml with '' CmdletName '' CmdletParameters '' Caller '' *\n | extend TargetObject = iif( CmdletParameters has \"-Identity \", split(split(CmdletParameters,'-Identity ')[1],'\"')[1], iif( CmdletParameters has \"-Name \", split(split(CmdletParameters,'-Name ')[1],'\"')[1], \"\"));\nlet MSExchange_Management = (){\nEventList\n | extend Status = case( EventID == 1, 'Success', 'Failure')\n | join kind=leftouter (EventList | project TargetObject | invoke Check()) on TargetObject\n | extend IsVIP = iif(SearchKey == \"\", false, true)\n | join kind=leftouter ( \n MESCheckVIP() ) on SearchKey\n | extend CmdletNameJoin = tolower(CmdletName)\n | join kind=leftouter ( \n CmdletCheck\n | extend CmdletNameJoin = tolower(Cmdlet)\n ) on CmdletNameJoin\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\n | join kind=leftouter ( \n Env\n ) on $left.DomainEnv == $right.DomainFQDN_\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\"Unknown-\",DomainEnv))\n | extend IsSenstiveCmdlet = iif( isnotempty(CmdletNameJoin1) , true, false) \n | extend IsRestrictedCmdLet = iif(IsSenstiveCmdlet == true, iif( RestrictToParameter == \"Yes\", true, false), dynamic(null))\n | extend RestrictedParameters = iif(IsSenstiveCmdlet == true, split(tolower(Parameters),';'), dynamic(null))\n | extend ExtractedParameters = iif(IsSenstiveCmdlet == true,extract_all(@\"\\B(-\\w+)\", tolower(CmdletParameters)), dynamic(null))\n | extend IsSenstiveCmdletParameters = iif(IsSenstiveCmdlet == true,iif( array_length(set_difference(ExtractedParameters,RestrictedParameters)) == array_length(ExtractedParameters), false, true ) , false)\n | extend IsSensitive = iif( ( IsSenstiveCmdlet == true and IsRestrictedCmdLet == false ) or (IsSenstiveCmdlet == true and IsRestrictedCmdLet == true and IsSenstiveCmdletParameters == true ), true, false )\n | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,canonicalName,displayName,distinguishedName,objectGUID,objectSID,sAMAccountName,userPrincipalName,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment\n};\nMSExchange_Management\n",
+ "functionParameters": "",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject1')._parserId1]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ExchangeAdminAuditLogs Data Parser')]",
+ "contentId": "[variables('parserObject1').parserContentId1]",
+ "kind": "Parser",
+ "version": "[variables('parserObject1').parserVersion1]",
+ "source": {
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "kind": "Solution",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject1').parserContentId1]",
"contentKind": "Parser",
"displayName": "Parser for ExchangeAdminAuditLogs",
"contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.3.0')))]",
@@ -2257,7 +5124,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeConfiguration Data Parser with template version 3.1.5",
+ "description": "ExchangeConfiguration Data Parser with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject2').parserVersion2]",
@@ -2387,7 +5254,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeEnvironmentList Data Parser with template version 3.1.5",
+ "description": "ExchangeEnvironmentList Data Parser with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject3').parserVersion3]",
@@ -2517,7 +5384,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "MESCheckVIP Data Parser with template version 3.1.5",
+ "description": "MESCheckVIP Data Parser with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserObject4').parserVersion4]",
@@ -2638,6 +5505,136 @@
}
}
},
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserObject5').parserTemplateSpecName5]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "MESCompareDataOnPMRA Data Parser with template version 3.3.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserObject5').parserVersion5]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('parserObject5')._parserName5]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for MRA Configuration Data Comparison On-Premises",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "MESCompareDataOnPMRA",
+ "query": "// Version: 1.0.0\n// Last Updated: 30/08/2024\n// \n// DESCRIPTION:\n// This parser is used to compare the data of a specific section of the Exchange Online Configuration. It will compare the data of a specific section between two dates and return the differences between them.\n//\n// USAGE:\n// Parameters : 7 parameters to add during creation. \n// 1. SectionCompare, type string, default value \"\"\n// 2. DateCompare, type string, default value \"lastdate\"\n// 3. CurrentDate, type string, default value \"lastdate\"\n// 4. EnvList, type string, default value \"All\"\n// 5. TypeEnv, type string, default value \"Online\"\n// 6. CurrentRole, type string, default value \"\"\n// 7. ExclusionsAcct, type dynamic, default value dynamic(\"\")\n//\n// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SectionCompare = \"SampleEntry\";\n// let EnvList = \"All\";\n// let TypeEnv = \"Online\";\n// let CurrentRole = \"\";\n// let ExclusionsAcct = dynamic(\"\");\n// let DateCompare = \"lastdate\";\n// let CurrentDate = \"lastdate\";\n//\n// Parameters definition\nlet _SectionCompare = SectionCompare;\nlet _EnvList =EnvList;\nlet _TypeEnv = TypeEnv;\nlet _CurrentRole =CurrentRole;\nlet _ExclusionsAcct = ExclusionsAcct;\nlet _DateCompare = DateCompare;\nlet _CurrentDate = CurrentDate;\nlet _DateCompareB = todatetime(DateCompare);\nlet _currD = (ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\n| summarize TimeMax = max(TimeGenerated)\n| extend TimeMax = tostring(split(TimeMax,\"T\")[0])\n| project TimeMax);\nlet _CurrentDateB = todatetime(toscalar(_currD));\nlet BeforeData = \n ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_DateCompare,SpecificConfigurationEnv=_EnvList,Target=_TypeEnv)\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend Role = tostring(CmdletResultValue.Role)\n ; \nlet AfterData = \n ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend Role = tostring(CmdletResultValue.Role)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n ;\nlet i=0;\nlet allDataRange = \n ESIExchangeConfig_CL\n | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\n | where ESIEnvironment_s == _EnvList\n | where Section_s == \"MRA\"\n | extend CmdletResultValue = parse_json(rawData_s)\n | project TimeGenerated,CmdletResultValue,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend Role = tostring(CmdletResultValue.Role)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n ;\nlet DiffAddDataP1 = allDataRange\n | join kind = rightanti (AfterData | where WhenCreated >=_DateCompareB) on WhenCreated\n;\nlet DiffAddDataP2 = allDataRange\n | join kind = innerunique (allDataRange ) on WhenCreated\n | where WhenCreated >=_DateCompareB\n | where bin(WhenCreated,5m)==bin(WhenChanged,5m)\n | distinct ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n;\nlet DiffAddData = union DiffAddDataP1,DiffAddDataP2\n| extend Actiontype =\"Add\";\nlet DiffRemoveData = allDataRange\n | join kind = leftanti AfterData on RoleAssigneeName\n | extend Actiontype =\"Remove\"\n | distinct Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n | project WhenChanged=_CurrentDateB,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n ;\nlet DiffModifData = union AfterData,allDataRange\n| sort by ManagementRoleAssignement,WhenChanged asc\n| extend Status = iff( ManagementRoleAssignement == prev(ManagementRoleAssignement) and Status != prev(Status) and prev(Status) !=\"\" , strcat(\"📍 \", Status, \" (\",prev(Status),\"->\", Status,\" )\"),Status)\n| extend CustomRecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomRecipientWriteScope != prev(CustomRecipientWriteScope) and prev(CustomRecipientWriteScope) !=\"\" , strcat(\"📍 \", CustomRecipientWriteScope, \" (\", prev(CustomRecipientWriteScope),\"->\", CustomRecipientWriteScope, \")\"),CustomRecipientWriteScope)\n| extend CustomConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomConfigWriteScope != prev(CustomConfigWriteScope) and prev(CustomConfigWriteScope) !=\"\" , strcat(\"📍 \", CustomConfigWriteScope, \" (\", prev(CustomConfigWriteScope),\"->\", CustomConfigWriteScope, \")\"),CustomConfigWriteScope)\n| extend RecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and RecipientWriteScope != prev(RecipientWriteScope) and prev(RecipientWriteScope) !=\"\" , strcat(\"📍 \", RecipientWriteScope, \" (\", prev(RecipientWriteScope),\"->\", RecipientWriteScope, \")\"),RecipientWriteScope)\n| extend ConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and ConfigWriteScope != prev(ConfigWriteScope) and prev(ConfigWriteScope) !=\"\" , strcat(\"📍 \", ConfigWriteScope, \" (\", prev(ConfigWriteScope),\"->\", ConfigWriteScope, \")\"),ConfigWriteScope)\n| extend ActiontypeR =iff((Status contains \"📍\" or CustomRecipientWriteScope contains\"📍\" or CustomConfigWriteScope contains\"📍\" or RecipientWriteScope contains\"📍\" or ConfigWriteScope contains\"📍\" ), i=i + 1, i)\n| extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\n| where ActiontypeR == 1\n| project WhenChanged,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n;\nunion DiffAddData, DiffRemoveData, DiffModifData\n| extend RoleAssigneeName = iff(RoleAssigneeType == \"User\", strcat(\"🧑🦰 \", RoleAssigneeName), strcat(\"👪 \", RoleAssigneeName))\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\",WhenCreated, WhenChanged))\n//| extend WhenChanged = case(Actiontype == \"Modif\" , tostring(bin(WhenChanged,1m)), Actiontype == \"Add\",tostring(bin(WhenChanged,1m)),Actiontype == \"Remove\",\"NoInformation\",\"N/A\")\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\n| sort by WhenChanged desc \n| project\n WhenChanged,\n Actiontype,\n RoleAssigneeName,\n RoleAssigneeType,\n Status,\n CustomRecipientWriteScope,\n CustomConfigWriteScope, \n RecipientWriteScope, \n ConfigWriteScope,\n ManagementRoleAssignement,\n RoleAssignmentDelegationType,\n WhenCreated\n",
+ "functionParameters": "SectionCompare:string='',DateCompare:string='lastdate',CurrentDate:string='lastdate',EnvList:string='All',TypeEnv:string='Online',CurrentRole:string='',ExclusionsAcct:dynamic=dynamic('')",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject5')._parserId5,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject5')._parserId5]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'MESCompareDataOnPMRA')]",
+ "contentId": "[variables('parserObject5').parserContentId5]",
+ "kind": "Parser",
+ "version": "[variables('parserObject5').parserVersion5]",
+ "source": {
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "kind": "Solution",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ }
+ ]
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('parserObject5').parserContentId5]",
+ "contentKind": "Parser",
+ "displayName": "Parser for MRA Configuration Data Comparison On-Premises",
+ "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject5').parserContentId5,'-', '1.0.0')))]",
+ "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject5').parserContentId5,'-', '1.0.0')))]",
+ "version": "[variables('parserObject5').parserVersion5]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('parserObject5')._parserName5]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for MRA Configuration Data Comparison On-Premises",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "MESCompareDataOnPMRA",
+ "query": "// Version: 1.0.0\n// Last Updated: 30/08/2024\n// \n// DESCRIPTION:\n// This parser is used to compare the data of a specific section of the Exchange Online Configuration. It will compare the data of a specific section between two dates and return the differences between them.\n//\n// USAGE:\n// Parameters : 7 parameters to add during creation. \n// 1. SectionCompare, type string, default value \"\"\n// 2. DateCompare, type string, default value \"lastdate\"\n// 3. CurrentDate, type string, default value \"lastdate\"\n// 4. EnvList, type string, default value \"All\"\n// 5. TypeEnv, type string, default value \"Online\"\n// 6. CurrentRole, type string, default value \"\"\n// 7. ExclusionsAcct, type dynamic, default value dynamic(\"\")\n//\n// Parameters simulation\n// If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values.\n//\n// let SectionCompare = \"SampleEntry\";\n// let EnvList = \"All\";\n// let TypeEnv = \"Online\";\n// let CurrentRole = \"\";\n// let ExclusionsAcct = dynamic(\"\");\n// let DateCompare = \"lastdate\";\n// let CurrentDate = \"lastdate\";\n//\n// Parameters definition\nlet _SectionCompare = SectionCompare;\nlet _EnvList =EnvList;\nlet _TypeEnv = TypeEnv;\nlet _CurrentRole =CurrentRole;\nlet _ExclusionsAcct = ExclusionsAcct;\nlet _DateCompare = DateCompare;\nlet _CurrentDate = CurrentDate;\nlet _DateCompareB = todatetime(DateCompare);\nlet _currD = (ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\n| summarize TimeMax = max(TimeGenerated)\n| extend TimeMax = tostring(split(TimeMax,\"T\")[0])\n| project TimeMax);\nlet _CurrentDateB = todatetime(toscalar(_currD));\nlet BeforeData = \n ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_DateCompare,SpecificConfigurationEnv=_EnvList,Target=_TypeEnv)\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend Role = tostring(CmdletResultValue.Role)\n ; \nlet AfterData = \n ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv)\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend Role = tostring(CmdletResultValue.Role)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n ;\nlet i=0;\nlet allDataRange = \n ESIExchangeConfig_CL\n | where TimeGenerated between (_DateCompareB .. _CurrentDateB)\n | where ESIEnvironment_s == _EnvList\n | where Section_s == \"MRA\"\n | extend CmdletResultValue = parse_json(rawData_s)\n | project TimeGenerated,CmdletResultValue,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t\n | where CmdletResultValue.Role contains _CurrentRole\n and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct)\n and CmdletResultValue.Name !contains \"Deleg\"\n | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\n | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \"0\" or CmdletResultValue.RoleAssigneeType== \"2\" , \"User\", CmdletResultValue.RoleAssigneeType== \"10\",\"Group\",\"LinkedGroup\")\n | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\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\")\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\"0\",\"None\",CmdletResultValue.ConfigWriteScope==\"7\",\"CustomConfigScope\",CmdletResultValue.ConfigWriteScope==\"10\",\"OrganizationConfig\",\"NotApplicable\")\n | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\n | extend Status= tostring(CmdletResultValue.Enabled)\n | extend Role = tostring(CmdletResultValue.Role)\n | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == \"6\" or CmdletResultValue.RoleAssignmentDelegationType == \"Delegating\", \"Delegating\", \"Regular\") \n ;\nlet DiffAddDataP1 = allDataRange\n | join kind = rightanti (AfterData | where WhenCreated >=_DateCompareB) on WhenCreated\n;\nlet DiffAddDataP2 = allDataRange\n | join kind = innerunique (allDataRange ) on WhenCreated\n | where WhenCreated >=_DateCompareB\n | where bin(WhenCreated,5m)==bin(WhenChanged,5m)\n | distinct ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n;\nlet DiffAddData = union DiffAddDataP1,DiffAddDataP2\n| extend Actiontype =\"Add\";\nlet DiffRemoveData = allDataRange\n | join kind = leftanti AfterData on RoleAssigneeName\n | extend Actiontype =\"Remove\"\n | distinct Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n | project WhenChanged=_CurrentDateB,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n ;\nlet DiffModifData = union AfterData,allDataRange\n| sort by ManagementRoleAssignement,WhenChanged asc\n| extend Status = iff( ManagementRoleAssignement == prev(ManagementRoleAssignement) and Status != prev(Status) and prev(Status) !=\"\" , strcat(\"📍 \", Status, \" (\",prev(Status),\"->\", Status,\" )\"),Status)\n| extend CustomRecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomRecipientWriteScope != prev(CustomRecipientWriteScope) and prev(CustomRecipientWriteScope) !=\"\" , strcat(\"📍 \", CustomRecipientWriteScope, \" (\", prev(CustomRecipientWriteScope),\"->\", CustomRecipientWriteScope, \")\"),CustomRecipientWriteScope)\n| extend CustomConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomConfigWriteScope != prev(CustomConfigWriteScope) and prev(CustomConfigWriteScope) !=\"\" , strcat(\"📍 \", CustomConfigWriteScope, \" (\", prev(CustomConfigWriteScope),\"->\", CustomConfigWriteScope, \")\"),CustomConfigWriteScope)\n| extend RecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and RecipientWriteScope != prev(RecipientWriteScope) and prev(RecipientWriteScope) !=\"\" , strcat(\"📍 \", RecipientWriteScope, \" (\", prev(RecipientWriteScope),\"->\", RecipientWriteScope, \")\"),RecipientWriteScope)\n| extend ConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and ConfigWriteScope != prev(ConfigWriteScope) and prev(ConfigWriteScope) !=\"\" , strcat(\"📍 \", ConfigWriteScope, \" (\", prev(ConfigWriteScope),\"->\", ConfigWriteScope, \")\"),ConfigWriteScope)\n| extend ActiontypeR =iff((Status contains \"📍\" or CustomRecipientWriteScope contains\"📍\" or CustomConfigWriteScope contains\"📍\" or RecipientWriteScope contains\"📍\" or ConfigWriteScope contains\"📍\" ), i=i + 1, i)\n| extend Actiontype =iff(ActiontypeR > 0, \"Modif\", \"NO\")\n| where ActiontypeR == 1\n| project WhenChanged,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated\n;\nunion DiffAddData, DiffRemoveData, DiffModifData\n| extend RoleAssigneeName = iff(RoleAssigneeType == \"User\", strcat(\"🧑🦰 \", RoleAssigneeName), strcat(\"👪 \", RoleAssigneeName))\n| extend WhenChanged = iff (Actiontype == \"Modif\", WhenChanged, iff(Actiontype == \"Add\",WhenCreated, WhenChanged))\n//| extend WhenChanged = case(Actiontype == \"Modif\" , tostring(bin(WhenChanged,1m)), Actiontype == \"Add\",tostring(bin(WhenChanged,1m)),Actiontype == \"Remove\",\"NoInformation\",\"N/A\")\n| extend Actiontype = case(Actiontype == \"Add\", strcat(\"➕ \", Actiontype), Actiontype == \"Remove\", strcat(\"➖ \", Actiontype), Actiontype == \"Modif\", strcat(\"📍 \", Actiontype), \"N/A\")\n| sort by WhenChanged desc \n| project\n WhenChanged,\n Actiontype,\n RoleAssigneeName,\n RoleAssigneeType,\n Status,\n CustomRecipientWriteScope,\n CustomConfigWriteScope, \n RecipientWriteScope, \n ConfigWriteScope,\n ManagementRoleAssignement,\n RoleAssignmentDelegationType,\n WhenCreated\n",
+ "functionParameters": "SectionCompare:string='',DateCompare:string='lastdate',CurrentDate:string='lastdate',EnvList:string='All',TypeEnv:string='Online',CurrentRole:string='',ExclusionsAcct:dynamic=dynamic('')",
+ "version": 2,
+ "tags": [
+ {
+ "name": "description",
+ "value": ""
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject5')._parserId5,'/'))))]",
+ "dependsOn": [
+ "[variables('parserObject5')._parserId5]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'MESCompareDataOnPMRA')]",
+ "contentId": "[variables('parserObject5').parserContentId5]",
+ "kind": "Parser",
+ "version": "[variables('parserObject5').parserVersion5]",
+ "source": {
+ "kind": "Solution",
+ "name": "Microsoft Exchange Security - Exchange On-Premises",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "Microsoft",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "Community",
+ "tier": "Community",
+ "link": "https://github.com/Azure/Azure-Sentinel/issues"
+ }
+ }
+ },
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
@@ -2647,7 +5644,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Least Privilege with RBAC Workbook with template version 3.1.5",
+ "description": "Microsoft Exchange Least Privilege with RBAC Workbook with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -2738,7 +5735,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Search AdminAuditLog Workbook with template version 3.1.5",
+ "description": "Microsoft Exchange Search AdminAuditLog Workbook with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -2829,7 +5826,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Admin Activity Workbook with template version 3.1.5",
+ "description": "Microsoft Exchange Admin Activity Workbook with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -2920,7 +5917,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Security Review Workbook with template version 3.1.5",
+ "description": "Microsoft Exchange Security Review Workbook with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion4')]",
@@ -2938,7 +5935,7 @@
},
"properties": {
"displayName": "[parameters('workbook4-name')]",
- "serializedData": "{\"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,\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"a88b4e41-eb2f-41bf-92d8-27c83650a4b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"DateOfConfiguration\",\"label\":\"Collection time\",\"type\":2,\"isRequired\":true,\"query\":\"let _configurationEnv = split(iff(isnull({EnvironmentList}) or isempty({EnvironmentList}) or tolower({EnvironmentList}) == \\\"all\\\",\\\"All\\\",tostring({EnvironmentList})),',');\\r\\nESIExchangeConfig_CL\\r\\n| extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n| where ScopedEnvironment in (_configurationEnv)\\r\\n| extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n| summarize Collection = max(Collection)\\r\\n| project Collection = \\\"lastdate\\\", Selected = true\\r\\n| join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | summarize by Collection \\r\\n | join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm ')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | join kind=leftouter (\\r\\n ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | summarize count() by Collection\\r\\n ) on Collection\\r\\n ) on Collection\\r\\n) on Collection\\r\\n| project Value = iif(Selected,Collection,iif(count_ > 1,PreciseCollection,Collection1)), Label = iif(Selected,\\\"Last Known date\\\",iif(count_ > 1,PreciseCollection,Collection1)), Selected\\r\\n| sort by Selected, Value desc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"8ac96eb3-918b-4a36-bcc4-df50d8f46175\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Help\",\"label\":\"Show Help\",\"type\":10,\"isRequired\":true,\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"[\\\\r\\\\n { \\\\\\\"value\\\\\\\": \\\\\\\"Yes\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"Yes\\\\\\\"},\\\\r\\\\n {\\\\\\\"value\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"selected\\\\\\\":true }\\\\r\\\\n]\\\\r\\\\n\\\"}\\r\\n\",\"timeContext\":{\"durationMs\":2592000000},\"queryType\":8}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"TimeRange\"},{\"type\":1,\"content\":{\"json\":\"This workbook helps review your Exchange Security configuration.\\r\\nSelect your Exchange Organization and adjust the time range.\\r\\nBy default, the Help won't be displayed. To display the help, choose Yes on the toogle buttom \\\"Show Help\\\"\",\"style\":\"info\"},\"name\":\"text - 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 display the Exchange version and the CU installed.\\r\\n\\r\\nFor the latest build number, check this link : Exchange Build Numbers\\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.\\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://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExchBuildNumber.csv\\\"]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://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExchBuildNumber.csv\\\"]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\\nAdmin Audit Log \\r\\n\\r\\nManage Admin Audit Log \\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 with to identify the necessary privileges)\\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. Remember that AdminAudit log need 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://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/CmdletWatchlist.csv\\\"]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}}]},\"name\":\"group - 0Admin Audit Log configuration\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\"},\"name\":\"POP authentication 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 who need to actually 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\\nConfiguring Authentication for POP3 and IMAP4\\r\\n \\r\\n Set-PopSettings\\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 contains (\\\"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\":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 needs 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\\nConfiguring Authentication for POP3 and IMAP4\\r\\n\\r\\n Set-IMAPSettings\\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 contains (\\\"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\":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 Configuration Partition for Exchange container. By selecting Yes for Generic All buttom only delegation set for Generic All will be display. 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 run 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 Exchange 2013 deployment permissions reference\\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\":\"AccessRights\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"AccessRights\",\"sortOrder\":1}]},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"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 :
\\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.Name !contains \\\"Deleg\\\" and CmdletResultValue.RoleAssigneeName != \\\"Hygiene Management\\\" and CmdletResultValue.RoleAssigneeName != \\\"Exchange Online-ApplicationAccount\\\" and CmdletResultValue.RoleAssigneeName != \\\"Discovery Management\\\"\\r\\n| where CmdletResultValue.Name !contains \\\"Deleg\\\" \\r\\n| where CmdletResultValue.RoleAssigneeName !in (\\\"Hygiene Management\\\",\\\"Exchange Online-ApplicationAccount\\\",\\\"Discovery Management\\\")\\r\\n| where CmdletResultValue.Role.Name contains \\\"Export\\\" or CmdletResultValue.Role.Name contains \\\"Impersonation\\\" or (CmdletResultValue.Role.Name contains \\\"Search\\\" and CmdletResultValue.Role.Name !contains \\\"MailboxSearchApplication\\\")\\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 account to access and modify the content of every mailboxes using EWS.\"},\"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\\nHelp for the role Application Impersonation\\r\\n\\r\\nIt is common (but not recommended) to see service accounts from backup solution, antivirus software, MDM... with this delegation.\\r\\n\\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 contains \\\"Impersonation\\\" and CmdletResultValue.RoleAssigneeName != \\\"Hygiene Management\\\" and CmdletResultValue.Name !contains \\\"Deleg\\\"\\r\\n//| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\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}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"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 search 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\\nHelp for the role Mailbox Import Export\\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 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 contains \\\"export\\\" and CmdletResultValue.Name !contains \\\"Deleg\\\"\\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}}]},\"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 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\\nDelegating delegation to Organization Management\\r\\nExchange Online-ApplicationAccount\\r\\nDiscovery Management has been excluded\\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\\nHelp for the role Mailbox Search\\r\\n\\r\\nℹ️ Recommendations\\r\\n\\r\\nIf you temporarily need this delegation, consider the following:\\r\\n\\r\\n- add the administrators in the Discovery Management group\\r\\n- monitor the group content and alert when the group 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 contains \\\"search\\\" and CmdletResultValue.Name !contains \\\"Deleg\\\"\\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}}]},\"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 are delegations at the database level.\\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\\nHelp for Receive As Permission\\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.Change 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\\nHelp for Send As Permission\\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.Change the password as often as possible.\\r\\n\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"SendAsHelp\"},{\"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| 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| summarize dcount(tostring(CmdletResultValue.Identity.Name)) by iff( tostring(Section) contains \\\"MailboxDatabaseReceiveAs\\\",\\\"ReceiveAs Unique DB\\\",\\\"SendAs Unique DB\\\")\",\"size\":1,\"showAnalytics\":true,\"title\":\"ReceiveAs/SendAs database 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| extend Account = tostring(CmdletResultValue.UserString)\\r\\n| extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\\r\\n| summarize Count =count() by Account,DatabaseName\\r\\n| project Account,Count,DatabaseName\\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| extend Account = tostring(CmdletResultValue.UserString)\\r\\n| extend DatabaseName = tostring(CmdletResultValue.Identity.Name)\\r\\n| summarize Count =count() by Account, DatabaseName\\r\\n| project Account, Count, DatabaseName\",\"size\":1,\"showAnalytics\":true,\"title\":\"SendAs Extended Right on databases\",\"noDataMessage\":\"No Send-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\",\"compositeBarSettings\":{\"labelText\":\"\"}}}],\"rowLimit\":10000,\"filter\":true,\"hierarchySettings\":{\"treeType\":1,\"groupBy\":[\"Account\"],\"finalBy\":\"Account\"},\"labelSettings\":[{\"columnId\":\"Account\",\"comment\":\"Account and the number of databases on which it has delegation \"}]}},\"customWidth\":\"50\",\"name\":\"MailboxDatabaseSendAsGrid\",\"styleSettings\":{\"showBorder\":true}}]},\"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 refer 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 differents sorting, displays...\"},\"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.\\r\\n\\r\\nIt is considered 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\\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\":\"**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 all servers\",\"expandable\":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\",\"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\":\"Number of 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\"},{\"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 view 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 the user comprised\\r\\n- **inconsistent memebrs** 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\":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 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\",\"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 user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 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\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"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 the two most sensistive groups in Exchange. This group has all privileges in Exchange and very high privileges in AD.\\r\\n\\r\\nExchange 2013 deployment permissions reference\\r\\n\\r\\nThis group should only contains 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 the two most sensistive groups in Exchange. This group has very high privileges in AD.\\r\\n\\r\\nExchange 2013 deployment permissions reference\\r\\n\\r\\nThis group should only contains 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\",\"title\":\"Exchange Windows Permissions direct nonstandard content (Exchange Trusted subsystem non standard content not included)\",\"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 = 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 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 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\\nHelp for Built-in role groups\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 0\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"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 details on the content of old groups\",\"expandable\":true,\"expanded\":false,\"items\":[{\"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\"},{\"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 user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 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=\\\"lastdate\\\", SpecificConfigurationEnv='B13', 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)| 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)) on ObjectGuid) ;\\r\\nExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\", SpecificConfigurationDate=\\\"lastdate\\\", SpecificConfigurationEnv='B13', 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 DN = tostring(CmdletResultValue.DN)\\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| project Parentgroup, MemberPath, Level, ObjectClass,LastLogon, LastPwdSet ,Enabled,DN\\r\\n\",\"size\":1,\"showAnalytics\":true,\"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}}]},\"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 are 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 pernissions to execute their tasks.\\r\\n- Use just in time administration principle by adding users in a group only when they need the 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\\nHelp for Built-in role groups\",\"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\":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\"},{\"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 user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 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//| extend MemberPath = case( ObjectClass == \\\"group\\\", strcat( \\\"👪 \\\", MemberPath), ObjectClass == \\\"computer\\\", strcat( \\\"💻 \\\", MemberPath), strcat( \\\"🧑🦰 \\\", MemberPath) )\\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}}]},\"name\":\"Exchange group\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"AD Group\",\"items\":[{\"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| 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\",\"gridSettings\":{\"rowLimit\":10000}},{\"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 user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 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//| extend MemberPath = case( ObjectClass == \\\"group\\\", strcat( \\\"👪 \\\", MemberPath), ObjectClass == \\\"computer\\\", strcat( \\\"💻 \\\", MemberPath), strcat( \\\"🧑🦰 \\\", MemberPath) )\\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}}]},\"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 differents security configuration for transport components.\"},\"name\":\"text - 10\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Receive Connectors\",\"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\\nAllow anonymous relay on Exchange server\\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\"},{\"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 toogle buttom help you to sort by:\\r\\n\\r\\n- Server\\r\\n- Receive connectors with 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.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}}]},\"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\\nAllow anonymous relay on Exchange server\\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\"},{\"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 toogle buttom help you to sort by:\\r\\n\\r\\n- Server\\r\\n- Receive connectors with 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}}]},\"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\"},{\"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 toogle buttom help you to sort by:\\r\\n\\r\\n- Server\\r\\n- Receive connectors with 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}}]},\"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\\nMail flow rules in Exchange Serve\\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}}]},\"name\":\"Transport Rules actions to monitor\"},{\"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\\nJournaling in Exchange Server\\r\\n\\r\\nJournaling procedures\\r\\n\\r\\n\\r\\nMailbox audit logging in Exchange Server\\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 Identity = tostring(CmdletResultValue.Identity)\\r\\n| extend Status= iff ( tostring(CmdletResultValue.Enabled)== \\\"Enabled\\\" or tostring(CmdletResultValue.Enabled)== \\\"1\\\" , \\\"Enabled\\\", iff(tostring(CmdletResultValue.Enabled)==\\\"\\\",\\\"\\\", \\\"Disabled\\\"))\\r\\n//| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend JournalEmailAddress = tostring(CmdletResultValue.JournalEmailAddress)\\r\\n| extend Recipient = tostring(CmdletResultValue.Recipient)\\r\\n| sort by Identity 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\":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\\nJournaling in Exchange Server\\r\\n\\r\\nJournaling procedures\\r\\n\\r\\n\\r\\nMailbox audit logging in Exchange Server\\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 Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend JournalRecipient = tostring(CmdletResultValue.JournalRecipient)\\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\"},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"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\\nRemote Domains\\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\":1,\"content\":{\"json\":\"Accepted domains set to * authorize Open Relay.\\r\\n\\r\\nMore information:\\r\\n\\r\\nAccepted domains\\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}}]},\"name\":\"ForwardGroup\"}]},\"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\"}\r\n",
+ "serializedData": "{\"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,\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"a88b4e41-eb2f-41bf-92d8-27c83650a4b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"DateOfConfiguration\",\"label\":\"Collection time\",\"type\":2,\"isRequired\":true,\"query\":\"let _configurationEnv = split(iff(isnull({EnvironmentList}) or isempty({EnvironmentList}) or tolower({EnvironmentList}) == \\\"all\\\",\\\"All\\\",tostring({EnvironmentList})),',');\\r\\nESIExchangeConfig_CL\\r\\n| extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n| where ScopedEnvironment in (_configurationEnv)\\r\\n| extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n| summarize Collection = max(Collection)\\r\\n| project Collection = \\\"lastdate\\\", Selected = true\\r\\n| join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | summarize by Collection \\r\\n | join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm ')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | join kind=leftouter (\\r\\n ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | summarize count() by Collection\\r\\n ) on Collection\\r\\n ) on Collection\\r\\n) on Collection\\r\\n| project Value = iif(Selected,Collection,iif(count_ > 1,PreciseCollection,Collection1)), Label = iif(Selected,\\\"Last Known date\\\",iif(count_ > 1,PreciseCollection,Collection1)), Selected\\r\\n| sort by Selected, Value desc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"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\":{\"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\":{\"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 : Exchange Build Numbers\\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\\nAdmin Audit Log \\r\\n\\r\\nManage Admin Audit Log \\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\\nConfiguring Authentication for POP3 and IMAP4\\r\\n \\r\\n Set-PopSettings\\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\\nConfiguring Authentication for POP3 and IMAP4\\r\\n\\r\\n Set-IMAPSettings\\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 Exchange 2013 deployment permissions reference\\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 :
\\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\\nHelp for the role Application Impersonation\\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\\nHelp for the role Mailbox Import Export\\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\\nHelp for the role Mailbox Search\\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\\nHelp for Receive As Permission\\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\\nHelp for Send As Permission\\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\":{\"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\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"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\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"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\\nExchange 2013 deployment permissions reference\\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\\nExchange 2013 deployment permissions reference\\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\\nHelp for Built-in role groups\",\"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\"},{\"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\\nHelp for Built-in role groups\",\"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\"},{\"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\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"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\\nAllow anonymous relay on Exchange server\\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\"},{\"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\\nAllow anonymous relay on Exchange server\\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\"},{\"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\"},{\"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\\nMail flow rules in Exchange Server\\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\\nJournaling in Exchange Server\\r\\n\\r\\nJournaling procedures\\r\\n\\r\\n\\r\\nMailbox audit logging in Exchange Server\\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\\nJournaling in Exchange Server\\r\\n\\r\\nJournaling procedures\\r\\n\\r\\n\\r\\nMailbox audit logging in Exchange Server\\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\\nRemote Domains\\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\\nAccepted domains\\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\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -2949,7 +5946,7 @@
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId4'),'/'))))]",
"properties": {
- "description": "@{workbookKey=MicrosoftExchangeSecurityReview; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.1; title=Microsoft Exchange Security Review; templateRelativePath=Microsoft Exchange Security Review.json; subtitle=; provider=Microsoft}.description",
+ "description": "@{workbookKey=MicrosoftExchangeSecurityReview; logoFileName=Azure_Sentinel.svg; description=This Workbook is dedicated to On-Premises Exchange organizations. It displays and highlights current Security configuration on various Exchange components including delegations, rights on databases, Exchange and most important AD Groups with members including nested groups, local administrators of servers. This workbook helps also to understand the transport configuration and the linked security risks. Required Data Connector: Exchange Security Insights On-Premises Collector.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=2.0.0; title=Microsoft Exchange Security Review; templateRelativePath=Microsoft Exchange Security Review.json; subtitle=; provider=Microsoft}.description",
"parentId": "[variables('workbookId4')]",
"contentId": "[variables('_workbookContentId4')]",
"kind": "Workbook",
@@ -3011,7 +6008,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.1.5",
+ "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject1').analyticRuleVersion1]",
@@ -3057,54 +6054,54 @@
],
"entityMappings": [
{
- "entityType": "Mailbox",
"fieldMappings": [
{
- "identifier": "MailboxPrimaryAddress",
- "columnName": "TargetObject"
+ "columnName": "TargetObject",
+ "identifier": "MailboxPrimaryAddress"
}
- ]
+ ],
+ "entityType": "Mailbox"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Sid",
- "columnName": "TargetObject"
+ "columnName": "TargetObject",
+ "identifier": "Sid"
},
{
- "identifier": "ObjectGuid",
- "columnName": "TargetObject"
+ "columnName": "TargetObject",
+ "identifier": "ObjectGuid"
},
{
- "identifier": "FullName",
- "columnName": "TargetObject"
+ "columnName": "TargetObject",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Caller"
+ "columnName": "Caller",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "Account"
}
],
"alertDetailsOverride": {
- "alertSeverityColumnName": "Level",
"alertDisplayNameFormat": "{{CmdletName}} executed on {{TargetObject}}",
- "alertDescriptionFormat": "Alert from Microsoft Exchange Security as {{CmdletName}} with parameters {{CmdletParameters}} was executed on {{TargetObject}}"
+ "alertDescriptionFormat": "Alert from Microsoft Exchange Security as {{CmdletName}} with parameters {{CmdletParameters}} was executed on {{TargetObject}}",
+ "alertSeverityColumnName": "Level"
}
}
},
@@ -3158,7 +6155,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.1.5",
+ "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.3.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleObject2').analyticRuleVersion2]",
@@ -3204,48 +6201,48 @@
],
"entityMappings": [
{
- "entityType": "Mailbox",
"fieldMappings": [
{
- "identifier": "MailboxPrimaryAddress",
- "columnName": "userPrincipalName"
+ "columnName": "userPrincipalName",
+ "identifier": "MailboxPrimaryAddress"
},
{
- "identifier": "Upn",
- "columnName": "userPrincipalName"
+ "columnName": "userPrincipalName",
+ "identifier": "Upn"
}
- ]
+ ],
+ "entityType": "Mailbox"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "ServerCmdletTargetObject"
+ "columnName": "ServerCmdletTargetObject",
+ "identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Caller"
+ "columnName": "Caller",
+ "identifier": "Name"
},
{
- "identifier": "ObjectGuid",
- "columnName": "objectGUID"
+ "columnName": "objectGUID",
+ "identifier": "ObjectGuid"
}
- ]
+ ],
+ "entityType": "Account"
}
]
}
@@ -3332,12 +6329,12 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.1.5",
+ "version": "3.3.0",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Microsoft Exchange Security - Exchange On-Premises",
"publisherDisplayName": "Community",
- "descriptionHtml": "
Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange On-Premises configuration and logs from a security lens to provide insights and alerts.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nData Connectors: 2, Parsers: 4, Workbooks: 4, Analytic Rules: 2, Watchlists: 2
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange On-Premises configuration and logs from a security lens to provide insights and alerts.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nData Connectors: 8, Parsers: 5, Workbooks: 4, Analytic Rules: 2, Watchlists: 2
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -3371,6 +6368,36 @@ "contentId": "[variables('_dataConnectorContentId2')]", "version": "[variables('dataConnectorVersion2')]" }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId3')]", + "version": "[variables('dataConnectorVersion3')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId4')]", + "version": "[variables('dataConnectorVersion4')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId5')]", + "version": "[variables('dataConnectorVersion5')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId6')]", + "version": "[variables('dataConnectorVersion6')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId7')]", + "version": "[variables('dataConnectorVersion7')]" + }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId8')]", + "version": "[variables('dataConnectorVersion8')]" + }, { "kind": "Parser", "contentId": "[variables('parserObject1').parserContentId1]", @@ -3391,6 +6418,11 @@ "contentId": "[variables('parserObject4').parserContentId4]", "version": "[variables('parserObject4').parserVersion4]" }, + { + "kind": "Parser", + "contentId": "[variables('parserObject5').parserContentId5]", + "version": "[variables('parserObject5').parserVersion5]" + }, { "kind": "Workbook", "contentId": "[variables('_workbookContentId1')]", @@ -3424,12 +6456,12 @@ { "kind": "Watchlist", "contentId": "[variables('_Exchange Services Monitoring')]", - "version": "3.1.5" + "version": "3.3.0" }, { "kind": "Watchlist", "contentId": "[variables('_Exchange VIP')]", - "version": "3.1.5" + "version": "3.3.0" } ] }, diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCompareDataOnPMRA.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCompareDataOnPMRA.yaml new file mode 100644 index 00000000000..33c7525d895 --- /dev/null +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCompareDataOnPMRA.yaml @@ -0,0 +1,183 @@ +id: 0a0f4ea0-6b94-4420-892e-41ca985f2f01 +Function: + Title: Parser for MRA Configuration Data Comparison On-Premises + Version: '1.0.0' + LastUpdated: '2024-08-30' +Category: Microsoft Sentinel Parser +FunctionName: MESCompareDataOnPMRA +FunctionAlias: MESCompareDataOnPMRA +FunctionParams: + - Name: SectionCompare + Type: string + Description: The Section to compare. Default value is "". + Default: '' + - Name: DateCompare + Type: string + Description: The date of the source comparison. Default value is "lastdate". + Default: 'lastdate' + - Name: CurrentDate + Type: string + Description: The date of the target comparison. Default value is "lastdate". + Default: 'lastdate' + - Name: EnvList + Type: string + Description: List of environments to compare. Default value is "All". + Default: 'All' + - Name: TypeEnv + Type: string + Description: Type of environment to compare. Default value is "Online". + Default: 'Online' + - Name: CurrentRole + Type: string + Description: A specific role to compare. Default value is "". + Default: '' + - Name: ExclusionsAcct + Type: dynamic + Description: List of actors to exclude. Default value is "dynamic('')". + Default: dynamic('') +FunctionQuery: | + // Version: 1.0.0 + // Last Updated: 30/08/2024 + // + // DESCRIPTION: + // This parser is used to compare the data of a specific section of the Exchange Online Configuration. It will compare the data of a specific section between two dates and return the differences between them. + // + // USAGE: + // Parameters : 7 parameters to add during creation. + // 1. SectionCompare, type string, default value "" + // 2. DateCompare, type string, default value "lastdate" + // 3. CurrentDate, type string, default value "lastdate" + // 4. EnvList, type string, default value "All" + // 5. TypeEnv, type string, default value "Online" + // 6. CurrentRole, type string, default value "" + // 7. ExclusionsAcct, type dynamic, default value dynamic("") + // + // Parameters simulation + // If you need to test the parser execution without saving it as a function, uncomment the bellow variable to simulate parameters values. + // + // let SectionCompare = "SampleEntry"; + // let EnvList = "All"; + // let TypeEnv = "Online"; + // let CurrentRole = ""; + // let ExclusionsAcct = dynamic(""); + // let DateCompare = "lastdate"; + // let CurrentDate = "lastdate"; + // + // Parameters definition + let _SectionCompare = SectionCompare; + let _EnvList =EnvList; + let _TypeEnv = TypeEnv; + let _CurrentRole =CurrentRole; + let _ExclusionsAcct = ExclusionsAcct; + let _DateCompare = DateCompare; + let _CurrentDate = CurrentDate; + let _DateCompareB = todatetime(DateCompare); + let _currD = (ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv) + | summarize TimeMax = max(TimeGenerated) + | extend TimeMax = tostring(split(TimeMax,"T")[0]) + | project TimeMax); + let _CurrentDateB = todatetime(toscalar(_currD)); + let BeforeData = + ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_DateCompare,SpecificConfigurationEnv=_EnvList,Target=_TypeEnv) + | where CmdletResultValue.Role contains _CurrentRole + and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct) + and CmdletResultValue.Name !contains "Deleg" + | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) + | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== "0" or CmdletResultValue.RoleAssigneeType== "2" , "User", CmdletResultValue.RoleAssigneeType== "10","Group","LinkedGroup") + | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name) + | extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name) + | 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") + | extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope=="0","None",CmdletResultValue.ConfigWriteScope=="7","CustomConfigScope",CmdletResultValue.ConfigWriteScope=="10","OrganizationConfig","NotApplicable") + | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name) + | extend Status= tostring(CmdletResultValue.Enabled) + | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6" or CmdletResultValue.RoleAssignmentDelegationType == "Delegating", "Delegating", "Regular") + | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) + | extend Role = tostring(CmdletResultValue.Role) + ; + let AfterData = + ExchangeConfiguration(SpecificSectionList=_SectionCompare,SpecificConfigurationDate=_CurrentDate,SpecificConfigurationEnv=_EnvList,Target = _TypeEnv) + | where CmdletResultValue.Role contains _CurrentRole + and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct) + and CmdletResultValue.Name !contains "Deleg" + | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) + | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== "0" or CmdletResultValue.RoleAssigneeType== "2" , "User", CmdletResultValue.RoleAssigneeType== "10","Group","LinkedGroup") + | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name) + | extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name) + | 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") + | extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope=="0","None",CmdletResultValue.ConfigWriteScope=="7","CustomConfigScope",CmdletResultValue.ConfigWriteScope=="10","OrganizationConfig","NotApplicable") + | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name) + | extend Status= tostring(CmdletResultValue.Enabled) + | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) + | extend Role = tostring(CmdletResultValue.Role) + | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6" or CmdletResultValue.RoleAssignmentDelegationType == "Delegating", "Delegating", "Regular") + ; + let i=0; + let allDataRange = + ESIExchangeConfig_CL + | where TimeGenerated between (_DateCompareB .. _CurrentDateB) + | where ESIEnvironment_s == _EnvList + | where Section_s == "MRA" + | extend CmdletResultValue = parse_json(rawData_s) + | project TimeGenerated,CmdletResultValue,WhenChanged = WhenChanged_t, WhenCreated=WhenCreated_t + | where CmdletResultValue.Role contains _CurrentRole + and CmdletResultValue.RoleAssigneeName !in (_ExclusionsAcct) + and CmdletResultValue.Name !contains "Deleg" + | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) + | extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== "0" or CmdletResultValue.RoleAssigneeType== "2" , "User", CmdletResultValue.RoleAssigneeType== "10","Group","LinkedGroup") + | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name) + | extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name) + | 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") + | extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope=="0","None",CmdletResultValue.ConfigWriteScope=="7","CustomConfigScope",CmdletResultValue.ConfigWriteScope=="10","OrganizationConfig","NotApplicable") + | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name) + | extend Status= tostring(CmdletResultValue.Enabled) + | extend Role = tostring(CmdletResultValue.Role) + | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6" or CmdletResultValue.RoleAssignmentDelegationType == "Delegating", "Delegating", "Regular") + ; + let DiffAddDataP1 = allDataRange + | join kind = rightanti (AfterData | where WhenCreated >=_DateCompareB) on WhenCreated + ; + let DiffAddDataP2 = allDataRange + | join kind = innerunique (allDataRange ) on WhenCreated + | where WhenCreated >=_DateCompareB + | where bin(WhenCreated,5m)==bin(WhenChanged,5m) + | distinct ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated + ; + let DiffAddData = union DiffAddDataP1,DiffAddDataP2 + | extend Actiontype ="Add"; + let DiffRemoveData = allDataRange + | join kind = leftanti AfterData on RoleAssigneeName + | extend Actiontype ="Remove" + | distinct Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated + | project WhenChanged=_CurrentDateB,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,RoleAssigneeType,CustomConfigWriteScope,RecipientWriteScope,ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated + ; + let DiffModifData = union AfterData,allDataRange + | sort by ManagementRoleAssignement,WhenChanged asc + | extend Status = iff( ManagementRoleAssignement == prev(ManagementRoleAssignement) and Status != prev(Status) and prev(Status) !="" , strcat("📍 ", Status, " (",prev(Status),"->", Status," )"),Status) + | extend CustomRecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomRecipientWriteScope != prev(CustomRecipientWriteScope) and prev(CustomRecipientWriteScope) !="" , strcat("📍 ", CustomRecipientWriteScope, " (", prev(CustomRecipientWriteScope),"->", CustomRecipientWriteScope, ")"),CustomRecipientWriteScope) + | extend CustomConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and CustomConfigWriteScope != prev(CustomConfigWriteScope) and prev(CustomConfigWriteScope) !="" , strcat("📍 ", CustomConfigWriteScope, " (", prev(CustomConfigWriteScope),"->", CustomConfigWriteScope, ")"),CustomConfigWriteScope) + | extend RecipientWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and RecipientWriteScope != prev(RecipientWriteScope) and prev(RecipientWriteScope) !="" , strcat("📍 ", RecipientWriteScope, " (", prev(RecipientWriteScope),"->", RecipientWriteScope, ")"),RecipientWriteScope) + | extend ConfigWriteScope = iff(ManagementRoleAssignement == prev(ManagementRoleAssignement) and ConfigWriteScope != prev(ConfigWriteScope) and prev(ConfigWriteScope) !="" , strcat("📍 ", ConfigWriteScope, " (", prev(ConfigWriteScope),"->", ConfigWriteScope, ")"),ConfigWriteScope) + | extend ActiontypeR =iff((Status contains "📍" or CustomRecipientWriteScope contains"📍" or CustomConfigWriteScope contains"📍" or RecipientWriteScope contains"📍" or ConfigWriteScope contains"📍" ), i=i + 1, i) + | extend Actiontype =iff(ActiontypeR > 0, "Modif", "NO") + | where ActiontypeR == 1 + | project WhenChanged,Actiontype,ManagementRoleAssignement,RoleAssigneeName, Status,CustomRecipientWriteScope,CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope,RoleAssignmentDelegationType,WhenCreated + ; + union DiffAddData, DiffRemoveData, DiffModifData + | extend RoleAssigneeName = iff(RoleAssigneeType == "User", strcat("🧑🦰 ", RoleAssigneeName), strcat("👪 ", RoleAssigneeName)) + | extend WhenChanged = iff (Actiontype == "Modif", WhenChanged, iff(Actiontype == "Add",WhenCreated, WhenChanged)) + //| extend WhenChanged = case(Actiontype == "Modif" , tostring(bin(WhenChanged,1m)), Actiontype == "Add",tostring(bin(WhenChanged,1m)),Actiontype == "Remove","NoInformation","N/A") + | extend Actiontype = case(Actiontype == "Add", strcat("➕ ", Actiontype), Actiontype == "Remove", strcat("➖ ", Actiontype), Actiontype == "Modif", strcat("📍 ", Actiontype), "N/A") + | sort by WhenChanged desc + | project + WhenChanged, + Actiontype, + RoleAssigneeName, + RoleAssigneeType, + Status, + CustomRecipientWriteScope, + CustomConfigWriteScope, + RecipientWriteScope, + ConfigWriteScope, + ManagementRoleAssignement, + RoleAssignmentDelegationType, + WhenCreated \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md index 56b98e50e99..d3e7780a041 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md @@ -28,6 +28,10 @@ Parsers are created [using functions in Azure monitor log queries](https://docs. - [Parser Description](#parser-description-3) - [Parser dependency](#parser-dependency-1) - [Parser Setup](#parser-setup-3) + - [Microsoft Exchange Compare Data MRA Parser for On-Premises](#microsoft-exchange-compare-data-mra-parser-for-on-premises) + - [Parser Definition](#parser-definition-4) + - [Parser Description](#parser-description-4) + - [Parser Setup](#parser-setup-4) ## ExchangeConfiguration Parser @@ -184,3 +188,39 @@ This parser is linked to "ExchangeVIP" whatchlist >1 parameter to add during creation : UserToCheck, type string, No default value 1. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries + +## Microsoft Exchange Compare Data MRA Parser for On-Premises + +### Parser Definition + +- Title: Microsoft Exchange Compare Data MRA Parser for On-Premises +- Version: 1.0.0 +- Last Updated: 30/08/2024 +- Description: This parser compare data from MRA and ESI Exchange Collector to find differences + +|**Version** |**Details** | +|---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.0 |Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange Online configuration and logs from a security lens to provide insights and alerts.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nData Connectors: 1, Parsers: 6, Workbooks: 4, Watchlists: 1
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "descriptionHtml": "Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Exchange Security Audit and Configuration Insight solution analyze Exchange Online configuration and logs from a security lens to provide insights and alerts.
\nUnderlying Microsoft Technologies used:
\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:
\n\nData Connectors: 1, Parsers: 5, Workbooks: 4, Watchlists: 1
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -1945,11 +1808,6 @@ "contentId": "[variables('parserObject5').parserContentId5]", "version": "[variables('parserObject5').parserVersion5]" }, - { - "kind": "Parser", - "contentId": "[variables('parserObject6').parserContentId6]", - "version": "[variables('parserObject6').parserVersion6]" - }, { "kind": "Workbook", "contentId": "[variables('_workbookContentId1')]", @@ -1973,7 +1831,7 @@ { "kind": "Watchlist", "contentId": "[variables('_Exchange Online VIP')]", - "version": "3.1.5" + "version": "3.1.6" } ] }, diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Package/testParameters.json b/Solutions/Microsoft Exchange Security - Exchange Online/Package/testParameters.json index 39020c8111b..a1e9f9bdb6e 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Package/testParameters.json +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Package/testParameters.json @@ -39,7 +39,7 @@ }, "workbook3-name": { "type": "string", - "defaultValue": "Microsoft Exchange Online Admin Activity", + "defaultValue": "Microsoft Exchange Admin Activity - Online", "minLength": 1, "metadata": { "description": "Name for the workbook" diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml deleted file mode 100644 index f242d0c9b16..00000000000 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml +++ /dev/null @@ -1,29 +0,0 @@ -id: 9f0e2122-f511-4e51-83a0-51fbd86d3121 -Function: - Title: Parser for VIP Check for Exchange - Version: '1.0.0' - LastUpdated: '2023-11-01' -Category: Microsoft Sentinel Parser -FunctionName: MESCheckVIP -FunctionAlias: MESCheckVIP -FunctionParams: - - Name: UserToCheck - Type: string - Description: The user to verifiy if is a VIP or not. Default value is "all". - Default: 'All' -FunctionQuery: | - //let UserToCheck = "SampleEntry"; - let _UserToCheck = iif(UserToCheck == "" or UserToCheck == "All","All",tolower(UserToCheck)); - let fuzzyWatchlist = datatable(displayName:string, userPrincipalName:string, sAMAccountName:string, objectSID:string, objectGUID:guid, canonicalName:string, comment:string) [ - "NONE","NONE","NONE","NONE","00000001-0000-1000-0000-100000000000","NONE","NONE"]; - let Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != "00000001-0000-1000-0000-100000000000" | project-away TableName; - let SearchUser = Watchlist | where _UserToCheck =~ canonicalName - or _UserToCheck =~ displayName - or _UserToCheck =~ userPrincipalName - or _UserToCheck =~ sAMAccountName - or _UserToCheck =~ objectSID - or _UserToCheck == tostring(objectGUID) - or _UserToCheck =~ distinguishedName - or _UserToCheck == "All" - | extend ValueChecked = iif(_UserToCheck=="All",strcat("#",displayName,"#",userPrincipalName,"#",sAMAccountName,"#",objectGUID,"#",objectSID,"#",distinguishedName,"#"),_UserToCheck); - SearchUser \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCompareDataMRA.yaml b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCompareDataMRA.yaml index 8f5b3cd4e4c..7aded9f868b 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCompareDataMRA.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCompareDataMRA.yaml @@ -1,8 +1,8 @@ id: 39f51672-8c63-4600-882a-5db8275f798f Function: Title: Parser for MRA Configuration Data Comparison - Version: '1.0.0' - LastUpdated: '2024-02-25' + Version: '1.1.0' + LastUpdated: '2024-08-30' Category: Microsoft Sentinel Parser FunctionName: MESCompareDataMRA FunctionAlias: MESCompareDataMRA @@ -36,8 +36,8 @@ FunctionParams: Description: List of actors to exclude. Default value is "dynamic('')". Default: dynamic('') FunctionQuery: | - // Version: 1.0.0 - // Last Updated: 25/02/2024 + // Version: 1.1.0 + // Last Updated: 30/08/2024 // // DESCRIPTION: // This parser is used to compare the data of a specific section of the Exchange Online Configuration. It will compare the data of a specific section between two dates and return the differences between them. @@ -84,14 +84,14 @@ FunctionQuery: | and CmdletResultValue.Name !contains "Deleg" | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) | extend RoleAssigneeType = iff(CmdletResultValue.RoleAssigneeType == "User", "User", "RoleGroup") - | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope) - | extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope) + | extend CustomRecipientWriteScope = iff (_TypeEnv=="On-Premises", tostring(CmdletResultValue.CustomRecipientWriteScope.Name), tostring(CmdletResultValue.CustomRecipientWriteScope)) + | extend CustomConfigWriteScope = iff (_TypeEnv=="On-Premises", tostring(CmdletResultValue.CustomConfigWriteScope.Name), tostring(CmdletResultValue.CustomConfigWriteScope)) | extend CustomResourceScope = tostring(CmdletResultValue.CustomResourceScope) | extend RecipientWriteScope = tostring(CmdletResultValue.RecipientWriteScope) | extend ConfigWriteScope = tostring(CmdletResultValue.ConfigWriteScope) | extend ManagementRoleAssignement = tostring(CmdletResultValue.Name) | extend Status= tostring(CmdletResultValue.Enabled) - | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6", "Delegating", "Regular") + | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6" or CmdletResultValue.RoleAssignmentDelegationType == "Delegating", "Delegating", "Regular") | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) | extend Role = tostring(CmdletResultValue.Role) | extend RoleAssignmentDelegationType = tostring(CmdletResultValue.RoleAssignmentDelegationType) @@ -103,8 +103,8 @@ FunctionQuery: | and CmdletResultValue.Name !contains "Deleg" | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) | extend RoleAssigneeType = iff(CmdletResultValue.RoleAssigneeType == "User", "User", "RoleGroup") - | extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope) - | extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope) + | extend CustomRecipientWriteScope = iff (_TypeEnv=="On-Premises", tostring(CmdletResultValue.CustomRecipientWriteScope.Name), tostring(CmdletResultValue.CustomRecipientWriteScope.Name)) + | extend CustomConfigWriteScope = iff (_TypeEnv=="On-Premises", tostring(CmdletResultValue.CustomConfigWriteScope.Name), tostring(CmdletResultValue.CustomConfigWriteScope)) | extend CustomResourceScope = tostring(CmdletResultValue.CustomResourceScope) | extend RecipientWriteScope = tostring(CmdletResultValue.RecipientWriteScope) | extend ConfigWriteScope = tostring(CmdletResultValue.ConfigWriteScope) @@ -112,6 +112,7 @@ FunctionQuery: | | extend Status= tostring(CmdletResultValue.Enabled) | extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName) | extend Role = tostring(CmdletResultValue.Role) + | extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType == "6" or CmdletResultValue.RoleAssignmentDelegationType == "Delegating", "Delegating", "Regular") | extend RoleAssignmentDelegationType = tostring(CmdletResultValue.RoleAssignmentDelegationType) ; let i=0; diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md index 46169e80260..fa0469c1ecf 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md @@ -164,12 +164,13 @@ If you need to test the parser execution without saving it as a function, add th ### Parser Definition - Title: Microsoft Exchange Compare Data MRA Parser -- Version: 1.0.0 -- Last Updated: 25/02/2024 +- Version: 1.1.0 +- Last Updated: 30/08/2024 - Description: This parser compare data from MRA and ESI Exchange Collector to find differences |**Version** |**Details** | |---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.1 |