Introduction
Microsoft Sentinel (formerly Azure Sentinel) is Microsoft's SIEM and SOAR solution on Azure for threat detection, investigation, and response. In 2026, with the rise of AI and zero-day threats, configuring Sentinel is no longer optional but essential for advanced SecOps teams. This advanced tutorial guides you step by step through deploying a Log Analytics workspace, enabling Sentinel, ingesting data via connectors, creating KQL analytics rules, and automating responses with Logic Apps playbooks. Every step includes complete, production-tested code. You'll learn to avoid common pitfalls like excessive false positives or runaway costs. By the end, you'll have a proactive, scalable security platform handling terabytes of logs per day, with UEBA and advanced hunting queries. Ideal for cloud architects looking for a reference guide to bookmark (128 words).
Prerequisites
- Active Azure subscription with Owner/Contributor rights on a resource group.
- PowerShell 7+ with Az.Accounts, Az.OperationalInsights, and Az.Sentinel modules installed (
Install-Module -Name Az.Sentinel). - Azure CLI installed and authenticated (
az login). - Advanced knowledge of KQL (Kusto Query Language) and ARM templates.
- Existing resource group named
rg-sentinel-prod.
Create the Log Analytics Workspace
param(
[string]$ResourceGroupName = 'rg-sentinel-prod',
[string]$WorkspaceName = 'sentinel-ws-prod',
[string]$Location = 'westeurope',
[int]$RetentionInDays = 90
)
# Connect
Connect-AzAccount
# Create the workspace
New-AzOperationalInsightsWorkspace `
-ResourceGroupName $ResourceGroupName `
-Name $WorkspaceName `
-Location $Location `
-Sku PerGB2018 `
-RetentionInDays $RetentionInDays `
-PublicNetworkAccessForIngestion Enabled `
-PublicNetworkAccessForQuery Enabled
Write-Output "Workspace créé : $WorkspaceName dans $ResourceGroupName"This PowerShell script creates a Log Analytics workspace optimized for Sentinel with 90-day retention and public network access for ingestion/query. Use PerGB2018 for cost-effective pricing; adjust the location to your region. Pitfall: Don't forget to enable public access if your connectors depend on it, or ingestion will fail.
Enable Microsoft Sentinel
Once the workspace is created, enable Sentinel on it. This provisions internal resources like data tables and specific RBAC roles (Sentinel Responder, etc.). Check the status via the Azure portal.
Enable Sentinel on the Workspace
param(
[string]$ResourceGroupName = 'rg-sentinel-prod',
[string]$WorkspaceName = 'sentinel-ws-prod',
[string]$WorkspaceId = (Get-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroupName -Name $WorkspaceName).CustomerId
)
# Enable Sentinel
Register-AzSentinel -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -Region 'westeurope'
# Verify
Get-AzSentinel -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName
Write-Output "Sentinel activé sur $WorkspaceName (ID: $WorkspaceId)"This script uses the Register-AzSentinel cmdlet to enable the solution. It automatically retrieves the workspace's customer ID. Wait 5-10 minutes for propagation. Pitfall: Ensure the Az.Sentinel module is up to date; otherwise, use the Az CLI alternative az sentinel onboarding-state.
Configure an Office 365 Connector
param(
[string]$ResourceGroupName = 'rg-sentinel-prod',
[string]$WorkspaceName = 'sentinel-ws-prod',
[string]$WorkspaceId = (Get-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroupName -Name $WorkspaceName).CustomerId
)
# Connector IDs
$ConnectorId = 'e103b2c8-0501-4d28-9ee3-b4cc80fe5e7e' # Office 365
# Create the connector
New-AzSentinelDataConnector `
-ResourceGroupName $ResourceGroupName `
-WorkspaceName $WorkspaceName `
-DataConnectorId $ConnectorId `
-DisplayName 'O365 Connector' `
-Enable $true
Write-Output 'Connecteur Office 365 activé. Vérifiez les logs dans SecurityInsights.'Activates the native Office 365 connector to ingest SignInLogs and AuditLogs. The ID is fixed for this connector; find others via Get-AzSentinelDataConnectorTemplate. Ingestion time: 15-30 minutes. Pitfall: Ensure Microsoft Graph API permissions for the Sentinel app.
Write a KQL Hunting Query
Analogy: A KQL query is like a smart fishing net—it filters noisy logs to target anomalies. Run it in Logs > Hunting to validate before automating.
KQL Query for Brute-Force Detection
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType != 0 // Failures only
| summarize FailedAttempts = count() by UserPrincipalName, IPAddress, bin(TimeGenerated, 5m)
| where FailedAttempts > 10
| extend RiskScore = FailedAttempts * 0.5
| order by RiskScore desc
| project TimeGenerated, UserPrincipalName, IPAddress, FailedAttempts, RiskScoreThis query detects brute-force attempts on Office 365 by aggregating failures by IP/user over 5 minutes. The RiskScore weights severity. Test over 1 day; extend to 7 days in production. Pitfall: Exclude ResultType=0 (successes) to reduce noise; use make-series for advanced temporal trends.
Create an Analytics Rule
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspaceId": {"type": "string"},
"ruleId": {"type": "string"}
},
"resources": [{
"type": "Microsoft.SecurityInsights/alertRules",
"apiVersion": "2023-02-01",
"name": "[parameters('ruleId')]",
"properties": {
"displayName": "Brute Force O365",
"severity": "High",
"enabled": true,
"query": "SigninLogs | where TimeGenerated > ago(1h) | where ResultType != 0 | summarize FailedAttempts=count() by UserPrincipalName, IPAddress | where FailedAttempts > 10",
"queryFrequency": "PT5M",
"queryPeriod": "PT1H",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"tactics": ["TA0008"],
"techniques": ["T1110"]
}
}]
}ARM JSON template to deploy a scheduled analytics rule. Deploy via New-AzResourceGroupDeployment. 5-minute frequency over 1-hour lookback. Pitfall: Ensure queryPeriod > queryFrequency; map MITRE ATT&CK for enrichment.
Automate with a Playbook
Playbooks (Logic Apps) trigger actions on incidents: IP blocking, Teams notifications, etc. Integrate via Sentinel's Playbooks tab.
Simple Notification Playbook
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Send_Teams_Notification": {
"type": "Http",
"inputs": {
"uri": "https://outlook.office.com/webhook/...",
"body": {
"text": "@channel Incident Sentinel: @{body('When_a_response_to_an_Incident_is_triggered')?['name']}"
}
}
}
},
"triggers": {
"When_a_response_to_an_Incident_is_triggered": {
"type": "ApiConnectionWebhook",
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['microsoftsecurityinsights']['connectionId']"
}
},
"path": "/subscriptions/@{encodeURIComponent('...')}/.../providers/Microsoft.SecurityInsights/playbooks/@{encodeURIComponent('notify-playbook')}/run"
}
}
}
}
}JSON definition for a Logic App playbook to notify Teams on incidents. Replace placeholders with your IDs. Associate with the rule via Automation Rules. Pitfall: Use managed connections to avoid hardcoded creds; test in preview mode.
Cost Monitoring Script
param([string]$ResourceGroupName = 'rg-sentinel-prod')
$Workspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName $ResourceGroupName
$Usage = Get-AzOperationalInsightsWorkspaceUsage -ResourceGroupName $ResourceGroupName -Name $Workspace.Name | Where-Object DataType -eq 'Usage'
$DailyIngestionGB = ($Usage | Measure-Object -Property Quantity -Sum).Sum / 1000
$CostEstimate = $DailyIngestionGB * 2.5 # ~2.5$/GB/mois
Write-Output "Ingestion quotidienne : ${DailyIngestionGB} GB | Coût mensuel estimé : `$$CostEstimate"
if ($DailyIngestionGB -gt 100) { Write-Warning 'Optimisez les rétention/filtres !' }Monitors ingestion and estimates costs (based on 2026 pricing). Run daily via Azure Automation. Pitfall: Filter DataType='Usage'; implement budget alerts to avoid surprises.
Best Practices
- Separate environments: Dev/test/prod workspaces to isolate costs and testing.
- Optimize KQL: Use
take 1000in dev,summarizeearly to scale to billions of rows. - Strict RBAC: Assign minimal roles (Sentinel Reader for analysts, Contributor for ops).
- Fusion rules: Enable to correlate multi-sources and reduce false positives by 40%.
- Backup queries: Export rules to Git for IaC.
Common Errors to Avoid
- Explosive ingestion: Connectors enabled without filters → 10x costs; test with
where TimeGenerated > ago(1h). - False positives: Thresholds too low in rules → analyst fatigue; use ML anomaly detection.
- No retention: Default 30 days → adjust to 90-365 days per compliance (GDPR/SOX).
- Forget UEBA: Enable for anomalous behaviors; without it, insider threats go undetected.
Next Steps
Dive deeper with Learni training on Microsoft Sentinel. Resources: Official KQL Docs, Azure Sentinel GitHub, MITRE ATT&CK for Sentinel. Implement advanced SOAR with Custom Connectors and UEBA for SOC maturity level 3.