diff --git a/.script/tests/KqlvalidationsTests/CustomFunctions/ExchangeAdminAuditLogs.json b/.script/tests/KqlvalidationsTests/CustomFunctions/ExchangeAdminAuditLogs.json
index c4504345dc8..12f86d866ee 100644
--- a/.script/tests/KqlvalidationsTests/CustomFunctions/ExchangeAdminAuditLogs.json
+++ b/.script/tests/KqlvalidationsTests/CustomFunctions/ExchangeAdminAuditLogs.json
@@ -24,7 +24,7 @@
},
{
"Name": "IsVIP",
- "Type": "String"
+ "Type": "bool"
},
{
"Name": "CmdletName",
@@ -38,10 +38,18 @@
"Name": "IsSensitiveCmdlet",
"Type": "bool"
},
+ {
+ "Name": "IsRestrictedCmdLet",
+ "Type": "bool"
+ },
{
"Name": "IsRestrictedParameters",
"Type": "bool"
},
+ {
+ "Name": "IsSenstiveCmdletParameters",
+ "Type": "bool"
+ },
{
"Name": "ExtractedParameters",
"Type": "dynamic"
diff --git a/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json b/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
index 61b5a6c2a2c..2f8e0b60533 100644
--- a/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
+++ b/.script/tests/KqlvalidationsTests/SkipValidationsTemplates.json
@@ -3183,6 +3183,11 @@
"templateName": "CrowdStrikeReplicatorV2.yaml",
"validationFailReason": "Temporarily Added for Parser KQL Queries validation"
},
+ {
+ "id": "9f0e2122-f511-4e51-83a0-51fbd86d3121",
+ "templateName": "MESCheckVIP.yaml",
+ "validationFailReason": "Temporarily Added for Parser KQL Queries validation"
+ },
{
"id": "600db9e0-1c11-4295-a88a-071c79434926",
"templateName": "AccountElevatedtoNewRole.yaml",
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml
index 5224517bfea..72ad7fbf312 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/CriticalCmdletsUsageDetection.yaml
@@ -6,7 +6,7 @@ requiredDataConnectors:
- connectorId: ESI-ExchangeAdminAuditLogEvents
dataTypes:
- Event
-severity: Low
+severity: Medium
queryFrequency: 30m
queryPeriod: 1h
triggerOperator: gt
@@ -21,11 +21,11 @@ relevantTechniques:
- T1098
- T1114
query: |
+ let VIPRestriction = "on";
ExchangeAdminAuditLogs
- | where ingestion_time() > ago(30m)
- | where IsSensitive == true
- | where UserOriented =~ 'Yes'
- | where IsVIP == true
+ | where IsVIP or VIPRestriction =~ "off"
+ | where UserOriented =~ 'Yes' and IsSensitive and ((IsRestrictedCmdLet and IsSenstiveCmdletParameters) or IsRestrictedCmdLet == false)
+ | extend Level = iif (Status == "Failure", "Medium", "High")
entityMappings:
- entityType: Mailbox
fieldMappings:
@@ -47,5 +47,9 @@ entityMappings:
fieldMappings:
- identifier: Name
columnName: Caller
-version: 1.0.1
+alertDetailsOverride:
+ alertDisplayNameFormat: "{{CmdletName}} executed on {{TargetObject}}"
+ alertDescriptionFormat: "Alert from Microsoft Exchange Security as {{CmdletName}} with parameters {{CmdletParameters}} was executed on {{TargetObject}}"
+ alertSeverityColumnName: Level
+version: 1.2.0
kind: Scheduled
\ No newline at end of file
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml
index 7f3c3b972df..2d2b9c8e2cc 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml
@@ -37,7 +37,6 @@ query: |
ExchangeAdminAuditLogs
| where TimeGenerated > ago(timeframe)
| where UserOriented =~ 'Yes'
- | lookup kind=leftouter _GetWatchlist('ExchangeVIP') on $left.TargetObject == $right.canonicalName
| project userExecutedTime = TimeGenerated,
UserCmdlet = CmdletName,
UserCmdletParams = CmdletParameters,
@@ -73,6 +72,6 @@ entityMappings:
- identifier: Name
columnName: Caller
- identifier: ObjectGuid
- columnName: TargetObject
-version: 1.0.1
+ columnName: objectGUID
+version: 1.2.0
kind: Scheduled
\ No newline at end of file
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 fb823d35ec2..1a4755d2f8a 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
@@ -183,23 +183,45 @@
"instructionSteps": [
{
"title": "Data Collection Rules - When Azure Monitor Agent is used",
- "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.\n>1. Choose 'Custom' type and Enter 'MS Exchange Management' as expression and Add it",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "type": "AdminAuditEvents"
- },
{
"parameters": {
- "linkType": "OpenCreateDataCollectionRule",
- "dataCollectionRuleType": 5
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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 'MS Exchange 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": "InstallAgent"
+ "type": "InstructionStepsGroup"
}
]
},
{
"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 advanced settings **Configuration**, select **Data** and then **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 **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -255,21 +277,12 @@
"title": "Data Collection Rules - When Azure Monitor Agent is used",
"description": "**Enable data collection rule**\n> Application and System Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "parameters": {
- "fillWith": [
- "WorkspaceId"
- ],
- "label": "Workspace ID"
- },
- "type": "CopyableLabel"
- },
{
"parameters": {
"instructionSteps": [
{
"title": "Option 1 - Azure Resource Manager (ARM) Template",
- "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ESI-DCROption2-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."
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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",
@@ -281,20 +294,16 @@
{
"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**."
- },
- {
- "title": "B. Select Application Event log and System Event log",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
- },
- {
- "title": "C. Assign the DCR to all Exchange Servers",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
}
]
},
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -434,6 +443,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -532,6 +545,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -630,6 +647,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -664,7 +685,7 @@
],
"metadata": {
"id": "5738bef7-b6c0-4fec-ba0b-ac728bef83a9",
- "version": "2.0.0",
+ "version": "2.1.0",
"kind": "dataConnector",
"source": {
"kind": "solution",
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 c10a4038781..41c788a9ca6 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
@@ -66,7 +66,7 @@
},
"instructionSteps": [
{
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)",
+ "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": [
{
@@ -105,15 +105,15 @@
"instructionSteps": [
{
"title": "Download the latest version of ESI Collector",
- "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script"
+ "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script. The file to download is CollectExchSecIns.zip"
},
{
"title": "Copy the script folder",
"description": "Unzip the content and copy the script folder on a server where Exchange PowerShell Cmdlets are present."
},
{
- "title": "Unlock the PS1 Scripts",
- "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as locked, unlock it."
+ "title": "Unblock the PS1 Scripts",
+ "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as blocked, unblock it. You can also use the Cmdlet 'Unblock-File *.* in the unzipped folder using PowerShell."
},
{
"title": "Configure Network Access ",
@@ -127,7 +127,7 @@
},
{
"title": "2. Configure the ESI Collector Script",
- "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty.",
+ "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty. By default, choose 'Def' as Default analysis. The other choices are for specific usage.",
"instructions": [
{
"parameters": {
@@ -151,12 +151,12 @@
},
{
"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 the be Exchange Organization Administrator"
+ "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"
}
],
"metadata": {
"id": "ed950fd7-e457-4a59-88f0-b9c949aa280d",
- "version": "1.1.0",
+ "version": "1.2.0",
"kind": "dataConnector",
"source": {
"kind": "solution",
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option1MSExchangeAuditLogs.json b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option1MSExchangeAuditLogs.json
new file mode 100644
index 00000000000..05dfdbb655e
--- /dev/null
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Data Connectors/azuredeploy_ESI_DCR_Option1MSExchangeAuditLogs.json
@@ -0,0 +1,73 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "dcrName": {
+ "type": "string",
+ "defaultValue": "DCR-Option1-MSExchangeAuditLogs",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name of the data collection rule"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Location for data collection rule"
+ }
+ },
+ "workspacename": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "The log analitycs workspace name"
+ }
+ }
+ },
+ "variables": {
+ "workspaceResourceId": "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',resourceGroup().name,'/providers/Microsoft.operationalinsights/workspaces/',parameters('workspacename'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/dataCollectionRules",
+ "apiVersion": "2021-09-01-preview",
+ "name": "[parameters('dcrName')]",
+ "location": "[parameters('location')]",
+ "kind": "Windows",
+ "properties": {
+ "dataSources": {
+ "windowsEventLogs": [
+ {
+ "streams": [
+ "Microsoft-Event"
+ ],
+ "xPathQueries": [
+ "\\MSExchange Management!*"
+ ],
+ "name": "eventLogsDataSource"
+ }
+ ]
+ },
+ "destinations": {
+ "logAnalytics": [
+ {
+ "workspaceResourceId": "[variables('workspaceResourceId')]",
+ "name": "la-data-destination"
+ }
+ ]
+ },
+ "dataFlows": [
+ {
+ "streams": [
+ "Microsoft-Event"
+ ],
+ "destinations": [
+ "la-data-destination"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
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 01d2863a010..3ea0979947c 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
@@ -10,7 +10,8 @@
"Parsers": [
"Parsers/ExchangeAdminAuditLogs.yaml",
"Parsers/ExchangeConfiguration.yaml",
- "Parsers/ExchangeEnvironmentList.yaml"
+ "Parsers/ExchangeEnvironmentList.yaml",
+ "Parsers/MESCheckVIP.yaml"
],
"Workbooks": [
"Workbooks/Microsoft Exchange Least Privilege with RBAC.json",
@@ -22,8 +23,13 @@
"Analytic Rules/CriticalCmdletsUsageDetection.yaml",
"Analytic Rules/ServerOrientedWithUserOrientedAdministration.yaml"
],
+ "Watchlists": [
+ "Watchlists/ExchangeServicesMonitoring.json",
+ "Watchlists/ExchangeVIP.json"
+ ],
+ "WatchlistDescription": ["List of important Exchange Windows Services that should be monitored","ExchangeVIP Watchlist contains a list of VIP users that are allowed to perform privileged operations on Exchange Servers. This watchlist is used by the ServerOrientedWithUserOrientedAdministration rule to detect suspicious activity by VIP users."],
"BasePath": "C:\\Git Repositories\\Azure-Sentinel\\Solutions\\Microsoft Exchange Security - Exchange On-Premises\\",
- "Version": "3.0.0",
+ "Version": "3.1.0",
"Metadata": "SolutionMetadata.json",
"TemplateSpec": true,
"Is1Pconnector": false
diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.1.0.zip b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.1.0.zip
new file mode 100644
index 00000000000..a3f45e48e77
Binary files /dev/null and b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/3.1.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 b11cfbb2982..980c54ecb04 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: \r \n • Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/ReleaseNotes.md)\r \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:** 3, **Workbooks:** 4, **Analytic Rules:** 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: \r \n • Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Exchange%20Security%20-%20Exchange%20On-Premises/ReleaseNotes.md)\r \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)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@@ -107,7 +107,7 @@
"name": "dataconnectors-parser-text",
"type": "Microsoft.Common.TextBlock",
"options": {
- "text": "The solution installs three (3) parsers that transform ingested data. The transformed logs can be accessed using the ExchangeConfiguration, ExchangeAdminAuditLogs and ExchangeEnvironmentList Kusto Function aliases."
+ "text": "The solution installs three (4) parsers that transform ingested data. The transformed logs can be accessed using the ExchangeConfiguration, ExchangeAdminAuditLogs, MESCheckVIP and ExchangeEnvironmentList Kusto Function aliases."
}
}
]
@@ -263,6 +263,56 @@
]
}
]
+ },
+ {
+ "name": "watchlists",
+ "label": "Watchlists",
+ "subLabel": {
+ "preValidation": "Configure the watchlists",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Watchlists",
+ "elements": [
+ {
+ "name": "watchlists-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "Microsoft Sentinel watchlists enable the collection of data from external data sources for correlation with the events in your Microsoft Sentinel environment. Once created, you can use watchlists in your search, detection rules, threat hunting, and response playbooks. Watchlists are stored in your Microsoft Sentinel workspace as name-value pairs and are cached for optimal query performance and low latency. Once deployment is successful, the installed watchlists will be available in the Watchlists blade under 'My Watchlists'.",
+ "link": {
+ "label": "Learn more",
+ "uri": "https://aka.ms/sentinelwatchlists"
+ }
+ }
+ },
+ {
+ "name": "watchlist1",
+ "type": "Microsoft.Common.Section",
+ "label": "Exchange Services Monitoring",
+ "elements": [
+ {
+ "name": "watchlist1-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "List of important Exchange Windows Services that should be monitored"
+ }
+ }
+ ]
+ },
+ {
+ "name": "watchlist2",
+ "type": "Microsoft.Common.Section",
+ "label": "Exchange VIP",
+ "elements": [
+ {
+ "name": "watchlist2-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "ExchangeVIP Watchlist contains a list of VIP users that are allowed to perform privileged operations on Exchange Servers. This watchlist is used by the ServerOrientedWithUserOrientedAdministration rule to detect suspicious activity by VIP users."
+ }
+ }
+ ]
+ }
+ ]
}
],
"outputs": {
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 fad4a49c3df..1025d19c143 100644
--- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json
+++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Package/mainTemplate.json
@@ -59,13 +59,29 @@
"metadata": {
"description": "Name for the workbook"
}
+ },
+ "watchlist1-id": {
+ "type": "string",
+ "defaultValue": "ExchangeServicesMonitoring",
+ "minLength": 1,
+ "metadata": {
+ "description": "Unique id for the watchlist"
+ }
+ },
+ "watchlist2-id": {
+ "type": "string",
+ "defaultValue": "ExchangeVIP",
+ "minLength": 1,
+ "metadata": {
+ "description": "Unique id for the watchlist"
+ }
}
},
"variables": {
"email": "support@microsoft.com",
"_email": "[variables('email')]",
"_solutionName": "Microsoft Exchange Security - Exchange On-Premises",
- "_solutionVersion": "3.0.1",
+ "_solutionVersion": "3.1.0",
"solutionId": "microsoftsentinelcommunity.azure-sentinel-solution-exchangesecurityinsights",
"_solutionId": "[variables('solutionId')]",
"uiConfigId1": "ESI-ExchangeAdminAuditLogEvents",
@@ -75,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.0.0",
+ "dataConnectorVersion1": "2.1.0",
"_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]",
"uiConfigId2": "ESI-ExchangeOnPremisesCollector",
"_uiConfigId2": "[variables('uiConfigId2')]",
@@ -84,14 +100,14 @@
"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.1.0",
+ "dataConnectorVersion2": "1.2.0",
"_dataConnectorcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId2'),'-', variables('dataConnectorVersion2'))))]",
"parserName1": "ExchangeAdminAuditLogs",
"_parserName1": "[concat(parameters('workspace'),'/',variables('parserName1'))]",
"parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
"_parserId1": "[variables('parserId1')]",
"parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId1'))))]",
- "parserVersion1": "1.0.0",
+ "parserVersion1": "1.3.0",
"parserContentId1": "ExchangeAdminAuditLogs-Parser",
"_parserContentId1": "[variables('parserContentId1')]",
"_parsercontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId1'),'-', variables('parserVersion1'))))]",
@@ -113,6 +129,15 @@
"parserContentId3": "ExchangeEnvironmentList-Parser",
"_parserContentId3": "[variables('parserContentId3')]",
"_parsercontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId3'),'-', variables('parserVersion3'))))]",
+ "parserName4": "MESCheckVIP",
+ "_parserName4": "[concat(parameters('workspace'),'/',variables('parserName4'))]",
+ "parserId4": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName4'))]",
+ "_parserId4": "[variables('parserId4')]",
+ "parserTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring(variables('_parserContentId4'))))]",
+ "parserVersion4": "1.0.0",
+ "parserContentId4": "MESCheckVIP-Parser",
+ "_parserContentId4": "[variables('parserContentId4')]",
+ "_parsercontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('_parserContentId4'),'-', variables('parserVersion4'))))]",
"workbookVersion1": "1.0.1",
"workbookContentId1": "MicrosoftExchangeLeastPrivilegewithRBAC",
"workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
@@ -138,18 +163,22 @@
"workbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId4'))))]",
"_workbookContentId4": "[variables('workbookContentId4')]",
"_workbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId4'),'-', variables('workbookVersion4'))))]",
- "analyticRuleVersion1": "1.0.1",
+ "analyticRuleVersion1": "1.2.0",
"analyticRulecontentId1": "5170c3c4-b8c9-485c-910d-a21d965ee181",
"_analyticRulecontentId1": "[variables('analyticRulecontentId1')]",
"analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]",
"analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1'))))]",
"_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId1'),'-', variables('analyticRuleVersion1'))))]",
- "analyticRuleVersion2": "1.0.1",
+ "analyticRuleVersion2": "1.2.0",
"analyticRulecontentId2": "7bce901b-9bc8-4948-8dfc-8f68878092d5",
"_analyticRulecontentId2": "[variables('analyticRulecontentId2')]",
"analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]",
"analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2'))))]",
"_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId2'),'-', variables('analyticRuleVersion2'))))]",
+ "Exchange Services Monitoring": "Exchange Services Monitoring",
+ "_Exchange Services Monitoring": "[variables('Exchange Services Monitoring')]",
+ "Exchange VIP": "Exchange VIP",
+ "_Exchange VIP": "[variables('Exchange VIP')]",
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
@@ -162,7 +191,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.0.1",
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion1')]",
@@ -360,23 +389,45 @@
"instructionSteps": [
{
"title": "Data Collection Rules - When Azure Monitor Agent is used",
- "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.\n>1. Choose 'Custom' type and Enter 'MS Exchange Management' as expression and Add it",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "type": "AdminAuditEvents"
- },
{
"parameters": {
- "linkType": "OpenCreateDataCollectionRule",
- "dataCollectionRuleType": 5
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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 'MS Exchange 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": "InstallAgent"
+ "type": "InstructionStepsGroup"
}
]
},
{
"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 advanced settings **Configuration**, select **Data** and then **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 **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -432,21 +483,12 @@
"title": "Data Collection Rules - When Azure Monitor Agent is used",
"description": "**Enable data collection rule**\n> Application and System Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "parameters": {
- "fillWith": [
- "WorkspaceId"
- ],
- "label": "Workspace ID"
- },
- "type": "CopyableLabel"
- },
{
"parameters": {
"instructionSteps": [
{
"title": "Option 1 - Azure Resource Manager (ARM) Template",
- "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ESI-DCROption2-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."
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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",
@@ -458,20 +500,16 @@
{
"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**."
- },
- {
- "title": "B. Select Application Event log and System Event log",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
- },
- {
- "title": "C. Assign the DCR to all Exchange Servers",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
}
]
},
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -611,6 +649,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -709,6 +751,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -807,6 +853,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -842,7 +892,7 @@
],
"metadata": {
"id": "5738bef7-b6c0-4fec-ba0b-ac728bef83a9",
- "version": "2.0.0",
+ "version": "2.1.0",
"kind": "dataConnector",
"source": {
"kind": "solution",
@@ -1119,23 +1169,45 @@
"instructionSteps": [
{
"title": "Data Collection Rules - When Azure Monitor Agent is used",
- "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.\n>1. Choose 'Custom' type and Enter 'MS Exchange Management' as expression and Add it",
+ "description": "**Enable data collection rule**\n> Microsoft Exchange Admin Audit Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "type": "AdminAuditEvents"
- },
{
"parameters": {
- "linkType": "OpenCreateDataCollectionRule",
- "dataCollectionRuleType": 5
+ "instructionSteps": [
+ {
+ "title": "Option 1 - Azure Resource Manager (ARM) Template",
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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 'MS Exchange 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": "InstallAgent"
+ "type": "InstructionStepsGroup"
}
]
},
{
"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 advanced settings **Configuration**, select **Data** and then **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 **MS Exchange Management** as log name.\n3. Collect Error, Warning and Information types\n4. Click **Save**.",
"instructions": [
{
"parameters": {
@@ -1191,21 +1263,12 @@
"title": "Data Collection Rules - When Azure Monitor Agent is used",
"description": "**Enable data collection rule**\n> Application and System Events logs are collected only from **Windows** agents.",
"instructions": [
- {
- "parameters": {
- "fillWith": [
- "WorkspaceId"
- ],
- "label": "Workspace ID"
- },
- "type": "CopyableLabel"
- },
{
"parameters": {
"instructionSteps": [
{
"title": "Option 1 - Azure Resource Manager (ARM) Template",
- "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-ESI-DCROption2-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."
+ "description": "Use this method for automated deployment of the DCR.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](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",
@@ -1217,20 +1280,16 @@
{
"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**."
- },
- {
- "title": "B. Select Application Event log and System Event log",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
- },
- {
- "title": "C. Assign the DCR to all Exchange Servers",
- "description": "1. On the Automation Account page, select **Modules**.\n2. Click on **Browse gallery** and search the **ExchangeOnlineManagement** module.\n3. Select it and click on **Select**.\n4. Choose Version **5.1** on Runtime version field and click on Import button.\nRepeat the step for the following modules : 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users' and 'Microsoft.Graph.Groups. **Attention, you need to wait for Microsoft.Graph.Authentication installation before processing next modules**"
}
]
},
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -1370,6 +1429,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -1468,6 +1531,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -1566,6 +1633,10 @@
"type": "InstructionStepsGroup"
}
]
+ },
+ {
+ "title": "Assign the DCR to all Exchange Servers",
+ "description": "Add all your Exchange Servers to the DCR"
}
]
},
@@ -1612,7 +1683,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.0.1",
+ "description": "Microsoft Exchange Security - Exchange On-Premises data connector with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('dataConnectorVersion2')]",
@@ -1721,7 +1792,7 @@
"type": "InstructionStepsGroup"
}
],
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)"
+ "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 ",
@@ -1732,15 +1803,15 @@
"instructionSteps": [
{
"title": "Download the latest version of ESI Collector",
- "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script"
+ "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script. The file to download is CollectExchSecIns.zip"
},
{
"title": "Copy the script folder",
"description": "Unzip the content and copy the script folder on a server where Exchange PowerShell Cmdlets are present."
},
{
- "title": "Unlock the PS1 Scripts",
- "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as locked, unlock it."
+ "title": "Unblock the PS1 Scripts",
+ "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as blocked, unblock it. You can also use the Cmdlet 'Unblock-File *.* in the unzipped folder using PowerShell."
},
{
"title": "Configure Network Access ",
@@ -1754,7 +1825,7 @@
"title": "1. Install the ESI Collector Script on a server with Exchange Admin PowerShell console"
},
{
- "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty.",
+ "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty. By default, choose 'Def' as Default analysis. The other choices are for specific usage.",
"instructions": [
{
"parameters": {
@@ -1778,13 +1849,13 @@
"title": "2. Configure the ESI Collector Script"
},
{
- "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 the be Exchange Organization Administrator",
+ "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)"
}
],
"metadata": {
"id": "ed950fd7-e457-4a59-88f0-b9c949aa280d",
- "version": "1.1.0",
+ "version": "1.2.0",
"kind": "dataConnector",
"source": {
"kind": "solution",
@@ -1972,7 +2043,7 @@
"type": "InstructionStepsGroup"
}
],
- "title": "Parser deployment (When using Microsoft Exchange Security Solution, Parsers are automatically deployed)"
+ "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 ",
@@ -1983,15 +2054,15 @@
"instructionSteps": [
{
"title": "Download the latest version of ESI Collector",
- "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script"
+ "description": "The latest version can be found here : https://aka.ms/ESI-ExchangeCollector-Script. The file to download is CollectExchSecIns.zip"
},
{
"title": "Copy the script folder",
"description": "Unzip the content and copy the script folder on a server where Exchange PowerShell Cmdlets are present."
},
{
- "title": "Unlock the PS1 Scripts",
- "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as locked, unlock it."
+ "title": "Unblock the PS1 Scripts",
+ "description": "Click right on each PS1 Script and go to Properties tab.\n If the script is marked as blocked, unblock it. You can also use the Cmdlet 'Unblock-File *.* in the unzipped folder using PowerShell."
},
{
"title": "Configure Network Access ",
@@ -2005,7 +2076,7 @@
"title": "1. Install the ESI Collector Script on a server with Exchange Admin PowerShell console"
},
{
- "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty.",
+ "description": "Be sure to be local administrator of the server.\nIn 'Run as Administrator' mode, launch the 'setup.ps1' script to configure the collector.\n Fill the Log Analytics (Microsoft Sentinel) Workspace information.\n Fill the Environment name or leave empty. By default, choose 'Def' as Default analysis. The other choices are for specific usage.",
"instructions": [
{
"parameters": {
@@ -2029,7 +2100,7 @@
"title": "2. Configure the ESI Collector Script"
},
{
- "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 the be Exchange Organization Administrator",
+ "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)"
}
],
@@ -2046,7 +2117,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeAdminAuditLogs Data Parser with template version 3.0.1",
+ "description": "ExchangeAdminAuditLogs Data Parser with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserVersion1')]",
@@ -2063,7 +2134,7 @@
"displayName": "Parser for ExchangeAdminAuditLogs",
"category": "Microsoft Sentinel Parser",
"functionAlias": "ExchangeAdminAuditLogs",
- "query": "let cVIPs = _GetWatchlist('ExchangeVIP') | project tostring(canonicalName) ;\nlet sVIPs = _GetWatchlist('ExchangeVIP') | project tostring(sAMAccountName) ;\nlet 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 = 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) | project tostring(Cmdlet) ;\nlet Env = ExchangeConfiguration(SpecificSectionList=\"ESIEnvironment\")\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\n| project DomainFQDN_, ESIEnvironment;\nlet MSExchange_Management = (){\n 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], \"\"))\n | extend Status = case( EventID == 1, 'Success', 'Failure')\n | extend IsVIP = iif(TargetObject in (cVIPs) or TargetObject in (sVIPs), true, false)\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,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters\n | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment\n};\nMSExchange_Management\n",
+ "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": [
@@ -2079,7 +2150,7 @@
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId1'),'/'))))]",
"dependsOn": [
- "[variables('_parserName1')]"
+ "[variables('_parserId1')]"
],
"properties": {
"parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName1'))]",
@@ -2127,7 +2198,7 @@
"displayName": "Parser for ExchangeAdminAuditLogs",
"category": "Microsoft Sentinel Parser",
"functionAlias": "ExchangeAdminAuditLogs",
- "query": "let cVIPs = _GetWatchlist('ExchangeVIP') | project tostring(canonicalName) ;\nlet sVIPs = _GetWatchlist('ExchangeVIP') | project tostring(sAMAccountName) ;\nlet 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 = 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) | project tostring(Cmdlet) ;\nlet Env = ExchangeConfiguration(SpecificSectionList=\"ESIEnvironment\")\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\n| project DomainFQDN_, ESIEnvironment;\nlet MSExchange_Management = (){\n 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], \"\"))\n | extend Status = case( EventID == 1, 'Success', 'Failure')\n | extend IsVIP = iif(TargetObject in (cVIPs) or TargetObject in (sVIPs), true, false)\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,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters\n | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment\n};\nMSExchange_Management\n",
+ "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": [
@@ -2176,7 +2247,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeConfiguration Data Parser with template version 3.0.1",
+ "description": "ExchangeConfiguration Data Parser with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserVersion2')]",
@@ -2209,7 +2280,7 @@
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId2'),'/'))))]",
"dependsOn": [
- "[variables('_parserName2')]"
+ "[variables('_parserId2')]"
],
"properties": {
"parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName2'))]",
@@ -2306,7 +2377,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ExchangeEnvironmentList Data Parser with template version 3.0.1",
+ "description": "ExchangeEnvironmentList Data Parser with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('parserVersion3')]",
@@ -2339,7 +2410,7 @@
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('_parserId3'),'/'))))]",
"dependsOn": [
- "[variables('_parserName3')]"
+ "[variables('_parserId3')]"
],
"properties": {
"parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName3'))]",
@@ -2427,6 +2498,136 @@
}
}
},
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('parserTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "MESCheckVIP Data Parser with template version 3.1.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('parserVersion4')]",
+ "parameters": {},
+ "variables": {},
+ "resources": [
+ {
+ "name": "[variables('_parserName4')]",
+ "apiVersion": "2022-10-01",
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for VIP Check for Exchange",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "MESCheckVIP",
+ "query": "//let UserToCheck = \"SampleEntry\";\nlet _UserToCheck = iif(UserToCheck == \"\" or UserToCheck == \"All\",\"All\",tolower(UserToCheck));\nlet 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\"];\nlet Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != \"00000001-0000-1000-0000-100000000000\" | project-away TableName;\nlet SearchUser = Watchlist | where _UserToCheck =~ canonicalName \n or _UserToCheck =~ displayName \n or _UserToCheck =~ userPrincipalName \n or _UserToCheck =~ sAMAccountName \n or _UserToCheck =~ objectSID \n or _UserToCheck == tostring(objectGUID) \n or _UserToCheck =~ distinguishedName\n or _UserToCheck == \"All\"\n | extend ValueChecked = iif(_UserToCheck==\"All\",strcat(\"#\",displayName,\"#\",userPrincipalName,\"#\",sAMAccountName,\"#\",objectGUID,\"#\",objectSID,\"#\",distinguishedName,\"#\"),_UserToCheck);\nSearchUser\n",
+ "functionParameters": "UserToCheck:string = \"All\"",
+ "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('_parserId4'),'/'))))]",
+ "dependsOn": [
+ "[variables('_parserId4')]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName4'))]",
+ "contentId": "[variables('_parserContentId4')]",
+ "kind": "Parser",
+ "version": "[variables('parserVersion4')]",
+ "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('_parserContentId4')]",
+ "contentKind": "Parser",
+ "displayName": "Parser for VIP Check for Exchange",
+ "contentProductId": "[variables('_parsercontentProductId4')]",
+ "id": "[variables('_parsercontentProductId4')]",
+ "version": "[variables('parserVersion4')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
+ "apiVersion": "2022-10-01",
+ "name": "[variables('_parserName4')]",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "eTag": "*",
+ "displayName": "Parser for VIP Check for Exchange",
+ "category": "Microsoft Sentinel Parser",
+ "functionAlias": "MESCheckVIP",
+ "query": "//let UserToCheck = \"SampleEntry\";\nlet _UserToCheck = iif(UserToCheck == \"\" or UserToCheck == \"All\",\"All\",tolower(UserToCheck));\nlet 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\"];\nlet Watchlist = union isfuzzy=true withsource=TableName _GetWatchlist('ExchangeVIP'), fuzzyWatchlist | where objectGUID != \"00000001-0000-1000-0000-100000000000\" | project-away TableName;\nlet SearchUser = Watchlist | where _UserToCheck =~ canonicalName \n or _UserToCheck =~ displayName \n or _UserToCheck =~ userPrincipalName \n or _UserToCheck =~ sAMAccountName \n or _UserToCheck =~ objectSID \n or _UserToCheck == tostring(objectGUID) \n or _UserToCheck =~ distinguishedName\n or _UserToCheck == \"All\"\n | extend ValueChecked = iif(_UserToCheck==\"All\",strcat(\"#\",displayName,\"#\",userPrincipalName,\"#\",sAMAccountName,\"#\",objectGUID,\"#\",objectSID,\"#\",distinguishedName,\"#\"),_UserToCheck);\nSearchUser\n",
+ "functionParameters": "UserToCheck:string = \"All\"",
+ "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('_parserId4'),'/'))))]",
+ "dependsOn": [
+ "[variables('_parserId4')]"
+ ],
+ "properties": {
+ "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), variables('parserName4'))]",
+ "contentId": "[variables('_parserContentId4')]",
+ "kind": "Parser",
+ "version": "[variables('parserVersion4')]",
+ "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",
@@ -2436,7 +2637,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.0.1",
+ "description": "Microsoft Exchange Least Privilege with RBAC Workbook with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion1')]",
@@ -2454,7 +2655,7 @@
},
"properties": {
"displayName": "[parameters('workbook1-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"743317e2-ebcf-4958-861d-4ff97fc7cce1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EnvironmentList\",\"label\":\"Environment\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"ExchangeEnvironmentList(Target=\\\"On-Premises\\\") | where ESIEnvironment != \\\"\\\"\",\"typeSettings\":{\"limitSelectTo\":1,\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"a88b4e41-eb2f-41bf-92d8-27c83650a4b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"DateOfConfiguration\",\"label\":\"Collection time\",\"type\":2,\"isRequired\":true,\"query\":\"let _configurationEnv = split(iff(isnull({EnvironmentList}) or isempty({EnvironmentList}) or tolower({EnvironmentList}) == \\\"all\\\",\\\"All\\\",tostring({EnvironmentList})),',');\\r\\nESIExchangeConfig_CL\\r\\n| extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n| where ScopedEnvironment in (_configurationEnv)\\r\\n| extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n| summarize Collection = max(Collection)\\r\\n| project Collection = \\\"lastdate\\\", Selected = true\\r\\n| join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | summarize by Collection \\r\\n | join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm ')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | join kind=leftouter (\\r\\n ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | summarize count() by Collection\\r\\n ) on Collection\\r\\n ) on Collection\\r\\n) on Collection\\r\\n| project Value = iif(Selected,Collection,iif(count_ > 1,PreciseCollection,Collection1)), Label = iif(Selected,\\\"Last Known date\\\",iif(count_ > 1,PreciseCollection,Collection1)), Selected\\r\\n| sort by Selected, Value desc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"8ac96eb3-918b-4a36-bcc4-df50d8f46175\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Help\",\"label\":\"Show Help\",\"type\":10,\"isRequired\":true,\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"[\\\\r\\\\n { \\\\\\\"value\\\\\\\": \\\\\\\"Yes\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"Yes\\\\\\\"},\\\\r\\\\n {\\\\\\\"value\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"selected\\\\\\\":true }\\\\r\\\\n]\\\\r\\\\n\\\"}\",\"timeContext\":{\"durationMs\":2592000000},\"queryType\":8}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"TimeRange\"},{\"type\":1,\"content\":{\"json\":\"This workbook displayed the custom RBAC delegations: on default groups, on Custom Roles groups, Using custom roles.\\r\\nSelect your Exchange Organization and adjust the time range.\\r\\nBy default, the Help won't be displayed. To display the help, choose Yes on the toogle buttom \\\"Show Help\\\"\",\"style\":\"info\"},\"name\":\"text - 8\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"e59f0f7f-fd05-4ec8-9f59-e4d9c3b589f2\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Current RBAC Delegation\",\"subTarget\":\"RBACDelegation\",\"preText\":\"RBAC Delegation\",\"postText\":\"\",\"style\":\"link\"},{\"id\":\"67739913-b364-4071-864d-faf4d94c9ad6\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Custom Roles\",\"subTarget\":\"CustomRole\",\"style\":\"link\"},{\"id\":\"8def944a-53fe-4544-bc8f-5b3ca66eda34\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Default Groups content\",\"subTarget\":\"DefaultGroup\",\"preText\":\"Default Group\",\"style\":\"link\"},{\"id\":\"5eeebe10-be67-4f8a-9d91-4bc6c70c3e16\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workbook Help\",\"subTarget\":\"start\",\"style\":\"link\"}]},\"name\":\"links - 3\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegations\",\"items\":[{\"type\":1,\"content\":{\"json\":\"The current delegations are compared to an export of default delegations done on Exchange 2019.\\r\\nTo find which is used for the comparaison please follow this link.\\r\\nThe export is located on the public GitHub of the project.\\r\\n\\r\\ncheck this link : https://aka.ms/esiwatchlist\\r\\n\\r\\nIt will be updated by the team project.\\r\\n\",\"style\":\"info\"},\"name\":\"text - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegations on User Accounts\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays custom delegations set directly on User Accounts.\"},\"name\":\"text - 2 - Copy\"},{\"type\":1,\"content\":{\"json\":\"This section displays all the nonstandard delegations done directly to a user account.\\r\\n\\r\\nDetailed information for the user accounts will be displayed.\\r\\n\\r\\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\\r\\n\\r\\nThese types of delegations are not visible on the Exchange Admin Center.\\r\\n\\r\\nUsual results :\\r\\n\\r\\n - Delegations done directly to service account. Being able to see this delegation will help to sanityze the environment as some delegations may be no more necessary\\r\\n\\r\\n - Delegation done by mistake directly to Administrator Accounts\\r\\n\\r\\n - Suspicious delegations\\r\\n\\r\\nDetailed information for the user accounts will be displayed in the sections below.\\r\\n\\r\\nView RBAC effective permissions\\r\\n\\r\\nGet-ManagementRoleAssignment\\r\\n\\r\\nUnderstanding Role Based Access Control\\r\\n\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"d9d4e0a2-b75d-4825-9f4e-7606516500e1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\\r\\n\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"46c608de-033d-4c4f-99e6-2784439cfa18\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Role\",\"type\":2,\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n|extend Role=tostring (CmdletResultValue.Role.Name)\\r\\n| distinct Role\\r\\n| sort by Role asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleAssigneeName endswith \\\"{RoleAssignee}\\\" \\r\\n| where CmdletResultValue.Role.Name contains \\\"{Role}\\\"\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\" and CmdletResultValue.Name !contains \\\"Deleg\\\"\\r\\n| extend Name = tostring(CmdletResultValue.Name)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend Status= tostring(CmdletResultValue.Enabled)\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\")\\r\\n| project Name,Role,RoleAssigneeName, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\\r\\n\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"CmdletName\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"31.5ch\"}},{\"columnMatch\":\"Total\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"9.3ch\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"330px\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":10,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"330px\"}}],\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"RoleAssigneeName\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"RoleAssigneeName\",\"sortOrder\":1}]},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Custom Delegations on User Accounts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegation on Groups\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays custom delegations set on groups.\"},\"name\":\"text - 2\"},{\"type\":1,\"content\":{\"json\":\"This section displays all the nonstandard delegations done for standard and nonstandard groups. Indeed, default groups have a list of default delegations but an Exchange administrators can add also new roles to the default groups.\\r\\n\\r\\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\\r\\n\\r\\n\\r\\nUsual results :\\r\\n\\r\\n - Delegations done for role group Organization Management to role like Mailbox Import Export or Mailbox Search (by default this delegation is not configured)\\r\\n\\r\\n - Delegation done by mistake\\r\\n\\r\\n - Suspicious delegations\\r\\n\\r\\nDetailed information for the user accounts present in the groups will be displayed in the sections below.\\r\\n\\r\\nView RBAC effective permissions\\r\\n\\r\\nGet-ManagementRoleAssignment\\r\\n\\r\\nUnderstanding Role Based Access Control \\r\\n\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"c548eb09-54e3-41bf-a99d-be3534f7018b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\" or CmdletResultValue.RoleAssigneeType == \\\"12\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"rowLimit\":10000},{\"id\":\"4194717a-4a09-4c73-b02d-b1ac8587619d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Role\",\"type\":2,\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n|extend Role=tostring (CmdletResultValue.Role.Name)\\r\\n| distinct Role\\r\\n| sort by Role asc\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nlet RoleG = ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| project RoleAssigneeName=tostring(CmdletResultValue.Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleAssigneeName endswith \\\"{RoleAssignee}\\\" \\r\\n| where CmdletResultValue.Role.Name contains \\\"{Role}\\\"\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\" or CmdletResultValue.RoleAssigneeType == \\\"12\\\"\\r\\n| extend Name = tostring(CmdletResultValue.Name)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n|lookup RoleG on RoleAssigneeName \\r\\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\")\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend Status= tostring(CmdletResultValue.Enabled)\\r\\n| project Name,Role,RoleAssigneeName,LinkedGroup, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Custom Delegation on Groups\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Custom Delegation\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee User account\",\"items\":[{\"type\":1,\"content\":{\"json\":\"In the previous section, custom delegations for user have been displayed.\\r\\n\\r\\nThis section display detailed information for the accounts found in the previous. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\\r\\n\\r\\nSelect a user un the dropdown list.\\r\\n\\r\\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"This section displays details information for user accounts found with non standard delegations :\\r\\n - Last logon\\r\\n - Last Password changed\\r\\n - Account enabled\\r\\n\\r\\nYou may find old service accounts that are no more used, or with a last password set very old...\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"27e4c2e9-d113-4bf9-808f-0f8f68b5152e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"isRequired\":true,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"10c2eb2f-2cf2-4650-a9f1-3ee646acaebb\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"},{\"id\":\"6f7128ee-2f2c-421d-bc9f-37aee85fb214\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"label\":\"Password Last Set\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"DirectRoleAssignments\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.SamAccountName contains \\\"{RoleAssignee}\\\"\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| project CmdletResultValue\\r\\n| extend ManagementRoleAssignment = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend Account = tostring(CmdletResultValue.SamAccountName)\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue\\r\\n| sort by Account asc\",\"size\":1,\"showAnalytics\":true,\"color\":\"green\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"ManagementRoleAssignment\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"ManagementRoleAssignment\",\"sortOrder\":1}]},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Role Assignee User account\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee group\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Details information for Group delegation\\r\\nIn the previous section, custom delegations for groups have been displayed.\\r\\n\\r\\nThis section display detailed information for the accounts found in the group displayed in the previuos section. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\\r\\n\\r\\nSelect a group un the dropdown list.\\r\\n\\r\\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"This section displays details information for user accounts included in the found groups with non standard delegation : \\r\\n\\r\\n - Last logon\\r\\n - Last Password changed\\r\\n - Account enabled\\r\\n\\r\\nYou may find old service accounts that are no more used, or with a last password set very old...\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"75c3cdf3-d0c3-46c3-83ae-429979774234\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"isRequired\":true,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"1a3b374c-0467-4fd9-b2fc-edebd0a97302\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"},{\"id\":\"170db194-195f-4991-b726-6c0658562616\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup contains \\\"{RoleAssignee}\\\"\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| where CmdletResultValue.Level != 0\\r\\n| project CmdletResultValue\\r\\n| extend Level_ = tostring(CmdletResultValue.Level)\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue, Level_,Parentgroup\\r\\n| sort by MemberPath asc\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Role Assignee group\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Information for Role Assignee\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Linked Groups information\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Linked Groups\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Display associated remote forest's group for Linked Group\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"RoleGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleGroupType == \\\"1\\\"\\r\\n//| extend ManagementRoleAssignment = tostring(CmdletResultValue.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.Name)\\r\\n| extend LinkedGroup = tostring(CmdletResultValue.LinkedGroup)\\r\\n//| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n//|lookup RoleG on RoleAssigneeName \\r\\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n| project RoleAssigneeName, LinkedGroup, WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\",\"size\":1,\"showAnalytics\":true,\"color\":\"green\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Linked Groups\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Linked Groups information\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let StandardGroup = dynamic([\\\"Compliance Management\\\", \\\"Delegated Setup\\\",\\\"Discovery Management\\\",\\\"Help Desk\\\",\\\"Hygiene Management\\\",\\\"Organization Management\\\",\\\"Public Folder Management\\\",\\\"Recipient Management\\\",\\\"Records Management\\\",\\\"Security Administrator\\\",\\\"Security Reader\\\",\\\"Server Management\\\",\\\"UM Management\\\",\\\"View-Only Organization Management\\\"]);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup in (StandardGroup)\\r\\n| project CmdletResultValue\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| summarize Total = count()-1 by Parentgroup\\r\\n| extend Comment = case (Total>0 and Parentgroup contains \\\"Discovery Management\\\", \\\"❌ This group should be empty Just in time should be used\\\", Total>5 and Parentgroup contains \\\"Organization Management\\\", \\\"❌ The content of this group should limited to only Level 3 Administrators\\\", Total>0 and Parentgroup contains \\\"Hygiene Management\\\", \\\"❌ This group should be empty or only contains Exchange server and/or Exchange antivirus Spam accounts\\\", \\\"Remember to regularly review the content of the group\\\")\\r\\n| sort by Parentgroup asc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Numbers of members for high privileges groups\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Explanations\",\"expandable\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"All the default Exchange groups located in the default Exchange OU : Microsoft Exchange Security Groups are displayed with their number of members.\\r\\n\\r\\nIt is very important to monitor the content of Exchange groups and raise an alert when a new member is added.\\r\\n\\r\\nFor critical groups, a warning is display if the number exceeded a define thresold :\\r\\n - Discovery Management: This group should be empty, so a warning is displayed when the group is not empty\\r\\n\\r\\n - Organization Management : This group should only contain only Exchange expert. No service account should be member of this groupe. A warning is display when the total numer of member exceeded 5\\r\\n - Hygiene Management : This group can acces and moidify the content of all mailboxes using EWS. A warning is display when the group is not empty. This warning can be ignored if the accounts are the Antispam service account or Exchange servers Computer accounts\"},\"name\":\"text - 0\"}]},\"name\":\"group - 1\"}]},\"name\":\"Summarize Number of Member Per Group\"},{\"type\":1,\"content\":{\"json\":\"❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"7c281d60-8434-4636-b85e-aef6296f1107\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"e122a0de-1395-4002-96f9-cc057c257518\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"label\":\"Password Last Set\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let StandardGroup = dynamic([\\\"Compliance Management\\\", \\\"Delegated Setup\\\",\\\"Discovery Management\\\",\\\"Help Desk\\\",\\\"Hygiene Management\\\",\\\"Organization Management\\\",\\\"Public Folder Management\\\",\\\"Recipient Management\\\",\\\"Records Management\\\",\\\"Security Administrator\\\",\\\"Security Reader\\\",\\\"Server Management\\\",\\\"UM Management\\\",\\\"View-Only Organization Management\\\"]);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup in (StandardGroup)\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| project CmdletResultValue\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\\r\\n| extend Level = tostring(CmdletResultValue.Level)\\r\\n| where Level !=0\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue\\r\\n| sort by MemberPath asc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Default Exchange groups content\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"$gen_group\",\"formatter\":1},{\"columnMatch\":\"ParentGroup\",\"formatter\":1},{\"columnMatch\":\"Parentgroup\",\"formatter\":5},{\"columnMatch\":\"Group\",\"formatter\":1}],\"rowLimit\":10000,\"filter\":true,\"hierarchySettings\":{\"treeType\":1,\"groupBy\":[\"Parentgroup\"],\"finalBy\":\"Parentgroup\"},\"labelSettings\":[{\"columnId\":\"Parentgroup\",\"label\":\"ParentGroup\"}]}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Explanations\",\"expandable\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"This section the content of the groups with details informations.\\r\\n\\r\\nIt is recommended to check the Last logon and last password change informations.\"},\"name\":\"text - 0\"}]},\"name\":\"group - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"DefaultGroup\"},\"name\":\"group - 4\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Let start with Least Privileges with RBAC\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Workbook goals\\r\\nThe goals of this workbook is to show you the current RBAC delegation\\r\\n\\r\\n\\r\\nThis workbook will display :\\r\\n\\r\\n - NonStandrd RBAC delegation\\r\\n\\r\\n - Exchange default group content\\r\\n\\r\\n - Analysis of the actions performed by Organization Management members to remove them from the groups\\r\\n\\r\\n----\\r\\n\\r\\n## Tabs\\r\\n\\r\\n### Current RBAC Delegation\\r\\n\\r\\nThis tab will show all the nonstandard RBAC delegation.\\r\\n\\r\\n**Most of the time RBAC are done and forgotten... This tab will provide a clear statut of the delegation and help with the remediation.**\\r\\n\\r\\nBy nonstandard, it means that the current delegation are compared to the delegation from Exchange 2019 CU11.\\r\\n\\r\\nNonstandard delegation for standard groups like Organization Management will also be displayed.\\r\\n\\r\\nDetail information for found will be displayed : Last logon, last password changed...\\r\\n\\r\\n### Default Group content\\r\\n\\r\\nThis tab will show the number of members for default Exchange groups and their content.\\r\\n\\r\\nMost of the time, the content of common Exchange groups but Exchange is shipped with many groups that have very high privileges and its interesting to see that they are not empty as expected.\"},\"name\":\"text - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"start\"},\"name\":\"group - 6\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Role details\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"List of Custom Roles\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section shows the Custom management roles that exist in your environnment and the name of the parent's role\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"Liste of existing Custom roles\"},\"customWidth\":\"50\",\"name\":\"text - 5\"},{\"type\":1,\"content\":{\"json\":\"List of Custom with a Management Role Assignement (associated with a group or a user). Display the target account and scope if set\"},\"customWidth\":\"50\",\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| extend WhenCreated = WhenCreated\\r\\n| project Identity, ParentRole, WhenCreated, WhenChanged\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n//| extend Scope = tostring(CmdletResultValue.RecipientWriteScope)\\r\\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n//| project Role = tostring(CmdletResultValue.Role.Name)\\r\\n| distinct Role,RoleAssigneeName,Scope\\r\\n| project Role,RoleAssigneeName,Scope\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| project Role = tostring(CmdletResultValue.Name));\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| project Role = tostring(CmdletResultValue.Role.Name), Scope, RoleAssigneeName\\r\\n| join kind=fullouter (MRcustomRoles) on Role\\r\\n| project Role = Role1, Scope, RoleAssigneeName,Comment = iff(Role == \\\"\\\", \\\"⚠️ No existing delegation for this role\\\", \\\"✅ This role is delegated with a Management Role Assignment\\\")\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n | project Role = tostring(CmdletResultValue.Name));\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| project Role = tostring(CmdletResultValue.Role.Name)\\r\\n| join kind=fullouter (MRcustomRoles) on Role\\r\\n| summarize acount = count() by iff( Role==\\\"\\\",\\\"Number of non assigned roles\\\", Role)\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 3\"}]},\"name\":\"List of Custom Roles\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Roles delegation on group\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section shows delegation associated with the Custom Roles\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \\\"0\\\" or CmdletResultValue.RoleAssigneeType== \\\"2\\\" , \\\"User\\\", CmdletResultValue.RoleAssigneeType== \\\"10\\\",\\\"Group\\\",\\\"LinkedGroup\\\")\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\") \\r\\n| extend RoleAssigneeName = iff( RoleAssigneeType == \\\"User\\\", strcat(\\\"🧑🦰 \\\",tostring(CmdletResultValue.RoleAssigneeName)), strcat(\\\"👪 \\\", tostring(CmdletResultValue.RoleAssigneeName)) )\\r\\n| project RoleAssigneeName, Role, RoleAssigneeType, CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged\\r\\n\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\"}]},\"name\":\"group - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Details for Custom Roles Cmdlets \",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays for the chosen custom management roles all Cmdlets and their parameters associated with this custom role.\\r\\nRemember that for a cmdlet, some parameters can be removed.\"},\"name\":\"text - 0\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"07c8ac83-371d-4702-ab66-72aeb2a20053\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CustomRole\",\"type\":2,\"isRequired\":true,\"query\":\" ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| project Identity\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by Role;\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = CmdletResultValue.Name\\r\\n| extend Parameters = CmdletResultValue.Parameters\\r\\n| project CmdletName,Parameters,ParentRole = SelectedRole\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Parameters\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"100ch\"}}],\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"70\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by Role;\\r\\nlet MRCustomD = ExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend Role = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = CmdletResultValue.Name\\r\\n| extend ParentRole = tostring(SelectedRole)\\r\\n| summarize CmdletCount = count() by Role, ParentRole\\r\\n| project Role,CmdletCount;\\r\\nunion MRCustomD, DefMRA\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"30\",\"name\":\"query - 3\"},{\"type\":1,\"content\":{\"json\":\"List of Cmdlets ( Get- command have been removed to clarify the information) with :\\r\\nCustomParamCount : number of parameters for the Cmdlet in the custom role\\r\\nDefaultCmdletNumberofParam : number of parameters for the Cmdlet in the default role\\r\\n\"},\"name\":\"text - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,Name:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | mv-expand split(todynamic(Parameters),\\\";\\\")| summarize ParamCount = count() by Name;\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = tostring(CmdletResultValue.Name)\\r\\n| where CmdletName !contains \\\"get-\\\"\\r\\n| extend Parameters = CmdletResultValue.Parameters\\r\\n| extend ParentRole = tostring(SelectedRole)\\r\\n| mv-expand split(todynamic(Parameters),\\\";\\\")\\r\\n| summarize ParamCount = count() by CmdletName, ParentRole\\r\\n| join (DefMRA) on $left.CmdletName == $right.Name\\r\\n| project CmdletName, CustomParamCount = ParamCount , DefaultCmdletNumberofParam = ParamCount1\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"DefaultCmdletNumberofParam\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"DefaultCmdletNumberofParam\",\"sortOrder\":1}]},\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Details for Custom Roles Cmdlets \"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"CustomRole\"},\"name\":\"Custom Role\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-MicrosoftExchangeLeastPrivilegewithRBAC\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
+ "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"743317e2-ebcf-4958-861d-4ff97fc7cce1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EnvironmentList\",\"label\":\"Environment\",\"type\":2,\"isRequired\":true,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"ExchangeEnvironmentList(Target=\\\"On-Premises\\\") | where ESIEnvironment != \\\"\\\"\",\"typeSettings\":{\"limitSelectTo\":1,\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"a88b4e41-eb2f-41bf-92d8-27c83650a4b8\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"DateOfConfiguration\",\"label\":\"Collection time\",\"type\":2,\"isRequired\":true,\"query\":\"let _configurationEnv = split(iff(isnull({EnvironmentList}) or isempty({EnvironmentList}) or tolower({EnvironmentList}) == \\\"all\\\",\\\"All\\\",tostring({EnvironmentList})),',');\\r\\nESIExchangeConfig_CL\\r\\n| extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n| where ScopedEnvironment in (_configurationEnv)\\r\\n| extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n| summarize Collection = max(Collection)\\r\\n| project Collection = \\\"lastdate\\\", Selected = true\\r\\n| join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | summarize by Collection \\r\\n | join kind= fullouter ( ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm ')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | join kind=leftouter (\\r\\n ESIExchangeConfig_CL | extend ScopedEnvironment = iff(_configurationEnv contains \\\"All\\\", \\\"All\\\",ESIEnvironment_s) \\r\\n | where ScopedEnvironment in (_configurationEnv)\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend Collection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd')\\r\\n | extend PreciseCollection = format_datetime(todatetime(EntryDate_s), 'yyyy-MM-dd HH:mm')\\r\\n | summarize by PreciseCollection, Collection \\r\\n | summarize count() by Collection\\r\\n ) on Collection\\r\\n ) on Collection\\r\\n) on Collection\\r\\n| project Value = iif(Selected,Collection,iif(count_ > 1,PreciseCollection,Collection1)), Label = iif(Selected,\\\"Last Known date\\\",iif(count_ > 1,PreciseCollection,Collection1)), Selected\\r\\n| sort by Selected, Value desc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"8ac96eb3-918b-4a36-bcc4-df50d8f46175\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Help\",\"label\":\"Show Help\",\"type\":10,\"isRequired\":true,\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"[\\\\r\\\\n { \\\\\\\"value\\\\\\\": \\\\\\\"Yes\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"Yes\\\\\\\"},\\\\r\\\\n {\\\\\\\"value\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"selected\\\\\\\":true }\\\\r\\\\n]\\\\r\\\\n\\\"}\\r\\n\",\"timeContext\":{\"durationMs\":2592000000},\"queryType\":8}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"TimeRange\"},{\"type\":1,\"content\":{\"json\":\"This workbook displayed the custom RBAC delegations: on default groups, on Custom Roles groups, Using custom roles.\\r\\nSelect your Exchange Organization and adjust the time range.\\r\\nBy default, the Help won't be displayed. To display the help, choose Yes on the toogle buttom \\\"Show Help\\\"\",\"style\":\"info\"},\"name\":\"text - 8\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"e59f0f7f-fd05-4ec8-9f59-e4d9c3b589f2\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Current RBAC Delegation\",\"subTarget\":\"RBACDelegation\",\"preText\":\"RBAC Delegation\",\"postText\":\"\",\"style\":\"link\"},{\"id\":\"67739913-b364-4071-864d-faf4d94c9ad6\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Custom Roles\",\"subTarget\":\"CustomRole\",\"style\":\"link\"},{\"id\":\"8def944a-53fe-4544-bc8f-5b3ca66eda34\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Default Groups content\",\"subTarget\":\"DefaultGroup\",\"preText\":\"Default Group\",\"style\":\"link\"},{\"id\":\"5eeebe10-be67-4f8a-9d91-4bc6c70c3e16\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Workbook Help\",\"subTarget\":\"start\",\"style\":\"link\"}]},\"name\":\"links - 3\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegations\",\"items\":[{\"type\":1,\"content\":{\"json\":\"The current delegations are compared to an export of default delegations done on Exchange 2019.\\r\\nTo find which is used for the comparaison please follow this link.\\r\\nThe export is located on the public GitHub of the project.\\r\\n\\r\\ncheck this link : https://aka.ms/esiwatchlist\\r\\n\\r\\nIt will be updated by the team project.\\r\\n\",\"style\":\"info\"},\"name\":\"text - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegations on User Accounts\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays custom delegations set directly on User Accounts.\"},\"name\":\"text - 2 - Copy\"},{\"type\":1,\"content\":{\"json\":\"This section displays all the nonstandard delegations done directly to a user account.\\r\\n\\r\\nDetailed information for the user accounts will be displayed.\\r\\n\\r\\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\\r\\n\\r\\nThese types of delegations are not visible on the Exchange Admin Center.\\r\\n\\r\\nUsual results :\\r\\n\\r\\n - Delegations done directly to service account. Being able to see this delegation will help to sanityze the environment as some delegations may be no more necessary\\r\\n\\r\\n - Delegation done by mistake directly to Administrator Accounts\\r\\n\\r\\n - Suspicious delegations\\r\\n\\r\\nDetailed information for the user accounts will be displayed in the sections below.\\r\\n\\r\\nView RBAC effective permissions\\r\\n\\r\\nGet-ManagementRoleAssignment\\r\\n\\r\\nUnderstanding Role Based Access Control\\r\\n\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"d9d4e0a2-b75d-4825-9f4e-7606516500e1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\\r\\n\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"46c608de-033d-4c4f-99e6-2784439cfa18\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Role\",\"type\":2,\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n|extend Role=tostring (CmdletResultValue.Role.Name)\\r\\n| distinct Role\\r\\n| sort by Role asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleAssigneeName endswith \\\"{RoleAssignee}\\\" \\r\\n| where CmdletResultValue.Role.Name contains \\\"{Role}\\\"\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\" and CmdletResultValue.Name !contains \\\"Deleg\\\"\\r\\n| extend Name = tostring(CmdletResultValue.Name)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend Status= tostring(CmdletResultValue.Enabled)\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\")\\r\\n| project Name,Role,RoleAssigneeName, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\\r\\n\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"CmdletName\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"31.5ch\"}},{\"columnMatch\":\"Total\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"9.3ch\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"330px\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":10,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"330px\"}}],\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"RoleAssigneeName\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"RoleAssigneeName\",\"sortOrder\":1}]},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Custom Delegations on User Accounts\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Delegation on Groups\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays custom delegations set on groups.\"},\"name\":\"text - 2\"},{\"type\":1,\"content\":{\"json\":\"This section displays all the nonstandard delegations done for standard and nonstandard groups. Indeed, default groups have a list of default delegations but an Exchange administrators can add also new roles to the default groups.\\r\\n\\r\\nThis status is done by comparing current delegation with the default delegations for latest export of default Exchange 2019 delegation located in the public GitHub of the project.\\r\\n\\r\\n\\r\\nUsual results :\\r\\n\\r\\n - Delegations done for role group Organization Management to role like Mailbox Import Export or Mailbox Search (by default this delegation is not configured)\\r\\n\\r\\n - Delegation done by mistake\\r\\n\\r\\n - Suspicious delegations\\r\\n\\r\\nDetailed information for the user accounts present in the groups will be displayed in the sections below.\\r\\n\\r\\nView RBAC effective permissions\\r\\n\\r\\nGet-ManagementRoleAssignment\\r\\n\\r\\nUnderstanding Role Based Access Control \\r\\n\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"c548eb09-54e3-41bf-a99d-be3534f7018b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\" or CmdletResultValue.RoleAssigneeType == \\\"12\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"rowLimit\":10000},{\"id\":\"4194717a-4a09-4c73-b02d-b1ac8587619d\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Role\",\"type\":2,\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n|extend Role=tostring (CmdletResultValue.Role.Name)\\r\\n| distinct Role\\r\\n| sort by Role asc\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nlet RoleG = ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| project RoleAssigneeName=tostring(CmdletResultValue.Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleAssigneeName endswith \\\"{RoleAssignee}\\\" \\r\\n| where CmdletResultValue.Role.Name contains \\\"{Role}\\\"\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\" or CmdletResultValue.RoleAssigneeType == \\\"12\\\"\\r\\n| extend Name = tostring(CmdletResultValue.Name)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n|lookup RoleG on RoleAssigneeName \\r\\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\")\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend Status= tostring(CmdletResultValue.Enabled)\\r\\n| project Name,Role,RoleAssigneeName,LinkedGroup, RoleAssignmentDelegationType,Status,CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope,WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Custom Delegation on Groups\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Custom Delegation\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee User account\",\"items\":[{\"type\":1,\"content\":{\"json\":\"In the previous section, custom delegations for user have been displayed.\\r\\n\\r\\nThis section display detailed information for the accounts found in the previous. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\\r\\n\\r\\nSelect a user un the dropdown list.\\r\\n\\r\\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"This section displays details information for user accounts found with non standard delegations :\\r\\n - Last logon\\r\\n - Last Password changed\\r\\n - Account enabled\\r\\n\\r\\nYou may find old service accounts that are no more used, or with a last password set very old...\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"27e4c2e9-d113-4bf9-808f-0f8f68b5152e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"isRequired\":true,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"0\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"10c2eb2f-2cf2-4650-a9f1-3ee646acaebb\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"},{\"id\":\"6f7128ee-2f2c-421d-bc9f-37aee85fb214\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"label\":\"Password Last Set\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"DirectRoleAssignments\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.SamAccountName contains \\\"{RoleAssignee}\\\"\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| project CmdletResultValue\\r\\n| extend ManagementRoleAssignment = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend Account = tostring(CmdletResultValue.SamAccountName)\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue\\r\\n| sort by Account asc\",\"size\":1,\"showAnalytics\":true,\"color\":\"green\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"ManagementRoleAssignment\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"ManagementRoleAssignment\",\"sortOrder\":1}]},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Role Assignee User account\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Role Assignee group\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Details information for Group delegation\\r\\nIn the previous section, custom delegations for groups have been displayed.\\r\\n\\r\\nThis section display detailed information for the accounts found in the group displayed in the previuos section. Once you know that an account has a high privilege delegations, you may want to have additional information like Last Logon, Password Last Set...\\r\\n\\r\\nSelect a group un the dropdown list.\\r\\n\\r\\n❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"This section displays details information for user accounts included in the found groups with non standard delegation : \\r\\n\\r\\n - Last logon\\r\\n - Last Password changed\\r\\n - Account enabled\\r\\n\\r\\nYou may find old service accounts that are no more used, or with a last password set very old...\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"75c3cdf3-d0c3-46c3-83ae-429979774234\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"RoleAssignee\",\"type\":2,\"isRequired\":true,\"query\":\"let DefMRA = externaldata (Name:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/StandardMRA.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| summarize make_list(Name);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Name !in (DefMRA) and CmdletResultValue.RoleAssigneeType == \\\"10\\\" or CmdletResultValue.RoleAssigneeType == \\\"2\\\"\\r\\n| project CmdletResultValue\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| distinct RoleAssigneeName\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"1a3b374c-0467-4fd9-b2fc-edebd0a97302\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"},{\"id\":\"170db194-195f-4991-b726-6c0658562616\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup contains \\\"{RoleAssignee}\\\"\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| where CmdletResultValue.Level != 0\\r\\n| project CmdletResultValue\\r\\n| extend Level_ = tostring(CmdletResultValue.Level)\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue, Level_,Parentgroup\\r\\n| sort by MemberPath asc\",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Role Assignee group\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Information for Role Assignee\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Linked Groups information\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Information for Linked Groups\",\"items\":[{\"type\":1,\"content\":{\"json\":\"Display associated remote forest's group for Linked Group\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"RoleGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.RoleGroupType == \\\"1\\\"\\r\\n//| extend ManagementRoleAssignment = tostring(CmdletResultValue.Name)\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.Name)\\r\\n| extend LinkedGroup = tostring(CmdletResultValue.LinkedGroup)\\r\\n//| extend LinkedGroup = iff(tostring(CmdletResultValue.RoleAssigneeType)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n//|lookup RoleG on RoleAssigneeName \\r\\n//| extend LinkedGroup = iff(tostring(LinkedGroup)==\\\"12\\\", \\\"Yes\\\",\\\"No\\\")\\r\\n| project RoleAssigneeName, LinkedGroup, WhenCreated, WhenChanged\\r\\n| sort by RoleAssigneeName asc\",\"size\":1,\"showAnalytics\":true,\"color\":\"green\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Information for Linked Groups\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"RBACDelegation\"},\"name\":\"Linked Groups information\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let StandardGroup = dynamic([\\\"Compliance Management\\\", \\\"Delegated Setup\\\",\\\"Discovery Management\\\",\\\"Help Desk\\\",\\\"Hygiene Management\\\",\\\"Organization Management\\\",\\\"Public Folder Management\\\",\\\"Recipient Management\\\",\\\"Records Management\\\",\\\"Security Administrator\\\",\\\"Security Reader\\\",\\\"Server Management\\\",\\\"UM Management\\\",\\\"View-Only Organization Management\\\"]);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup in (StandardGroup)\\r\\n| project CmdletResultValue\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| summarize Total = count()-1 by Parentgroup\\r\\n| extend Comment = case (Total>0 and Parentgroup contains \\\"Discovery Management\\\", \\\"❌ This group should be empty Just in time should be used\\\", Total>5 and Parentgroup contains \\\"Organization Management\\\", \\\"❌ The content of this group should limited to only Level 3 Administrators\\\", Total>0 and Parentgroup contains \\\"Hygiene Management\\\", \\\"❌ This group should be empty or only contains Exchange server and/or Exchange antivirus Spam accounts\\\", \\\"Remember to regularly review the content of the group\\\")\\r\\n| sort by Parentgroup asc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Numbers of members for high privileges groups\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Explanations\",\"expandable\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"All the default Exchange groups located in the default Exchange OU : Microsoft Exchange Security Groups are displayed with their number of members.\\r\\n\\r\\nIt is very important to monitor the content of Exchange groups and raise an alert when a new member is added.\\r\\n\\r\\nFor critical groups, a warning is display if the number exceeded a define thresold :\\r\\n - Discovery Management: This group should be empty, so a warning is displayed when the group is not empty\\r\\n\\r\\n - Organization Management : This group should only contain only Exchange expert. No service account should be member of this groupe. A warning is display when the total numer of member exceeded 5\\r\\n - Hygiene Management : This group can acces and moidify the content of all mailboxes using EWS. A warning is display when the group is not empty. This warning can be ignored if the accounts are the Antispam service account or Exchange servers Computer accounts\"},\"name\":\"text - 0\"}]},\"name\":\"group - 1\"}]},\"name\":\"Summarize Number of Member Per Group\"},{\"type\":1,\"content\":{\"json\":\"❌ : for last logon displayed when user logged or the last logon is greater than 180 days\\r\\n\\r\\n❌ : for password last set displayed when last password set greater than 366 days\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"7c281d60-8434-4636-b85e-aef6296f1107\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"LastLogon\",\"label\":\"Last Logon\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[ {\\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true},\\r\\n{ \\\"value\\\": \\\"90d\\\", \\\"label\\\": \\\"90d\\\" },\\r\\n { \\\"value\\\": \\\"180d\\\", \\\"label\\\": \\\"6m\\\" },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1085d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"e122a0de-1395-4002-96f9-cc057c257518\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"PasswordLast\",\"label\":\"Password Last Set\",\"type\":10,\"isRequired\":true,\"jsonData\":\"[{ \\\"value\\\": \\\"0d\\\", \\\"label\\\": \\\"No filter\\\",\\\"selected\\\":true },\\r\\n { \\\"value\\\": \\\"365d\\\", \\\"label\\\": \\\"1y\\\" },\\r\\n{ \\\"value\\\": \\\"730d\\\", \\\"label\\\": \\\"2y\\\" },\\r\\n{ \\\"value\\\": \\\"1095d\\\", \\\"label\\\": \\\"3y\\\" },\\r\\n{ \\\"value\\\": \\\"1097d\\\", \\\"label\\\": \\\"more than 3y\\\"},\\r\\n{ \\\"value\\\": \\\"3650d\\\", \\\"label\\\": \\\"more than 10y\\\"}\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let StandardGroup = dynamic([\\\"Compliance Management\\\", \\\"Delegated Setup\\\",\\\"Discovery Management\\\",\\\"Help Desk\\\",\\\"Hygiene Management\\\",\\\"Organization Management\\\",\\\"Public Folder Management\\\",\\\"Recipient Management\\\",\\\"Records Management\\\",\\\"Security Administrator\\\",\\\"Security Reader\\\",\\\"Server Management\\\",\\\"UM Management\\\",\\\"View-Only Organization Management\\\"]);\\r\\nExchangeConfiguration(SpecificSectionList=\\\"ExGroup\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList})\\r\\n| where CmdletResultValue.Parentgroup in (StandardGroup)\\r\\n| where todatetime (CmdletResultValue.LastPwdSetString) < ago({PasswordLast}) or tostring (CmdletResultValue.LastPwdSetString) == \\\"\\\"\\r\\n| where todatetime (CmdletResultValue.LastLogonString) < ago({LastLogon}) or tostring (CmdletResultValue.LastLogonString) == \\\"\\\"\\r\\n| project CmdletResultValue\\r\\n| extend Parentgroup = tostring(CmdletResultValue.Parentgroup)\\r\\n| extend MemberPath = tostring(CmdletResultValue.MemberPath)\\r\\n| extend Level = tostring(CmdletResultValue.Level)\\r\\n| where Level !=0\\r\\n| extend ObjectClass = tostring(CmdletResultValue.ObjectClass)\\r\\n| extend LastLogon = tostring(CmdletResultValue.LastLogonString)\\r\\n| extend LastLogon = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\", iif ( todatetime (CmdletResultValue.LastLogonString) > ago(180d), CmdletResultValue.LastLogonString,iff (LastLogon==\\\"\\\", \\\"❌ Never logged\\\",strcat(\\\"❌\\\",LastLogon))))\\r\\n| extend LastPwdSet = CmdletResultValue.LastPwdSetString\\r\\n| extend LastPwdSet = iif(ObjectClass==\\\"group\\\" or ObjectClass==\\\"computer\\\" or ObjectClass==\\\"Local User\\\" or ObjectClass==\\\"computer\\\",\\\"N/A\\\",iif ( todatetime (CmdletResultValue.LastPwdSetString) > ago(366d), CmdletResultValue.LastPwdSetString,iff (LastPwdSet==\\\"\\\", \\\"❌ Password never set\\\",strcat(\\\"❌\\\",LastPwdSet))))\\r\\n| extend Enabled = tostring(CmdletResultValue.Enabled)\\r\\n| extend DN = tostring(CmdletResultValue.DN)\\r\\n| project-away CmdletResultValue\\r\\n| sort by MemberPath asc\",\"size\":3,\"showAnalytics\":true,\"title\":\"Default Exchange groups content\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"$gen_group\",\"formatter\":1},{\"columnMatch\":\"ParentGroup\",\"formatter\":1},{\"columnMatch\":\"Parentgroup\",\"formatter\":5},{\"columnMatch\":\"Group\",\"formatter\":1}],\"rowLimit\":10000,\"filter\":true,\"hierarchySettings\":{\"treeType\":1,\"groupBy\":[\"Parentgroup\"],\"finalBy\":\"Parentgroup\"},\"labelSettings\":[{\"columnId\":\"Parentgroup\",\"label\":\"ParentGroup\"}]}},\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Explanations\",\"expandable\":true,\"items\":[{\"type\":1,\"content\":{\"json\":\"This section the content of the groups with details informations.\\r\\n\\r\\nIt is recommended to check the Last logon and last password change informations.\"},\"name\":\"text - 0\"}]},\"name\":\"group - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"DefaultGroup\"},\"name\":\"group - 4\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Let start with Least Privileges with RBAC\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Workbook goals\\r\\nThe goals of this workbook is to show you the current RBAC delegation\\r\\n\\r\\n\\r\\nThis workbook will display :\\r\\n\\r\\n - NonStandrd RBAC delegation\\r\\n\\r\\n - Exchange default group content\\r\\n\\r\\n - Analysis of the actions performed by Organization Management members to remove them from the groups\\r\\n\\r\\n----\\r\\n\\r\\n## Tabs\\r\\n\\r\\n### Current RBAC Delegation\\r\\n\\r\\nThis tab will show all the nonstandard RBAC delegation.\\r\\n\\r\\n**Most of the time RBAC are done and forgotten... This tab will provide a clear statut of the delegation and help with the remediation.**\\r\\n\\r\\nBy nonstandard, it means that the current delegation are compared to the delegation from Exchange 2019 CU11.\\r\\n\\r\\nNonstandard delegation for standard groups like Organization Management will also be displayed.\\r\\n\\r\\nDetail information for found will be displayed : Last logon, last password changed...\\r\\n\\r\\n### Default Group content\\r\\n\\r\\nThis tab will show the number of members for default Exchange groups and their content.\\r\\n\\r\\nMost of the time, the content of common Exchange groups but Exchange is shipped with many groups that have very high privileges and its interesting to see that they are not empty as expected.\"},\"name\":\"text - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"start\"},\"name\":\"group - 6\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Role details\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"List of Custom Roles\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section shows the Custom management roles that exist in your environnment and the name of the parent's role\"},\"name\":\"text - 0\"},{\"type\":1,\"content\":{\"json\":\"Liste of existing Custom roles\"},\"customWidth\":\"50\",\"name\":\"text - 5\"},{\"type\":1,\"content\":{\"json\":\"List of Custom with a Management Role Assignement (associated with a group or a user). Display the target account and scope if set\"},\"customWidth\":\"50\",\"name\":\"text - 6\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| extend WhenCreated = WhenCreated\\r\\n| project Identity, ParentRole, WhenCreated, WhenChanged\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n//| extend Scope = tostring(CmdletResultValue.RecipientWriteScope)\\r\\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n//| project Role = tostring(CmdletResultValue.Role.Name)\\r\\n| distinct Role,RoleAssigneeName,Scope\\r\\n| project Role,RoleAssigneeName,Scope\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| project Role = tostring(CmdletResultValue.Name));\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend RoleAssigneeName = tostring(CmdletResultValue.RoleAssigneeName)\\r\\n| extend Scope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| project Role = tostring(CmdletResultValue.Role.Name), Scope, RoleAssigneeName\\r\\n| join kind=fullouter (MRcustomRoles) on Role\\r\\n| project Role = Role1, Scope, RoleAssigneeName,Comment = iff(Role == \\\"\\\", \\\"⚠️ No existing delegation for this role\\\", \\\"✅ This role is delegated with a Management Role Assignment\\\")\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let MRcustomRoles = (ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n | project Role = tostring(CmdletResultValue.Name));\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRA\\\", SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| project Role = tostring(CmdletResultValue.Role.Name)\\r\\n| join kind=fullouter (MRcustomRoles) on Role\\r\\n| summarize acount = count() by iff( Role==\\\"\\\",\\\"Number of non assigned roles\\\", Role)\",\"size\":0,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"50\",\"name\":\"query - 3\"}]},\"name\":\"List of Custom Roles\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Custom Roles delegation on group\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section shows delegation associated with the Custom Roles\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"ExchangeConfiguration(SpecificSectionList=\\\"MRA\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where CmdletResultValue.Role.Parent.Parent == \\\"Roles\\\"\\r\\n| where CmdletResultValue.RoleAssignmentDelegationType <> 6\\r\\n| extend Role = tostring(CmdletResultValue.Role.Name)\\r\\n| extend RoleAssigneeType = case(CmdletResultValue.RoleAssigneeType== \\\"0\\\" or CmdletResultValue.RoleAssigneeType== \\\"2\\\" , \\\"User\\\", CmdletResultValue.RoleAssigneeType== \\\"10\\\",\\\"Group\\\",\\\"LinkedGroup\\\")\\r\\n| extend CustomRecipientWriteScope = tostring(CmdletResultValue.CustomRecipientWriteScope.Name)\\r\\n| extend CustomConfigWriteScope = tostring(CmdletResultValue.CustomConfigWriteScope.Name)\\r\\n| extend RecipientWriteScope = case(CmdletResultValue.RecipientWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.RecipientWriteScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientWriteScope==\\\"3\\\",\\\"MyGAL\\\", CmdletResultValue.RecipientWriteScope==\\\"4\\\",\\\"Self\\\",CmdletResultValue.RecipientWriteScope==\\\"7\\\", \\\"CustomRecipientScope\\\",CmdletResultValue.RecipientWriteScope==\\\"8\\\",\\\"MyDistributionGroups\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigWriteScope = case(CmdletResultValue.ConfigWriteScope==\\\"0\\\",\\\"None\\\",CmdletResultValue.ConfigWriteScope==\\\"7\\\",\\\"CustomConfigScope\\\",CmdletResultValue.ConfigWriteScope==\\\"10\\\",\\\"OrganizationConfig\\\",\\\"NotApplicable\\\")\\r\\n| extend ConfigReadScope = iff(CmdletResultValue.ConfigReadScope == \\\"0\\\" , \\\"None\\\", \\\"OrganizationConfig\\\")\\r\\n| extend RecipientReadScope = case(CmdletResultValue.RecipientReadScope==\\\"2\\\",\\\"Organization\\\",CmdletResultValue.RecipientReadScope==\\\"3\\\",\\\"MyGAL\\\",CmdletResultValue.RecipientReadScope==\\\"4\\\",\\\"Self\\\",\\\"NotApplicable\\\")\\r\\n| extend ManagementRoleAssignement = tostring(CmdletResultValue.Name)\\r\\n| extend RoleAssignmentDelegationType = iff(CmdletResultValue.RoleAssignmentDelegationType ==\\\"6\\\" , \\\"Delegating\\\", \\\"Regular\\\") \\r\\n| extend RoleAssigneeName = iff( RoleAssigneeType == \\\"User\\\", strcat(\\\"🧑🦰 \\\",tostring(CmdletResultValue.RoleAssigneeName)), strcat(\\\"👪 \\\", tostring(CmdletResultValue.RoleAssigneeName)) )\\r\\n| project RoleAssigneeName, Role, RoleAssigneeType, CustomRecipientWriteScope, CustomConfigWriteScope, RecipientWriteScope, ConfigWriteScope, ConfigReadScope, RecipientReadScope, ManagementRoleAssignement, RoleAssignmentDelegationType, WhenCreated, WhenChanged\\r\\n\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 1\"}]},\"name\":\"group - 2\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Details for Custom Roles Cmdlets \",\"items\":[{\"type\":1,\"content\":{\"json\":\"This section displays for the chosen custom management roles all Cmdlets and their parameters associated with this custom role.\\r\\nRemember that for a cmdlet, some parameters can be removed.\"},\"name\":\"text - 0\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"07c8ac83-371d-4702-ab66-72aeb2a20053\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CustomRole\",\"type\":2,\"isRequired\":true,\"query\":\" ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| project Identity\",\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by Role;\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = CmdletResultValue.Name\\r\\n| extend Parameters = CmdletResultValue.Parameters\\r\\n| project CmdletName,Parameters,ParentRole = SelectedRole\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Parameters\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"100ch\"}}],\"rowLimit\":10000,\"filter\":true}},\"customWidth\":\"70\",\"name\":\"query - 1\",\"styleSettings\":{\"showBorder\":true}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,CmdletCount:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | summarize CmdletCount=count() by Role;\\r\\nlet MRCustomD = ExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend Role = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = CmdletResultValue.Name\\r\\n| extend ParentRole = tostring(SelectedRole)\\r\\n| summarize CmdletCount = count() by Role, ParentRole\\r\\n| project Role,CmdletCount;\\r\\nunion MRCustomD, DefMRA\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"30\",\"name\":\"query - 3\"},{\"type\":1,\"content\":{\"json\":\"List of Cmdlets ( Get- command have been removed to clarify the information) with :\\r\\nCustomParamCount : number of parameters for the Cmdlet in the custom role\\r\\nDefaultCmdletNumberofParam : number of parameters for the Cmdlet in the default role\\r\\n\"},\"name\":\"text - 5\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let SelectedRole = toscalar ( ExchangeConfiguration(SpecificSectionList=\\\"MRCustom\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| extend Identity = CmdletResultValue.Name\\r\\n| where Identity contains \\\"{CustomRole}\\\"\\r\\n| extend ParentRole = CmdletResultValue.Parent.Name\\r\\n| project ParentRole);\\r\\nlet DefMRA = externaldata (Role:string,Name:string,Parameters:string )[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/RBACRoleCmdlet.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| where Role == SelectedRole | mv-expand split(todynamic(Parameters),\\\";\\\")| summarize ParamCount = count() by Name;\\r\\nExchangeConfiguration(SpecificSectionList=\\\"MRCustomDetails\\\",SpecificConfigurationDate=\\\"{DateOfConfiguration:value}\\\",SpecificConfigurationEnv={EnvironmentList},Target = \\\"On-Premises\\\")\\r\\n| where (replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")) contains \\\"{CustomRole}\\\"\\r\\n| extend CustomRoleName = replace_string(replace_string(tostring(split(CmdletResultValue.Role.DistinguishedName,\\\",\\\",0)),\\\"[\\\\\\\"CN=\\\",\\\"\\\"),\\\"\\\\\\\"]\\\",\\\"\\\")\\r\\n| extend CmdletName = tostring(CmdletResultValue.Name)\\r\\n| where CmdletName !contains \\\"get-\\\"\\r\\n| extend Parameters = CmdletResultValue.Parameters\\r\\n| extend ParentRole = tostring(SelectedRole)\\r\\n| mv-expand split(todynamic(Parameters),\\\";\\\")\\r\\n| summarize ParamCount = count() by CmdletName, ParentRole\\r\\n| join (DefMRA) on $left.CmdletName == $right.Name\\r\\n| project CmdletName, CustomParamCount = ParamCount , DefaultCmdletNumberofParam = ParamCount1\",\"size\":1,\"showAnalytics\":true,\"timeContext\":{\"durationMs\":86400000},\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"DefaultCmdletNumberofParam\",\"sortOrder\":1}]},\"sortBy\":[{\"itemKey\":\"DefaultCmdletNumberofParam\",\"sortOrder\":1}]},\"name\":\"query - 4\",\"styleSettings\":{\"showBorder\":true}}]},\"name\":\"Details for Custom Roles Cmdlets \"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"CustomRole\"},\"name\":\"Custom Role\",\"styleSettings\":{\"showBorder\":true}}],\"fromTemplateId\":\"sentinel-MicrosoftExchangeLeastPrivilegewithRBAC\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -2527,7 +2728,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Search AdminAuditLog Workbook with template version 3.0.1",
+ "description": "Microsoft Exchange Search AdminAuditLog Workbook with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion2')]",
@@ -2618,7 +2819,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Admin Activity Workbook with template version 3.0.1",
+ "description": "Microsoft Exchange Admin Activity Workbook with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion3')]",
@@ -2636,7 +2837,7 @@
},
"properties": {
"displayName": "[parameters('workbook3-name')]",
- "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Microsoft Exchange Admin Activity\\r\\n\\r\\nThis workbook helps you visualize what is happening in your Exchange environment.\\r\\nResults removed :\\r\\n\\t- All Test-* and Set-AdServerSetting Cmdlets\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"3792117c-d924-4ec7-a327-1e8d5e9f291a\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"value\":{\"durationMs\":2592000000}},{\"id\":\"743317e2-ebcf-4958-861d-4ff97fc7cce1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EnvironmentList\",\"label\":\"Environment\",\"type\":2,\"isRequired\":true,\"query\":\"ExchangeAdminAuditLogs | where TimeGenerated {TimeRange}\\r\\n | summarize by ESIEnvironment\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"8ac96eb3-918b-4a36-bcc4-df50d8f46175\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Help\",\"label\":\"Show Help\",\"type\":10,\"isRequired\":true,\"query\":\"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"[\\\\r\\\\n { \\\\\\\"value\\\\\\\": \\\\\\\"Yes\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"Yes\\\\\\\"},\\\\r\\\\n {\\\\\\\"value\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"label\\\\\\\": \\\\\\\"No\\\\\\\", \\\\\\\"selected\\\\\\\":true }\\\\r\\\\n]\\\\r\\\\n\\\"}\",\"timeContext\":{\"durationMs\":2592000000},\"queryType\":8}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"TimeRange\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"34188faf-7a02-4697-9b36-2afa986afc0f\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Cmdlet Analysis\",\"subTarget\":\"Cmdlet\",\"postText\":\"t\",\"style\":\"link\",\"icon\":\"3\",\"linkIsContextBlade\":true},{\"id\":\"be02c735-6150-4b6e-a386-b2b023e754e5\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Active Directory Modifications\",\"subTarget\":\"AD\",\"style\":\"link\"}]},\"name\":\"links - 1\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Cmdlet summary\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This tab parses the events from Admin Audit logs :\\r\\n\\r\\n- list of cmdlets\\r\\n- filter on a VIP and/or Sensitive objects (based on Watchlist \\\"Exchange VIP\\\" and \\\" Monitored Exchange Cmdlets\\\")\\r\\n- anomalies detections are based on the KQL function series_decompose_anomalies\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"CmdletGroupHelp\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"5a942eba-c991-4b84-9a94-c153bca86e12\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"VIPOnly\",\"label\":\"Show VIP Only\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"True\\\", \\\"label\\\": \\\"Yes\\\"},\\r\\n { \\\"value\\\": \\\"True,False\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"83befa26-eee0-49ab-9785-72653943bc6b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"SensitiveOnly\",\"label\":\"Sensitive CmdLet Only\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"True\\\", \\\"label\\\": \\\"Yes\\\" },\\r\\n { \\\"value\\\": \\\"True,False\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\\r\\n\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"a6046096-a14b-4023-af1a-ab47f4e2dff1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CallerFilter1\",\"label\":\"Caller\",\"type\":2,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"ExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| distinct Caller\",\"isHiddenWhenLocked\":true,\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"4c896211-577a-4390-b85a-6f9ac18f2824\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CmdletFilter1\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| distinct CmdletName\",\"isHiddenWhenLocked\":true,\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 0\"},{\"type\":1,\"content\":{\"json\":\"This section show all the Cmdlets executed in the selected time range. Possible filters are: \\r\\n- **VIP Only selected** Cmdlets used against VIP objects (based on the \\\"Exchange VIP\\\" watchlist)\\r\\n- **Sensitive Cmdlets** Cmdlets considered as Sensitive (based on the \\\"Monitored Exchange Cmdlets\\\" watchlist)\\r\\n\\r\\nThese informations can be useful to detect unexpected behaviors or to determine what are the action performed by the accounts (ie. service accounts).\\r\\n\\r\\nℹ️ It is recommended to delegated only the necessary privileges to an account.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"CmdtListHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize count() by CmdletName\\r\\n| sort by count_\",\"size\":2,\"showAnalytics\":true,\"title\":\"List of all executed cmdlets during the last 90 days (based on Sentinel retention)\",\"exportFieldName\":\"CmdletName\",\"exportParameterName\":\"CmdletFilter\",\"exportDefaultValue\":\"\\\"\\\"\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"CmdletName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"CmdletName\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"createOtherGroup\":20}},\"customWidth\":\"45\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n | where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize count() by CmdletName\\r\\n| join kind=leftouter ( ExchangeAdminAuditLogs \\r\\n | where TimeGenerated > ago(30d)\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | where Status == \\\"Success\\\"\\r\\n //| where TargetObject !contains \\\"Health\\\"\\r\\n | where CmdletName !in (ExcludedCmdlet)\\r\\n | where IsVIP in ({VIPOnly})\\r\\n | where IsSensitive in ({SensitiveOnly})\\r\\n | make-series Count=count() on TimeGenerated from ago(30d) to now() step 1d by CmdletName\\r\\n | extend Anomalies=series_decompose_anomalies(Count)\\r\\n) on CmdletName\\r\\n| project CmdletName, Total=count_, Count, Anomalies\\r\\n| sort by Total\",\"size\":2,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"CmdletName\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"31.5ch\"}},{\"columnMatch\":\"Total\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"9.3ch\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"330px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":9,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"330px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"rowLimit\":10000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"CmdletName\",\"label\":\"Cmdlet\"},{\"columnId\":\"Count\",\"label\":\"Count for the last 30 days\"}]}},\"customWidth\":\"55\",\"name\":\"CmdletTrends\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize Total = count() by Caller\\r\\n| join kind=leftouter ( ExchangeAdminAuditLogs \\r\\n | where TimeGenerated > ago(30d)\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | where Status == \\\"Success\\\"\\r\\n | where IsVIP in ({VIPOnly})\\r\\n | where IsSensitive in ({SensitiveOnly})\\r\\n | make-series Count=count() on TimeGenerated from ago(30d) to now() step 1d by Caller\\r\\n | extend Anomalies=series_decompose_anomalies(Count)\\r\\n) on Caller\\r\\n| project Caller, Total, Count, Anomalies\\r\\n| sort by Total desc\",\"size\":1,\"showAnalytics\":true,\"exportFieldName\":\"Caller\",\"exportParameterName\":\"CallerFilter\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Caller\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"70ch\"}},{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"125px\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"300px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":10,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"300px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"$gen_bar_Total_1\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Count\",\"label\":\"Count for the last 30 days\"}]},\"sortBy\":[{\"itemKey\":\"$gen_bar_Total_1\",\"sortOrder\":2}],\"chartSettings\":{\"createOtherGroup\":20}},\"name\":\"query - 4\"},{\"type\":1,\"content\":{\"json\":\"## List of Cmdlets\\r\\nYou can pick a tile in the list of all executed cmdlets above to filter the list.\\r\\n\\r\\nBy default all accounts found in the log are displayed.\\r\\n\\r\\nSelect an account in the previous section, to display on Cmdlets launched by this user\\r\\n\\r\\n> **Legend** \\r\\n> \\r\\n> 👑 VIP user \\r\\n> 💥 Sensitive action\\r\\n\\r\\nIf needed, select an item in the dropdownlist. Dropdownlist are independent.\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"008273d1-a013-4d86-9e23-499e5175a85e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CallerFilter\",\"label\":\"Caller\",\"type\":2,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct Caller\\r\\n| sort by Caller asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"21bd4e45-65ca-4b9b-a19c-177d6b37d807\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TargetObjectFilter\",\"label\":\"Target Object\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct TargetObject\\r\\n| sort by TargetObject asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"9e93d5c3-0fcb-4ece-b2a0-fc3ff44a0b04\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CmdletFilter\",\"label\":\"Cmdlet Filter\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct CmdletName\\r\\n| sort by CmdletName asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nlet CallerF = toscalar(split(\\\"{CallerFilter}\\\",\\\",\\\"));\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n//| parse \\\"{CallerFilter}\\\" with \\\",\\\" CallerF\\r\\n//| where Caller contains {CallerFilter} and TargetObject contains \\\"{TargetObjectFilter}\\\" and CmdletName contains \\\"{CmdletFilter}\\\"\\r\\n| where (Caller in ({CallerFilter}) or Caller == \\\"ALL\\\") and TargetObject contains \\\"{TargetObjectFilter}\\\" and CmdletName contains \\\"{CmdletFilter}\\\"\\r\\n| extend ActualCmdLet = strcat( CmdletName, \\\" \\\", CmdletParameters)\\r\\n| extend TargetObject = iif(IsVIP == true and TargetObject !=\\\"\\\" , strcat(\\\"👑 \\\",TargetObject), TargetObject )\\r\\n| extend ActualCmdLet = iif(IsSensitive == true and TargetObject !=\\\"\\\", strcat(\\\"💥 \\\",ActualCmdLet), ActualCmdLet )\\r\\n| project TimeGenerated, Caller, TargetObject, ActualCmdLet\\r\\n| sort by TimeGenerated desc\",\"size\":2,\"showAnalytics\":true,\"title\":\"History\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"ActualCmdLet\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"120ch\"}}],\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Cmdlet\"},\"name\":\"Cmdlet Group\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## VIP modifications\\r\\n\\r\\nThis view allows you to quickly see what is happening on VIP accounts.\\r\\n**This tab needs Option 2 or 3**\"},\"name\":\"text - 3\"},{\"type\":1,\"content\":{\"json\":\"This section displays the modifications on VIP Active Directory objects for the selected Time Range.\\r\\n\\r\\nIt is based on the security events 4725, 4726, 4738, 4740 and 4767.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"HelpTotalModifVIP\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ImportantADActivities = dynamic([4725,4726,4738,4740,4767]);\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet VIPUsers = _GetWatchlist('ExchangeVIP') | summarize make_list(tostring(sAMAccountName)) ;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where EventID in (ImportantADActivities)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where SubjectUserName in (VIPUsers) or TargetUserName in (VIPUsers)\\r\\n| extend Activity = tostring(split(Activity,\\\"- \\\")[1])\\r\\n| summarize Count=count() by Activity\",\"size\":3,\"noDataMessage\":\"Sections related to Option 2 or 3\",\"noDataMessageStyle\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Activity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"showBorder\":false,\"size\":\"auto\"}},\"name\":\"QueryVIPModif\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ImportantADActivities = dynamic([4725,4726,4738,4740,4767]);\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet VIPUsers = _GetWatchlist('ExchangeVIP') | summarize make_list(tostring(sAMAccountName)) ;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where EventID in (ImportantADActivities)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where SubjectUserName in (VIPUsers) or TargetUserName in (VIPUsers)\\r\\n| extend Activity = split(Activity,\\\"- \\\")[1]\\r\\n| extend SubjectUserName = iif( SubjectUserName in (VIPUsers), strcat(SubjectUserName, \\\" 👑\\\"), SubjectUserName)\\r\\n| extend SubjectUserName = iif( SubjectUserName hassuffix \\\"$\\\", strcat(\\\"💻 \\\", SubjectUserName), strcat(\\\"👨💼 \\\", SubjectUserName))\\r\\n| extend TargetUserName = iif( TargetUserName in (VIPUsers), strcat(TargetUserName, \\\" 👑\\\"), TargetUserName)\\r\\n| project TimeGenerated, Activity, SubjectUserName,TargetUserName\\r\\n| order by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"noDataMessage\":\"Sections related to Option 2 or 3\",\"noDataMessageStyle\":2,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Activity\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"75ch\"}}],\"rowLimit\":10000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"TimeGenerated\",\"label\":\"Time\"},{\"columnId\":\"SubjectUserName\",\"label\":\"Operator\"},{\"columnId\":\"TargetUserName\",\"label\":\"Target\"}]}},\"name\":\"query - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"AD\"},\"name\":\"AdModifSummary\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Server activity summary\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"04d09365-30ba-4bb1-9e76-06fc7b97ea71\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ComputerFilter\",\"type\":1,\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":1,\"content\":{\"json\":\"This tab parses the events from the System and Security event logs of the Exchange servers. You can use it for the following activities:\\r\\n\\r\\n- Track the Exchange services status (based on the event 7036 and on the watchlist \\\"Exchange Services Monitoring\\\")\\r\\n- Track logons on the servers (this excludes network logons)\\r\\n- Track creations, modifications and delegation actions of local user accounts\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"ServersHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize count() by Computer\",\"size\":4,\"title\":\"Security Events per Exchange Servers\",\"exportFieldName\":\"Computer\",\"exportParameterName\":\"ComputerFilter\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Computer\"},\"subtitleContent\":{\"columnMatch\":\"count_\",\"formatter\":4,\"formatOptions\":{\"min\":2000,\"palette\":\"blue\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},\"showBorder\":true,\"sortCriteriaField\":\"Computer\",\"sortOrderField\":1,\"size\":\"auto\"}},\"customWidth\":\"100\",\"name\":\"ExServersListTiles\"},{\"type\":1,\"content\":{\"json\":\"## List of monitored services changes\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet ExchangeServices = _GetWatchlist('ExchangeServicesMonitoring') | summarize make_list(DisplayName);\\r\\nEvent \\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| where EventID == 7036\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where WindowsService_CF in (ExchangeServices)\\r\\n| extend ServiceNewState_CF = iif( ServiceNewState_CF == \\\"stopped\\\", strcat(\\\"🔴 \\\",ServiceNewState_CF), strcat(\\\"🟢 \\\",ServiceNewState_CF))\\r\\n| project TimeGenerated, Computer, WindowsService_CF, ServiceNewState_CF\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"showExpandCollapseGrid\":true,\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"WindowsService_CF\",\"label\":\"Service\"},{\"columnId\":\"ServiceNewState_CF\",\"label\":\"State\"}]}},\"name\":\"ListServicesState\"},{\"type\":1,\"content\":{\"json\":\"Details of logon on the Exchange servers (or the selected server from the tiles above).\\r\\n\\r\\nThis parses the security event 4624 on Exchange servers.\\r\\n\\r\\nThis uses the following filters:\\r\\n- LogonType <> 3 (Network)\\r\\n- AccountType <> \\\"Machine\\\"\\r\\n- TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n- Account !hasprefix \\\"Window Manager\\\"\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"ServerLogonHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID == 4624\\r\\n| where LogonType <> 3\\r\\n| where AccountType <> \\\"Machine\\\" \\r\\n| where TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n| where Account !hasprefix \\\"Window Manager\\\"\\r\\n| summarize count() by LogonTypeName\",\"size\":0,\"title\":\"Logon Type statistics\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"DetailsLogonEventsPie\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID == 4624\\r\\n| where LogonType <> 3\\r\\n| where AccountType <> \\\"Machine\\\" \\r\\n| where TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n| where Account !hasprefix \\\"Window Manager\\\"\\r\\n| project TimeGenerated, Computer, Account, IpAddress, LogonTypeName\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"75\",\"name\":\"DetailsLogonEvents\"},{\"type\":1,\"content\":{\"json\":\"Details of local account activities on the Exchange servers (or the selected server from the tiles above). It parses the following security events:\\r\\n- 4720 Account creation\\r\\n- 4724 Password reset\\r\\n- 4722 Account enabled\\r\\n- 4725 Account disabled\\r\\n- 4726 Account deleted\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"LocalAccountActivityHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID in (4720,4724,4722,4725,4726)\\r\\n| extend Action = case(EventID == 4720, \\\"🆕 Account creation\\\", EventID == 4724, \\\"🔄 Password reset\\\", EventID == 4722, \\\"🟢 Account enabled\\\", EventID == 4725, \\\"🔴 Account disabled\\\",\\\"❌ Account deleted\\\")\\r\\n| summarize count() by Action\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"List of local account activities\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"LocalAccountActivity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID in (4720,4724,4722,4725,4726)\\r\\n| extend Action = case(EventID == 4720, \\\"🆕 Account creation\\\", EventID == 4724, \\\"🔄 Password reset\\\", EventID == 4722, \\\"🟢 Account enabled\\\", EventID == 4725, \\\"🔴 Account disabled\\\",\\\"❌ Account deleted\\\")\\r\\n| project TimeGenerated, Computer, Action, SubjectAccount, TargetAccount\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"75\",\"name\":\"LocalActivityGrid\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Server\"},\"name\":\"ServerSummaryGroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Mail flow\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This is an experimental tab to search for information from the Message Tracking logs.\",\"style\":\"warning\"},\"name\":\"WarningMessagetracking\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"MessageTracking\\r\\n| where TimeGenerated > ago(7d)\\r\\n| summarize Max = max(TimeGenerated) by Computer\\r\\n| extend Age = strcat( datetime_diff( \\\"Hour\\\", now(), Max) , \\\" hours ago\\\")\",\"size\":4,\"noDataMessage\":\"No message tracking data for more than 7 days\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Computer\"},\"leftContent\":{\"columnMatch\":\"Max\"},\"rightContent\":{\"columnMatch\":\"Age\"},\"showBorder\":true,\"size\":\"auto\"}},\"name\":\"query - 1\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"69b3412d-8984-42a7-8b5a-c238462097b7\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Filter\",\"type\":1,\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"MessageTracking\\r\\n| search \\\"*{Filter}\\\"\\r\\n| project-away $table\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"noDataMessage\":\"No message tracking information found.\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Mail\"},\"name\":\"MailFlowGroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Data Statistics\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## 90-day statistics\"},\"name\":\"text - 4\"},{\"type\":1,\"content\":{\"json\":\"This tabs show the data ingestions of logs used to monitor Exchange Servers activities.\\r\\n\\r\\nNote that the Event table contains all Windows event log events but the security event logs.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"showPin\":false,\"name\":\"StatsHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nEvent \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (Event\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"Event table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"EventTable\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nW3CIISLog \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (W3CIISLog\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"W3CIISLog table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"IISLogs\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (SecurityEvent\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"SecurityEvent table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"SecurityEventTable\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let EHP = union isfuzzy=true withsource=TableName ExchangeHttpProxy, blabla*, Event | where TableName != \\\"Event\\\";\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nEHP \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (EHP\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"ExchangeHttpProxy table\",\"noDataMessage\":\"No Exchange HTTP Proxy Data\",\"noDataMessageStyle\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"ExchangeHttpProxyTable\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Stats\"},\"name\":\"group - 7\"}],\"fromTemplateId\":\"sentinel-MicrosoftExchangeSecurityMonitoring\",\"$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 Admin Activity\\r\\n\\r\\nThis workbook helps you visualize what is happening in your Exchange environment.\\r\\nResults removed :\\r\\n\\t- All Test-* and Set-AdServerSetting Cmdlets\"},\"name\":\"text - 2\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"3792117c-d924-4ec7-a327-1e8d5e9f291a\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeRange\",\"label\":\"Time Range\",\"type\":4,\"isRequired\":true,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"value\":{\"durationMs\":2592000000}},{\"id\":\"743317e2-ebcf-4958-861d-4ff97fc7cce1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"EnvironmentList\",\"label\":\"Environment\",\"type\":2,\"isRequired\":true,\"query\":\"ExchangeAdminAuditLogs | where TimeGenerated {TimeRange}\\r\\n | summarize by ESIEnvironment\",\"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\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"links\":[{\"id\":\"34188faf-7a02-4697-9b36-2afa986afc0f\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Cmdlet Analysis\",\"subTarget\":\"Cmdlet\",\"postText\":\"t\",\"style\":\"link\",\"icon\":\"3\",\"linkIsContextBlade\":true},{\"id\":\"be02c735-6150-4b6e-a386-b2b023e754e5\",\"cellValue\":\"selected\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Active Directory Modifications\",\"subTarget\":\"AD\",\"style\":\"link\"}]},\"name\":\"links - 1\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Cmdlet summary\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This tab parses the events from Admin Audit logs :\\r\\n\\r\\n- list of cmdlets\\r\\n- filter on a VIP and/or Sensitive objects (based on Watchlist \\\"Exchange VIP\\\" and \\\" Monitored Exchange Cmdlets\\\")\\r\\n- anomalies detections are based on the KQL function series_decompose_anomalies\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"CmdletGroupHelp\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"5a942eba-c991-4b84-9a94-c153bca86e12\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"VIPOnly\",\"label\":\"Show VIP Only\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"True\\\", \\\"label\\\": \\\"Yes\\\"},\\r\\n { \\\"value\\\": \\\"True,False\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"83befa26-eee0-49ab-9785-72653943bc6b\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"SensitiveOnly\",\"label\":\"Sensitive CmdLet Only\",\"type\":10,\"isRequired\":true,\"typeSettings\":{\"showDefault\":false},\"jsonData\":\"[\\r\\n { \\\"value\\\": \\\"True\\\", \\\"label\\\": \\\"Yes\\\" },\\r\\n { \\\"value\\\": \\\"True,False\\\", \\\"label\\\": \\\"No\\\", \\\"selected\\\":true }\\r\\n]\\r\\n\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"a6046096-a14b-4023-af1a-ab47f4e2dff1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CallerFilter1\",\"label\":\"Caller\",\"type\":2,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"ExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| distinct Caller\",\"isHiddenWhenLocked\":true,\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"4c896211-577a-4390-b85a-6f9ac18f2824\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CmdletFilter1\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| distinct CmdletName\",\"isHiddenWhenLocked\":true,\"typeSettings\":{\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"above\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 0\"},{\"type\":1,\"content\":{\"json\":\"This section show all the Cmdlets executed in the selected time range. Possible filters are: \\r\\n- **VIP Only selected** Cmdlets used against VIP objects (based on the \\\"Exchange VIP\\\" watchlist)\\r\\n- **Sensitive Cmdlets** Cmdlets considered as Sensitive (based on the \\\"Monitored Exchange Cmdlets\\\" watchlist)\\r\\n\\r\\nThese informations can be useful to detect unexpected behaviors or to determine what are the action performed by the accounts (ie. service accounts).\\r\\n\\r\\nℹ️ It is recommended to delegated only the necessary privileges to an account.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"CmdtListHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize count() by CmdletName\\r\\n| sort by count_\",\"size\":2,\"showAnalytics\":true,\"title\":\"List of all executed cmdlets during the last 90 days (based on Sentinel retention)\",\"exportFieldName\":\"CmdletName\",\"exportParameterName\":\"CmdletFilter\",\"exportDefaultValue\":\"\\\"\\\"\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"showBorder\":false,\"titleContent\":{\"columnMatch\":\"CmdletName\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"count_\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"CmdletName\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"count_\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}},\"chartSettings\":{\"createOtherGroup\":20}},\"customWidth\":\"45\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n | where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize count() by CmdletName\\r\\n| join kind=leftouter ( ExchangeAdminAuditLogs \\r\\n | where TimeGenerated > ago(30d)\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | where Status == \\\"Success\\\"\\r\\n //| where TargetObject !contains \\\"Health\\\"\\r\\n | where CmdletName !in (ExcludedCmdlet)\\r\\n | where IsVIP in ({VIPOnly})\\r\\n | where IsSensitive in ({SensitiveOnly})\\r\\n | make-series Count=count() on TimeGenerated from ago(30d) to now() step 1d by CmdletName\\r\\n | extend Anomalies=series_decompose_anomalies(Count)\\r\\n) on CmdletName\\r\\n| project CmdletName, Total=count_, Count, Anomalies\\r\\n| sort by Total\",\"size\":2,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"CmdletName\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"31.5ch\"}},{\"columnMatch\":\"Total\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"9.3ch\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"330px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":9,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"330px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"rowLimit\":10000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"CmdletName\",\"label\":\"Cmdlet\"},{\"columnId\":\"Count\",\"label\":\"Count for the last 30 days\"}]}},\"customWidth\":\"55\",\"name\":\"CmdletTrends\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| summarize Total = count() by Caller\\r\\n| join kind=leftouter ( ExchangeAdminAuditLogs \\r\\n | where TimeGenerated > ago(30d)\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | where Status == \\\"Success\\\"\\r\\n | where IsVIP in ({VIPOnly})\\r\\n | where IsSensitive in ({SensitiveOnly})\\r\\n | make-series Count=count() on TimeGenerated from ago(30d) to now() step 1d by Caller\\r\\n | extend Anomalies=series_decompose_anomalies(Count)\\r\\n) on Caller\\r\\n| project Caller, Total, Count, Anomalies\\r\\n| sort by Total desc\",\"size\":1,\"showAnalytics\":true,\"exportFieldName\":\"Caller\",\"exportParameterName\":\"CallerFilter\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Caller\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"70ch\"}},{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"125px\"}},{\"columnMatch\":\"Count\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"300px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"Anomalies\",\"formatter\":10,\"formatOptions\":{\"palette\":\"redBright\",\"customColumnWidthSetting\":\"300px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"rowLimit\":10000,\"filter\":true,\"sortBy\":[{\"itemKey\":\"$gen_bar_Total_1\",\"sortOrder\":2}],\"labelSettings\":[{\"columnId\":\"Count\",\"label\":\"Count for the last 30 days\"}]},\"sortBy\":[{\"itemKey\":\"$gen_bar_Total_1\",\"sortOrder\":2}],\"chartSettings\":{\"createOtherGroup\":20}},\"name\":\"query - 4\"},{\"type\":1,\"content\":{\"json\":\"## List of Cmdlets\\r\\nYou can pick a tile in the list of all executed cmdlets above to filter the list.\\r\\n\\r\\nBy default all accounts found in the log are displayed.\\r\\n\\r\\nSelect an account in the previous section, to display on Cmdlets launched by this user\\r\\n\\r\\n> **Legend** \\r\\n> \\r\\n> 👑 VIP user \\r\\n> 💥 Sensitive action\\r\\n\\r\\nIf needed, select an item in the dropdownlist. Dropdownlist are independent.\"},\"name\":\"text - 3\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"008273d1-a013-4d86-9e23-499e5175a85e\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CallerFilter\",\"label\":\"Caller\",\"type\":2,\"multiSelect\":true,\"quote\":\"'\",\"delimiter\":\",\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct Caller\\r\\n| sort by Caller asc\",\"typeSettings\":{\"additionalResourceOptions\":[\"value::all\"],\"showDefault\":false},\"defaultValue\":\"value::all\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"value\":[\"value::all\"]},{\"id\":\"21bd4e45-65ca-4b9b-a19c-177d6b37d807\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TargetObjectFilter\",\"label\":\"Target Object\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct TargetObject\\r\\n| sort by TargetObject asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},{\"id\":\"9e93d5c3-0fcb-4ece-b2a0-fc3ff44a0b04\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"CmdletFilter\",\"label\":\"Cmdlet Filter\",\"type\":2,\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n| distinct CmdletName\\r\\n| sort by CmdletName asc\",\"typeSettings\":{\"showDefault\":false},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 8\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ExcludedCmdlet = externaldata (Cmdlet:string)[h\\\"https://raw.githubusercontent.com/nlepagnez/ESI-PublicContent/main/Operations/Watchlists/ExcludedCmdletWatchlist.csv\\\"]with(format=\\\"csv\\\",ignoreFirstRecord=true)| project Cmdlet;\\r\\nlet CallerF = toscalar(split(\\\"{CallerFilter}\\\",\\\",\\\"));\\r\\nExchangeAdminAuditLogs\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Status == \\\"Success\\\"\\r\\n//| where TargetObject !contains \\\"Health\\\"\\r\\n| where CmdletName !in (ExcludedCmdlet)\\r\\n| where IsVIP in ({VIPOnly})\\r\\n| where IsSensitive in ({SensitiveOnly})\\r\\n//| parse \\\"{CallerFilter}\\\" with \\\",\\\" CallerF\\r\\n//| where Caller contains {CallerFilter} and TargetObject contains \\\"{TargetObjectFilter}\\\" and CmdletName contains \\\"{CmdletFilter}\\\"\\r\\n| where (Caller in ({CallerFilter}) or Caller == \\\"ALL\\\") and TargetObject contains \\\"{TargetObjectFilter}\\\" and CmdletName contains \\\"{CmdletFilter}\\\"\\r\\n| extend ActualCmdLet = strcat( CmdletName, \\\" \\\", CmdletParameters)\\r\\n| extend TargetObject = iif(IsVIP == true and TargetObject !=\\\"\\\" , strcat(\\\"👑 \\\",TargetObject), TargetObject )\\r\\n| extend ActualCmdLet = iif(IsSensitive == true and TargetObject !=\\\"\\\", strcat(\\\"💥 \\\",ActualCmdLet), ActualCmdLet )\\r\\n| project TimeGenerated, Caller, TargetObject, ActualCmdLet\\r\\n| sort by TimeGenerated desc\",\"size\":2,\"showAnalytics\":true,\"title\":\"History\",\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"ActualCmdLet\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"120ch\"}}],\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 5\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Cmdlet\"},\"name\":\"Cmdlet Group\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## VIP modifications\\r\\n\\r\\nThis view allows you to quickly see what is happening on VIP accounts.\\r\\n**This tab needs Option 2 or 3**\"},\"name\":\"text - 3\"},{\"type\":1,\"content\":{\"json\":\"This section displays the modifications on VIP Active Directory objects for the selected Time Range.\\r\\n\\r\\nIt is based on the security events 4725, 4726, 4738, 4740 and 4767.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"HelpTotalModifVIP\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ImportantADActivities = dynamic([4725,4726,4738,4740,4767]);\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet VIPUsers = _GetWatchlist('ExchangeVIP') | summarize make_list(tostring(sAMAccountName)) ;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where EventID in (ImportantADActivities)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where SubjectUserName in (VIPUsers) or TargetUserName in (VIPUsers)\\r\\n| extend Activity = tostring(split(Activity,\\\"- \\\")[1])\\r\\n| summarize Count=count() by Activity\",\"size\":3,\"noDataMessage\":\"Sections related to Option 2 or 3\",\"noDataMessageStyle\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Activity\",\"formatter\":1},\"leftContent\":{\"columnMatch\":\"Count\",\"formatter\":12,\"formatOptions\":{\"palette\":\"auto\"},\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}},\"showBorder\":false,\"size\":\"auto\"}},\"name\":\"QueryVIPModif\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let ImportantADActivities = dynamic([4725,4726,4738,4740,4767]);\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet VIPUsers = _GetWatchlist('ExchangeVIP') | summarize make_list(tostring(sAMAccountName)) ;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange}\\r\\n| where EventID in (ImportantADActivities)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where SubjectUserName in (VIPUsers) or TargetUserName in (VIPUsers)\\r\\n| extend Activity = split(Activity,\\\"- \\\")[1]\\r\\n| extend SubjectUserName = iif( SubjectUserName in (VIPUsers), strcat(SubjectUserName, \\\" 👑\\\"), SubjectUserName)\\r\\n| extend SubjectUserName = iif( SubjectUserName hassuffix \\\"$\\\", strcat(\\\"💻 \\\", SubjectUserName), strcat(\\\"👨💼 \\\", SubjectUserName))\\r\\n| extend TargetUserName = iif( TargetUserName in (VIPUsers), strcat(TargetUserName, \\\" 👑\\\"), TargetUserName)\\r\\n| project TimeGenerated, Activity, SubjectUserName,TargetUserName\\r\\n| order by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"noDataMessage\":\"Sections related to Option 2 or 3\",\"noDataMessageStyle\":2,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Activity\",\"formatter\":0,\"formatOptions\":{\"customColumnWidthSetting\":\"75ch\"}}],\"rowLimit\":10000,\"filter\":true,\"labelSettings\":[{\"columnId\":\"TimeGenerated\",\"label\":\"Time\"},{\"columnId\":\"SubjectUserName\",\"label\":\"Operator\"},{\"columnId\":\"TargetUserName\",\"label\":\"Target\"}]}},\"name\":\"query - 2\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"AD\"},\"name\":\"AdModifSummary\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Server activity summary\",\"items\":[{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"04d09365-30ba-4bb1-9e76-06fc7b97ea71\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"ComputerFilter\",\"type\":1,\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 5\"},{\"type\":1,\"content\":{\"json\":\"This tab parses the events from the System and Security event logs of the Exchange servers. You can use it for the following activities:\\r\\n\\r\\n- Track the Exchange services status (based on the event 7036 and on the watchlist \\\"Exchange Services Monitoring\\\")\\r\\n- Track logons on the servers (this excludes network logons)\\r\\n- Track creations, modifications and delegation actions of local user accounts\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"ServersHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize count() by Computer\",\"size\":4,\"title\":\"Security Events per Exchange Servers\",\"exportFieldName\":\"Computer\",\"exportParameterName\":\"ComputerFilter\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Computer\"},\"subtitleContent\":{\"columnMatch\":\"count_\",\"formatter\":4,\"formatOptions\":{\"min\":2000,\"palette\":\"blue\"},\"numberFormat\":{\"unit\":0,\"options\":{\"style\":\"decimal\"}}},\"showBorder\":true,\"sortCriteriaField\":\"Computer\",\"sortOrderField\":1,\"size\":\"auto\"}},\"customWidth\":\"100\",\"name\":\"ExServersListTiles\"},{\"type\":1,\"content\":{\"json\":\"## List of monitored services changes\"},\"name\":\"text - 7\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nlet ExchangeServices = _GetWatchlist('ExchangeServicesMonitoring') | summarize make_list(DisplayName);\\r\\nEvent \\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| where EventID == 7036\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where WindowsService_CF in (ExchangeServices)\\r\\n| extend ServiceNewState_CF = iif( ServiceNewState_CF == \\\"stopped\\\", strcat(\\\"🔴 \\\",ServiceNewState_CF), strcat(\\\"🟢 \\\",ServiceNewState_CF))\\r\\n| project TimeGenerated, Computer, WindowsService_CF, ServiceNewState_CF\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"showExpandCollapseGrid\":true,\"gridSettings\":{\"labelSettings\":[{\"columnId\":\"WindowsService_CF\",\"label\":\"Service\"},{\"columnId\":\"ServiceNewState_CF\",\"label\":\"State\"}]}},\"name\":\"ListServicesState\"},{\"type\":1,\"content\":{\"json\":\"Details of logon on the Exchange servers (or the selected server from the tiles above).\\r\\n\\r\\nThis parses the security event 4624 on Exchange servers.\\r\\n\\r\\nThis uses the following filters:\\r\\n- LogonType <> 3 (Network)\\r\\n- AccountType <> \\\"Machine\\\"\\r\\n- TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n- Account !hasprefix \\\"Window Manager\\\"\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"ServerLogonHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID == 4624\\r\\n| where LogonType <> 3\\r\\n| where AccountType <> \\\"Machine\\\" \\r\\n| where TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n| where Account !hasprefix \\\"Window Manager\\\"\\r\\n| summarize count() by LogonTypeName\",\"size\":0,\"title\":\"Logon Type statistics\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"DetailsLogonEventsPie\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID == 4624\\r\\n| where LogonType <> 3\\r\\n| where AccountType <> \\\"Machine\\\" \\r\\n| where TargetUserName !hasprefix \\\"HealthMailbox\\\"\\r\\n| where Account !hasprefix \\\"Window Manager\\\"\\r\\n| project TimeGenerated, Computer, Account, IpAddress, LogonTypeName\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"75\",\"name\":\"DetailsLogonEvents\"},{\"type\":1,\"content\":{\"json\":\"Details of local account activities on the Exchange servers (or the selected server from the tiles above). It parses the following security events:\\r\\n- 4720 Account creation\\r\\n- 4724 Password reset\\r\\n- 4722 Account enabled\\r\\n- 4725 Account disabled\\r\\n- 4726 Account deleted\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"LocalAccountActivityHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID in (4720,4724,4722,4725,4726)\\r\\n| extend Action = case(EventID == 4720, \\\"🆕 Account creation\\\", EventID == 4724, \\\"🔄 Password reset\\\", EventID == 4722, \\\"🟢 Account enabled\\\", EventID == 4725, \\\"🔴 Account disabled\\\",\\\"❌ Account deleted\\\")\\r\\n| summarize count() by Action\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"List of local account activities\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"25\",\"name\":\"LocalAccountActivity\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent\\r\\n| where TimeGenerated {TimeRange:value}\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| where Computer like \\\"{ComputerFilter}\\\"\\r\\n| where EventID in (4720,4724,4722,4725,4726)\\r\\n| extend Action = case(EventID == 4720, \\\"🆕 Account creation\\\", EventID == 4724, \\\"🔄 Password reset\\\", EventID == 4722, \\\"🟢 Account enabled\\\", EventID == 4725, \\\"🔴 Account disabled\\\",\\\"❌ Account deleted\\\")\\r\\n| project TimeGenerated, Computer, Action, SubjectAccount, TargetAccount\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"75\",\"name\":\"LocalActivityGrid\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Server\"},\"name\":\"ServerSummaryGroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Mail flow\",\"items\":[{\"type\":1,\"content\":{\"json\":\"This is an experimental tab to search for information from the Message Tracking logs.\",\"style\":\"warning\"},\"name\":\"WarningMessagetracking\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"MessageTracking\\r\\n| where TimeGenerated > ago(7d)\\r\\n| summarize Max = max(TimeGenerated) by Computer\\r\\n| extend Age = strcat( datetime_diff( \\\"Hour\\\", now(), Max) , \\\" hours ago\\\")\",\"size\":4,\"noDataMessage\":\"No message tracking data for more than 7 days\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{\"columnMatch\":\"Computer\"},\"leftContent\":{\"columnMatch\":\"Max\"},\"rightContent\":{\"columnMatch\":\"Age\"},\"showBorder\":true,\"size\":\"auto\"}},\"name\":\"query - 1\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"69b3412d-8984-42a7-8b5a-c238462097b7\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Filter\",\"type\":1,\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"MessageTracking\\r\\n| search \\\"*{Filter}\\\"\\r\\n| project-away $table\\r\\n| sort by TimeGenerated desc\",\"size\":0,\"showAnalytics\":true,\"showExportToExcel\":true,\"noDataMessage\":\"No message tracking information found.\",\"timeContextFromParameter\":\"TimeRange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true}},\"name\":\"query - 0\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Mail\"},\"name\":\"MailFlowGroup\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Data Statistics\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## 90-day statistics\"},\"name\":\"text - 4\"},{\"type\":1,\"content\":{\"json\":\"This tabs show the data ingestions of logs used to monitor Exchange Servers activities.\\r\\n\\r\\nNote that the Event table contains all Windows event log events but the security event logs.\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"Help\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"showPin\":false,\"name\":\"StatsHelp\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nEvent \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (Event\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"Event table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"EventTable\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nW3CIISLog \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (W3CIISLog\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"W3CIISLog table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"IISLogs\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nSecurityEvent \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (SecurityEvent\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"SecurityEvent table\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"min\":-1,\"max\":1,\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"SecurityEventTable\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"let EHP = union isfuzzy=true withsource=TableName ExchangeHttpProxy, blabla*, Event | where TableName != \\\"Event\\\";\\r\\nlet Env = ExchangeConfiguration(SpecificSectionList=\\\"ESIEnvironment\\\")\\r\\n| extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN)\\r\\n| project DomainFQDN_, ESIEnvironment;\\r\\nEHP \\r\\n| where TimeGenerated > ago(90d)\\r\\n| extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n| extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n| where ESIEnvironment in ('{EnvironmentList}')\\r\\n| summarize Total=count() by Computer\\r\\n| join (EHP\\r\\n | where TimeGenerated > ago(90d)\\r\\n | extend DomainEnv = replace_string(Computer,strcat(tostring(split(Computer,'.',0)[0]),'.'),'')\\r\\n | join kind=leftouter ( \\r\\n Env\\r\\n ) on $left.DomainEnv == $right.DomainFQDN_\\r\\n | extend ESIEnvironment = iif (isnotempty(ESIEnvironment), ESIEnvironment, strcat(\\\"Unknown-\\\",DomainEnv))\\r\\n | where ESIEnvironment in ('{EnvironmentList}')\\r\\n | make-series EventCount=count() on TimeGenerated from ago(90d) to now() step 1d by Computer\\r\\n | extend EventAnomalies=series_decompose_anomalies(EventCount)\\r\\n) on Computer\\r\\n| extend Computer = strcat(\\\"💻 \\\", Computer)\\r\\n| project-away TimeGenerated, Computer1\\r\\n| sort by Total desc \",\"size\":1,\"showAnalytics\":true,\"showExportToExcel\":true,\"title\":\"ExchangeHttpProxy table\",\"noDataMessage\":\"No Exchange HTTP Proxy Data\",\"noDataMessageStyle\":2,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"rowLimit\":10000,\"filter\":true,\"formatters\":[{\"columnMatch\":\"Total\",\"formatter\":4,\"formatOptions\":{\"min\":1000,\"palette\":\"blue\",\"customColumnWidthSetting\":\"70px\"}},{\"columnMatch\":\"EventCount\",\"formatter\":21,\"formatOptions\":{\"palette\":\"blue\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Trend\"}},{\"columnMatch\":\"EventAnomalies\",\"formatter\":9,\"formatOptions\":{\"palette\":\"redDark\",\"customColumnWidthSetting\":\"200px\"},\"tooltipFormat\":{\"tooltip\":\"Anomalies\"}}],\"labelSettings\":[{\"columnId\":\"EventCount\",\"label\":\"Count\"},{\"columnId\":\"EventAnomalies\",\"label\":\"Anomalies\"}]}},\"customWidth\":\"50\",\"name\":\"ExchangeHttpProxyTable\"}]},\"conditionalVisibility\":{\"parameterName\":\"selected\",\"comparison\":\"isEqualTo\",\"value\":\"Stats\"},\"name\":\"group - 7\"}],\"fromTemplateId\":\"sentinel-MicrosoftExchangeSecurityMonitoring\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -2709,7 +2910,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Microsoft Exchange Security Review Workbook with template version 3.0.1",
+ "description": "Microsoft Exchange Security Review Workbook with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('workbookVersion4')]",
@@ -2727,7 +2928,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\\\"}\",\"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\":\"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",
"version": "1.0",
"sourceId": "[variables('workspaceResourceId')]",
"category": "sentinel"
@@ -2800,7 +3001,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "CriticalCmdletsUsageDetection_AnalyticalRules Analytics Rule with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion1')]",
@@ -2817,10 +3018,10 @@
"description": "Alert if a cmdlet that can be translated to data exfiltration or mailbox access is executed on a VIP Mailbox.",
"displayName": "VIP Mailbox manipulation",
"enabled": false,
- "query": "ExchangeAdminAuditLogs\n| where ingestion_time() > ago(30m)\n| where IsSensitive == true\n| where UserOriented =~ 'Yes'\n| where IsVIP == true\n",
+ "query": "let VIPRestriction = \"on\";\nExchangeAdminAuditLogs\n| where IsVIP or VIPRestriction =~ \"off\"\n| where UserOriented =~ 'Yes' and IsSensitive and ((IsRestrictedCmdLet and IsSenstiveCmdletParameters) or IsRestrictedCmdLet == false)\n| extend Level = iif (Status == \"Failure\", \"Medium\", \"High\")\n",
"queryFrequency": "PT30M",
"queryPeriod": "PT1H",
- "severity": "Low",
+ "severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"triggerOperator": "GreaterThan",
@@ -2848,8 +3049,8 @@
{
"fieldMappings": [
{
- "identifier": "MailboxPrimaryAddress",
- "columnName": "TargetObject"
+ "columnName": "TargetObject",
+ "identifier": "MailboxPrimaryAddress"
}
],
"entityType": "Mailbox"
@@ -2857,8 +3058,8 @@
{
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "FullName"
}
],
"entityType": "Host"
@@ -2866,16 +3067,16 @@
{
"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"
@@ -2883,13 +3084,18 @@
{
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Caller"
+ "columnName": "Caller",
+ "identifier": "Name"
}
],
"entityType": "Account"
}
- ]
+ ],
+ "alertDetailsOverride": {
+ "alertDescriptionFormat": "Alert from Microsoft Exchange Security as {{CmdletName}} with parameters {{CmdletParameters}} was executed on {{TargetObject}}",
+ "alertSeverityColumnName": "Level",
+ "alertDisplayNameFormat": "{{CmdletName}} executed on {{TargetObject}}"
+ }
}
},
{
@@ -2942,7 +3148,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "ServerOrientedWithUserOrientedAdministration_AnalyticalRules Analytics Rule with template version 3.1.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion2')]",
@@ -2959,7 +3165,7 @@
"description": "Detect if a server oriented cmdlet and a user oriented cmdlet that are monitored are launched by the same user in the same server within a 10 minutes timeframe",
"displayName": "Server Oriented Cmdlet And User Oriented Cmdlet used",
"enabled": false,
- "query": "let timeframe = 1d;\nlet spanoftime = 10m;\nlet threshold = 0;\nExchangeAdminAuditLogs \n | where TimeGenerated > ago(2 * timeframe)\n | where isempty(UserOriented)\n | project serverExecutedTime = TimeGenerated,\n ServerCmdlet = CmdletName,\n ServerCmdletParams = CmdletParameters,\n Computer,\n Caller,\n ServerCmdletTargetObject = TargetObject\n | join kind= inner (\n ExchangeAdminAuditLogs\n | where TimeGenerated > ago(timeframe)\n | where UserOriented =~ 'Yes'\n | lookup kind=leftouter _GetWatchlist('ExchangeVIP') on $left.TargetObject == $right.canonicalName\n | project userExecutedTime = TimeGenerated,\n UserCmdlet = CmdletName,\n UserCmdletParams = CmdletParameters,\n Computer,\n Caller,\n UserCmdletTargetObject = TargetObject,\n userPrincipalName,\n objectGUID,\n sAMAccountName,\n IsVIP)\n on Computer, Caller\n | where userExecutedTime - serverExecutedTime < spanoftime\n | extend TimeDelta = userExecutedTime - serverExecutedTime\n | extend TimeDeltaInverse = serverExecutedTime - userExecutedTime\n | where tolong(TimeDelta) >= threshold or tolong(TimeDeltaInverse) >= threshold\n",
+ "query": "let timeframe = 1d;\nlet spanoftime = 10m;\nlet threshold = 0;\nExchangeAdminAuditLogs \n | where TimeGenerated > ago(2 * timeframe)\n | where isempty(UserOriented)\n | project serverExecutedTime = TimeGenerated,\n ServerCmdlet = CmdletName,\n ServerCmdletParams = CmdletParameters,\n Computer,\n Caller,\n ServerCmdletTargetObject = TargetObject\n | join kind= inner (\n ExchangeAdminAuditLogs\n | where TimeGenerated > ago(timeframe)\n | where UserOriented =~ 'Yes'\n | project userExecutedTime = TimeGenerated,\n UserCmdlet = CmdletName,\n UserCmdletParams = CmdletParameters,\n Computer,\n Caller,\n UserCmdletTargetObject = TargetObject,\n userPrincipalName,\n objectGUID,\n sAMAccountName,\n IsVIP)\n on Computer, Caller\n | where userExecutedTime - serverExecutedTime < spanoftime\n | extend TimeDelta = userExecutedTime - serverExecutedTime\n | extend TimeDeltaInverse = serverExecutedTime - userExecutedTime\n | where tolong(TimeDelta) >= threshold or tolong(TimeDeltaInverse) >= threshold\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "High",
@@ -2990,12 +3196,12 @@
{
"fieldMappings": [
{
- "identifier": "MailboxPrimaryAddress",
- "columnName": "userPrincipalName"
+ "columnName": "userPrincipalName",
+ "identifier": "MailboxPrimaryAddress"
},
{
- "identifier": "Upn",
- "columnName": "userPrincipalName"
+ "columnName": "userPrincipalName",
+ "identifier": "Upn"
}
],
"entityType": "Mailbox"
@@ -3003,8 +3209,8 @@
{
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "FullName"
}
],
"entityType": "Host"
@@ -3012,8 +3218,8 @@
{
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "ServerCmdletTargetObject"
+ "columnName": "ServerCmdletTargetObject",
+ "identifier": "HostName"
}
],
"entityType": "Host"
@@ -3021,12 +3227,12 @@
{
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Caller"
+ "columnName": "Caller",
+ "identifier": "Name"
},
{
- "identifier": "ObjectGuid",
- "columnName": "TargetObject"
+ "columnName": "objectGUID",
+ "identifier": "ObjectGuid"
}
],
"entityType": "Account"
@@ -3075,17 +3281,53 @@
"version": "[variables('analyticRuleVersion2')]"
}
},
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',parameters('watchlist1-id'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/Watchlists",
+ "kind": "",
+ "properties": {
+ "displayName": "Exchange Services Monitoring",
+ "source": "ExchangeServicesMonitoring.csv",
+ "description": "Exchange Services Monitored for security reasons.",
+ "provider": "Microsoft",
+ "isDeleted": false,
+ "defaultDuration": "P1000Y",
+ "contentType": "Text/Csv",
+ "numberOfLinesToSkip": 0,
+ "itemsSearchKey": "Name",
+ "rawContent": "Name,DisplayName\r\n\"MSExchangeCompliance\",\"Microsoft Exchange Compliance Service\"\r\n\"MSExchangePop3\",\"Microsoft Exchange POP3\"\r\n\"MSExchangeDagMgmt\",\"Microsoft Exchange DAG Management\"\r\n\"MSExchangePOP3BE\",\"Microsoft Exchange POP3 Backend\"\r\n\"Spooler\",\"Print Spooler\"\r\n\"MSExchangeDelivery\",\"Microsoft Exchange Mailbox Transport Delivery\"\r\n\"MSExchangeRepl\",\"Microsoft Exchange Replication\"\r\n\"Netlogon\",\"Netlogon\"\r\n\"MSExchangeDiagnostics\",\"Microsoft Exchange Diagnostics\"\r\n\"MSExchangeRPC\",\"Microsoft Exchange RPC Client Access\"\r\n\"NetMsmqActivator\",\"Net.Msmq Listener Adapter\"\r\n\"MSExchangeEdgeSync\",\"Microsoft Exchange EdgeSync\"\r\n\"MSExchangeServiceHost\",\"Microsoft Exchange Service Host\"\r\n\"MSExchangeFastSearch\",\"Microsoft Exchange Search\"\r\n\"MSExchangeSubmission\",\"Microsoft Exchange Mailbox Transport Submission\"\r\n\"MSExchangeFrontEndTransport\",\"Microsoft Exchange Frontend Transport\"\r\n\"MSExchangeThrottling\",\"Microsoft Exchange Throttling\"\r\n\"MSExchangeImap4\",\"Microsoft Exchange IMAP4\"\r\n\"MSExchangeTransport\",\"Microsoft Exchange Transport\"\r\n\"MSComplianceAudit\",\"Microsoft Exchange Compliance Audit\"\r\n\"MSExchangeIMAP4BE\",\"Microsoft Exchange IMAP4 Backend\"\r\n\"MSExchangeTransportLogSearch\",\"Microsoft Exchange Transport Log Search\"\r\n\"MSExchangeIS\",\"Microsoft Exchange Information Store\"\r\n\"MSExchangeUM\",\"Microsoft Exchange Unified Messaging\"\r\n\"MSExchangeADTopology\",\"Microsoft Exchange Active Directory Topology\"\r\n\"MSExchangeMailboxAssistants\",\"Microsoft Exchange Mailbox Assistants\"\r\n\"MSExchangeUMCR\",\"Microsoft Exchange Unified Messaging Call Router\"\r\n\"WMSVC\",\"Web Management Service\"\r\n\"IISADMIN\",\"IIS Admin Service\"\r\n\"MSExchangeAntispamUpdate\",\"Microsoft Exchange Anti-spam Update\"\r\n\"MSExchangeMailboxReplication\",\"Microsoft Exchange Mailbox Replication\"\r\n\"W3SVC\",\"World Wide Web Publishing Service\"\r\n"
+ },
+ "apiVersion": "2021-03-01-preview"
+ },
+ {
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',parameters('watchlist2-id'))]",
+ "type": "Microsoft.OperationalInsights/workspaces/providers/Watchlists",
+ "kind": "",
+ "properties": {
+ "displayName": "Exchange VIP",
+ "source": "ExchangeVIP.csv",
+ "description": "Specific VIP Monitored in Exchange.",
+ "provider": "Microsoft",
+ "isDeleted": false,
+ "defaultDuration": "P1000Y",
+ "contentType": "Text/Csv",
+ "numberOfLinesToSkip": 0,
+ "itemsSearchKey": "userPrincipalName",
+ "rawContent": "displayName,userPrincipalName,sAMAccountName,objectSID,objectGUID,canonicalName,distinguishedName,comment\r\n\"2016DB1 User1\",\"2016DB1-User1@MyCompany.com\",\"2016DB1-User1\",\"S-1-5-21-666558943-2796267414-309129817-1211\",\"7d5c567e-621a-49d5-9766-b631921f1afe\",\"MyCompany.com/MyCompany/Users/2016DB1-User1\",\"CN=2016DB1-User1,CN=Users,CN=MyCompany,CN=MyCompany.com\",\r\n"
+ },
+ "apiVersion": "2021-03-01-preview"
+ },
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.1",
+ "version": "3.1.0",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Microsoft Exchange Security - Exchange On-Premises",
"publisherDisplayName": "Community",
- "descriptionHtml": "
Note: 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: 3, Workbooks: 4, Analytic Rules: 2
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "descriptionHtml": "Note: 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", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -3134,6 +3376,11 @@ "contentId": "[variables('_parserContentId3')]", "version": "[variables('parserVersion3')]" }, + { + "kind": "Parser", + "contentId": "[variables('_parserContentId4')]", + "version": "[variables('parserVersion4')]" + }, { "kind": "Workbook", "contentId": "[variables('_workbookContentId1')]", @@ -3163,6 +3410,16 @@ "kind": "AnalyticsRule", "contentId": "[variables('analyticRulecontentId2')]", "version": "[variables('analyticRuleVersion2')]" + }, + { + "kind": "Watchlist", + "contentId": "[variables('_Exchange Services Monitoring')]", + "version": "3.1.0" + }, + { + "kind": "Watchlist", + "contentId": "[variables('_Exchange VIP')]", + "version": "3.1.0" } ] }, diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeAdminAuditLogs.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeAdminAuditLogs.yaml index 8222b6467ca..ab7c05111f2 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeAdminAuditLogs.yaml +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/ExchangeAdminAuditLogs.yaml @@ -1,27 +1,49 @@ id: f79a3a19-bb9f-4f06-a109-3e3ac2001be9 Function: Title: Parser for ExchangeAdminAuditLogs - Version: '1.0.0' - LastUpdated: '2023-08-23' + Version: '1.3.0' + LastUpdated: '2023-11-01' Category: Microsoft Sentinel Parser FunctionName: ExchangeAdminAuditLogs FunctionAlias: ExchangeAdminAuditLogs FunctionQuery: | - let cVIPs = _GetWatchlist('ExchangeVIP') | project tostring(canonicalName) ; - let sVIPs = _GetWatchlist('ExchangeVIP') | project tostring(sAMAccountName) ; 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); - let SensitiveCmdlets = 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) | project tostring(Cmdlet) ; + let SensitiveCmdlets = CmdletCheck | project tostring(Cmdlet) ; + let Check = (T:(*)) { + 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 SearchUserDisplayName = T | join Watchlist on $left.TargetObject == $right.displayName | project TargetObject,SearchKey; + let SearchUserUPN = T | join Watchlist on $left.TargetObject == $right.userPrincipalName | project TargetObject,SearchKey; + let SearchUserCanonicalName = T | join Watchlist on $left.TargetObject == $right.canonicalName | project TargetObject,SearchKey; + let SearchUserSAMAccountName = T | join Watchlist on $left.TargetObject == $right.sAMAccountName | project TargetObject,SearchKey; + let SearchUserObjectSID = T | join Watchlist on $left.TargetObject == $right.objectSID | project TargetObject,SearchKey; + let SearchUserObjectGUID = T | join (Watchlist | extend objectGuidString = tostring(objectGUID)) on $left.TargetObject == $right.objectGuidString | project TargetObject,SearchKey; + let SearchUserDistinguishedName = T | join Watchlist on $left.TargetObject == $right.distinguishedName | project TargetObject,SearchKey; + union isfuzzy=true withsource=TableName + SearchUserDisplayName, + SearchUserUPN, + SearchUserCanonicalName, + SearchUserSAMAccountName, + SearchUserObjectSID, + SearchUserObjectGUID, + SearchUserDistinguishedName + }; let Env = ExchangeConfiguration(SpecificSectionList="ESIEnvironment") | extend DomainFQDN_ = tostring(CmdletResultValue.DomainFQDN) | project DomainFQDN_, ESIEnvironment; - let MSExchange_Management = (){ - Event + let EventList = Event | where EventLog == 'MSExchange Management' | where EventID in (1,6) // 1 = Success, 6 = Failure | parse ParameterXml with '' CmdletName '' CmdletParameters '' Caller '' * - | extend TargetObject = iif( CmdletParameters has "-Identity ", split(split(CmdletParameters,'-Identity ')[1],'"')[1], iif( CmdletParameters has "-Name ", split(split(CmdletParameters,'-Name ')[1],'"')[1], "")) + | extend TargetObject = iif( CmdletParameters has "-Identity ", split(split(CmdletParameters,'-Identity ')[1],'"')[1], iif( CmdletParameters has "-Name ", split(split(CmdletParameters,'-Name ')[1],'"')[1], "")); + let MSExchange_Management = (){ + EventList | extend Status = case( EventID == 1, 'Success', 'Failure') - | extend IsVIP = iif(TargetObject in (cVIPs) or TargetObject in (sVIPs), true, false) + | join kind=leftouter (EventList | project TargetObject | invoke Check()) on TargetObject + | extend IsVIP = iif(SearchKey == "", false, true) + | join kind=leftouter ( + MESCheckVIP() ) on SearchKey | extend CmdletNameJoin = tolower(CmdletName) | join kind=leftouter ( CmdletCheck @@ -38,7 +60,6 @@ FunctionQuery: | | extend ExtractedParameters = iif(IsSenstiveCmdlet == true,extract_all(@"\B(-\w+)", tolower(CmdletParameters)), dynamic(null)) | extend IsSenstiveCmdletParameters = iif(IsSenstiveCmdlet == true,iif( array_length(set_difference(ExtractedParameters,RestrictedParameters)) == array_length(ExtractedParameters), false, true ) , false) | extend IsSensitive = iif( ( IsSenstiveCmdlet == true and IsRestrictedCmdLet == false ) or (IsSenstiveCmdlet == true and IsRestrictedCmdLet == true and IsSenstiveCmdletParameters == true ), true, false ) - //| project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters - | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment + | project TimeGenerated,Computer,Status,Caller,TargetObject,IsVIP,canonicalName,displayName,distinguishedName,objectGUID,objectSID,sAMAccountName,userPrincipalName,CmdletName,CmdletParameters,IsSenstiveCmdlet,IsRestrictedCmdLet,ExtractedParameters,RestrictedParameters,IsSenstiveCmdletParameters,IsSensitive,UserOriented, ESIEnvironment }; MSExchange_Management \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCheckVIP.yaml b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCheckVIP.yaml new file mode 100644 index 00000000000..701b9dbffbd --- /dev/null +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/MESCheckVIP.yaml @@ -0,0 +1,29 @@ +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". + DefaultValue: '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 On-Premises/Parsers/README.md b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md index 2bb91a6bef8..cc231a9d401 100644 --- a/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md +++ b/Solutions/Microsoft Exchange Security - Exchange On-Premises/Parsers/README.md @@ -23,6 +23,11 @@ Parsers are created [using functions in Azure monitor log queries](https://docs. - [Parser dependency](#parser-dependency) - [Parser Setup](#parser-setup-2) - [Linked tables](#linked-tables-2) + - [Microsoft Exchange Security Check VIP Parser](#microsoft-exchange-security-check-vip-parser) + - [Parser Definition](#parser-definition-3) + - [Parser Description](#parser-description-3) + - [Parser dependency](#parser-dependency-1) + - [Parser Setup](#parser-setup-3) ## ExchangeConfiguration Parser @@ -120,11 +125,14 @@ let Target = 'On-Premises'; ### Parser Definition - Title: Exchange Admin Audit Logs Parser -- Version: 1.0 -- Last Updated: 15/11/2022 +- Version: 1.3.0 +- Last Updated: 01/11/2023 |**Version** |**Details** | |---------|-----------------------------------------------------------------------------------------------------------------------| +|v1.3 |Note: 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: 2, Workbooks: 2
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "descriptionHtml": "Note: 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: 3, Workbooks: 2, Watchlists: 1
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -1106,6 +1273,11 @@ "contentId": "[variables('_parserContentId2')]", "version": "[variables('parserVersion2')]" }, + { + "kind": "Parser", + "contentId": "[variables('_parserContentId3')]", + "version": "[variables('parserVersion3')]" + }, { "kind": "Workbook", "contentId": "[variables('_workbookContentId1')]", @@ -1115,6 +1287,11 @@ "kind": "Workbook", "contentId": "[variables('_workbookContentId2')]", "version": "[variables('workbookVersion2')]" + }, + { + "kind": "Watchlist", + "contentId": "[variables('_Exchange VIP')]", + "version": "3.0.2" } ] }, diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml new file mode 100644 index 00000000000..701b9dbffbd --- /dev/null +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/MESCheckVIP.yaml @@ -0,0 +1,29 @@ +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". + DefaultValue: '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/README.md b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md index 2bb91a6bef8..8c5ab31933a 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Parsers/README.md @@ -17,12 +17,11 @@ Parsers are created [using functions in Azure monitor log queries](https://docs. - [Parser Setup](#parser-setup-1) - [Linked tables](#linked-tables-1) - [Parameters simulation](#parameters-simulation-1) - - [Exchange Admin Audit Logs Parser](#exchange-admin-audit-logs-parser) + - [Microsoft Exchange Security Check VIP Parser](#microsoft-exchange-security-check-vip-parser) - [Parser Definition](#parser-definition-2) - [Parser Description](#parser-description-2) - [Parser dependency](#parser-dependency) - [Parser Setup](#parser-setup-2) - - [Linked tables](#linked-tables-2) ## ExchangeConfiguration Parser @@ -115,13 +114,13 @@ If you need to test the parser execution without saving it as a function, add th let Target = 'On-Premises'; ``` -## Exchange Admin Audit Logs Parser +## Microsoft Exchange Security Check VIP Parser ### Parser Definition -- Title: Exchange Admin Audit Logs Parser -- Version: 1.0 -- Last Updated: 15/11/2022 +- Title: Microsoft Exchange Security Check VIP (MESCheckVIP) Parser +- Version: 1.0.0 +- Last Updated: 01/11/2023 |**Version** |**Details** | |---------|-----------------------------------------------------------------------------------------------------------------------| @@ -129,7 +128,7 @@ let Target = 'On-Premises'; ### Parser Description -This parser takes raw Exchange Admin Audit Logs and add elements like ESI Environment, VIP information, sensitive information, etc... +This parser verify if a user (by Display name, UPN, Canonical name, alias, SamAccountName, DN) is a VIP in ExchangeVIP Whatchlist or not. ### Parser dependency @@ -138,9 +137,10 @@ This parser is linked to "ExchangeVIP" whatchlist ### Parser Setup 1. Open Log Analytics/Microsoft Sentinel Logs blade. Copy the query below and paste into the Logs query window. - 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "ExchangeAdminAuditLogs". - 3. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries - -### Linked tables + 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter the Function Name "MESCheckVIP". -This parser assumes that MS Exchange Management Logs from Exchange Servers Event Logs are collected in Log Analytics. +>#### **Parameters:** +> +>1 parameter to add during creation : UserToCheck, type string, default value "All" + + 1. Function App usually take 10-15 minutes to activate. You can then use Function Alias for other queries \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md b/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md index eb1bad6a518..dc9d76c2c97 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md +++ b/Solutions/Microsoft Exchange Security - Exchange Online/ReleaseNotes.md @@ -1,4 +1,5 @@ | **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | |-------------|--------------------------------|---------------------------------------------| +| 3.0.2 | 11-01-2023 | Adding a Parser to verify if user is Microsoft Exchange Security VIP (Watchlist) | | 3.0.1 | 09-13-2023 | readme file for parsers and typo correction | | 3.0.0 | 08-23-2023 |**ExchangeEnvironmentList** parser name corrected in Workbooks. | diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.csv b/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.csv index 4588538c877..8b93b583bc2 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.csv +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.csv @@ -1,2 +1,2 @@ -userPrincipalName,sAMAccountName,objectSID,objectGUID,canonicalName,comment -"2016DB1-User1@MyCompany.com","2016DB1-User1","S-1-5-21-666558943-2796267414-309129817-1211","7d5c567e-621a-49d5-9766-b631921f1afe","MyCompany.com/MyCompany/Users/2016DB1-User1", \ No newline at end of file +displayName,userPrincipalName,sAMAccountName,objectSID,objectGUID,canonicalName,distinguishedName,comment +"2016DB1 User1","2016DB1-User1@MyCompany.com","2016DB1-User1","S-1-5-21-666558943-2796267414-309129817-1211","7d5c567e-621a-49d5-9766-b631921f1afe","MyCompany.com/MyCompany/Users/2016DB1-User1","CN=2016DB1-User1,CN=Users,CN=MyCompany,CN=MyCompany.com", \ No newline at end of file diff --git a/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIPs.json b/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.json similarity index 63% rename from Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIPs.json rename to Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.json index f4ee6569b10..b2e92167e19 100644 --- a/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIPs.json +++ b/Solutions/Microsoft Exchange Security - Exchange Online/Watchlists/ExchangeVIP.json @@ -7,12 +7,6 @@ "metadata": { "description": "Workspace name for Log Analytics where Sentinel is setup" } - }, - "watchlistdescription": { - "type": "string", - "metadata": { - "description": "Specific VIP Monitored in Exchange." - } } }, "resources": [ @@ -23,16 +17,14 @@ "properties": { "displayName": "Exchange VIP", "source": "ExchangeVIP.csv", - "description": "[parameters('watchlistdescription')]", + "description": "Specific VIP Monitored in Exchange.", "provider": "Microsoft", "isDeleted": false, - "labels": [ - ], "defaultDuration": "P1000Y", "contentType": "Text/Csv", "numberOfLinesToSkip": 0, "itemsSearchKey": "userPrincipalName", - "rawContent": "userPrincipalName,sAMAccountName,objectSID,objectGUID,canonicalName,comment\r\n\"2016DB1-User1@MyCompany.com\",\"2016DB1-User1\",\"S-1-5-21-666558943-2796267414-309129817-1211\",\"7d5c567e-621a-49d5-9766-b631921f1afe\",\"MyCompany.com/MyCompany/Users/2016DB1-User1\",\r\n" + "rawContent": "displayName,userPrincipalName,sAMAccountName,objectSID,objectGUID,canonicalName,distinguishedName,comment\r\n\"2016DB1 User1\",\"2016DB1-User1@MyCompany.com\",\"2016DB1-User1\",\"S-1-5-21-666558943-2796267414-309129817-1211\",\"7d5c567e-621a-49d5-9766-b631921f1afe\",\"MyCompany.com/MyCompany/Users/2016DB1-User1\",\"CN=2016DB1-User1,CN=Users,CN=MyCompany,CN=MyCompany.com\",\r\n" }, "apiVersion": "2021-03-01-preview" } diff --git a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 index a9338037cfd..993da5bfc86 100644 --- a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 @@ -885,7 +885,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe "$($contentResourceDetails.dependsOn), variables('workbookTemplateSpecName$global:workbookCounter'))]" ); properties = [PSCustomObject]@{ - description = "$($fileName) Workbook with template version $($contentToImport.Version)"; + description = "$($workbookKey) Workbook with template version $($contentToImport.Version)"; mainTemplate = [PSCustomObject]@{ '$schema' = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"; contentVersion = "[variables('workbookVersion$global:workbookCounter')]"; @@ -2860,7 +2860,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe Write-Output "Missing arm-ttk validations. Downloading module..." Invoke-Expression "$armTtkFolder/download-arm-ttk.ps1" } - Invoke-Expression "$armTtkFolder/run-arm-ttk-in-automation.ps1 '$solutionName'" + Invoke-Expression "& '$armTtkFolder/run-arm-ttk-in-automation.ps1' '$solutionName'" } } diff --git a/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineBlack.png new file mode 100644 index 00000000000..4cece0641a3 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineWhite.png new file mode 100644 index 00000000000..ef00f0090bd Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBAC-OnlineWhite.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACBlack.png new file mode 100644 index 00000000000..6b250764e6a Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACWhite.png new file mode 100644 index 00000000000..37f06bc720d Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeLeastPrivilegewithRBACWhite.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogBlack.png new file mode 100644 index 00000000000..c8ba835efb1 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogWhite.png new file mode 100644 index 00000000000..ed256907901 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSearchAdminAuditLogWhite.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringBlack.png new file mode 100644 index 00000000000..5c76e73c8f1 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringWhite.png new file mode 100644 index 00000000000..3d07a4b935d Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityMonitoringWhite.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineBlack.png new file mode 100644 index 00000000000..8194456ed92 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineWhite.png new file mode 100644 index 00000000000..c223f0b45d0 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReview-OnlineWhite.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewBlack.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewBlack.png new file mode 100644 index 00000000000..e8f3622e6be Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewBlack.png differ diff --git a/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewWhite.png b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewWhite.png new file mode 100644 index 00000000000..96d1f9a0ba8 Binary files /dev/null and b/Workbooks/Images/Preview/MicrosoftExchangeSecurityReviewWhite.png differ diff --git a/Workbooks/WorkbooksMetadata.json b/Workbooks/WorkbooksMetadata.json index ca0ebc43878..d40b80f38f5 100644 --- a/Workbooks/WorkbooksMetadata.json +++ b/Workbooks/WorkbooksMetadata.json @@ -5194,31 +5194,55 @@ "ESIExchangeOnlineConfig_CL" ], "dataConnectorsDependencies": [ - "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", "ESI-ExchangeOnlineCollector" ], - "previewImagesFileNames": [""], - "version": "1.0.0", + "previewImagesFileNames": [ + "MicrosoftExchangeLeastPrivilegewithRBAC-OnlineBlack.png", + "MicrosoftExchangeLeastPrivilegewithRBAC-OnlineWhite.png" + ], + "version": "1.0.1", "title": "Microsoft Exchange Least Privilege with RBAC - Online", "templateRelativePath": "Microsoft Exchange Least Privilege with RBAC - Online.json", "subtitle": "", "provider": "Microsoft" }, +{ + "workbookKey": "MicrosoftExchangeLeastPrivilegewithRBAC", + "logoFileName": "Azure_Sentinel.svg", + "description": "This Workbook, dedicated to On-Premises environments is built to have a simple view of non-standard RBAC delegations on an On-Premises Exchange environment. This Workbook allow you to go deep dive on custom delegation and roles and also members of each delegation, including the nested level and the group imbrication on your environment. Required Data Connector: Exchange Security Insights On-Premises Collector.", + "dataTypesDependencies": [ + "ESIExchangeConfig_CL" + ], + "dataConnectorsDependencies": [ + "ESI-ExchangeOnPremisesCollector", + "ESI-ExchangeAdminAuditLogEvents" + ], + "previewImagesFileNames": [ + "MicrosoftExchangeLeastPrivilegewithRBACBlack.png", + "MicrosoftExchangeLeastPrivilegewithRBACWhite.png" + ], + "version": "1.0.1", + "title": "Microsoft Exchange Least Privilege with RBAC", + "templateRelativePath": "Microsoft Exchange Least Privilege with RBAC.json", + "subtitle": "", + "provider": "Microsoft" +}, { "workbookKey": "MicrosoftExchangeSearchAdminAuditLog", "logoFileName": "Azure_Sentinel.svg", - "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators' activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment.", + "description": "This workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs to give you a simple way to view administrators’ activities in your Exchange environment with Cmdlets usage statistics and multiple pivots to understand who and/or what is affected to modifications on your environment. Required Data Connector: Exchange Audit Event logs via Legacy Agent.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], - "previewImagesFileNames": [""], - "version": "1.0.0", + "previewImagesFileNames": [ + "MicrosoftExchangeSearchAdminAuditLogBlack.png", + "MicrosoftExchangeSearchAdminAuditLogWhite.png" + ], + "version": "1.0.1", "title": "Microsoft Exchange Search AdminAuditLog", "templateRelativePath": "Microsoft Exchange Search AdminAuditLog.json", "subtitle": "", @@ -5227,17 +5251,19 @@ { "workbookKey": "MicrosoftExchangeSecurityMonitoring", "logoFileName": "Azure_Sentinel.svg", - "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers.", + "description": "This Workbook is dedicated to On-Premises Exchange organizations. It uses the MSExchange Management event logs and Microsoft Exchange Security configuration collected by data connectors. It helps to track admin actions, especially on VIP Users and/or on Sensitive Cmdlets. This workbook allows also to list Exchange Services changes, local account activities and local logon on Exchange Servers. Required Data Connector: Exchange Audit Event logs via Legacy Agent.", "dataTypesDependencies": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], - "previewImagesFileNames": [""], - "version": "1.0.0", + "previewImagesFileNames": [ + "MicrosoftExchangeSecurityMonitoringBlack.png", + "MicrosoftExchangeSecurityMonitoringWhite.png" + ], + "version": "1.0.1", "title": "Microsoft Exchange Admin Activity", "templateRelativePath": "Microsoft Exchange Admin Activity.json", "subtitle": "", @@ -5251,12 +5277,13 @@ "ESIExchangeOnlineConfig_CL" ], "dataConnectorsDependencies": [ - "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", "ESI-ExchangeOnlineCollector" ], - "previewImagesFileNames": [""], - "version": "1.0.0", + "previewImagesFileNames": [ + "MicrosoftExchangeSecurityReview-OnlineBlack.png", + "MicrosoftExchangeSecurityReview-OnlineWhite.png" + ], + "version": "1.0.1", "title": "Microsoft Exchange Security Review - Online", "templateRelativePath": "Microsoft Exchange Security Review - Online.json", "subtitle": "", @@ -5265,17 +5292,19 @@ { "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.", + "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": [ - "ESIExchangeOnlineConfig_CL" + "ESIExchangeConfig_CL" ], "dataConnectorsDependencies": [ "ESI-ExchangeOnPremisesCollector", - "ESI-ExchangeAdminAuditLogEvents", - "ESI-ExchangeOnlineCollector" + "ESI-ExchangeAdminAuditLogEvents" ], - "previewImagesFileNames": [""], - "version": "1.0.0", + "previewImagesFileNames": [ + "MicrosoftExchangeSecurityReviewBlack.png", + "MicrosoftExchangeSecurityReviewWhite.png" + ], + "version": "1.0.1", "title": "Microsoft Exchange Security Review", "templateRelativePath": "Microsoft Exchange Security Review.json", "subtitle": "",