Beginner โฑ 60 min ๐Ÿ“‹ 10 Steps

Deploy Microsoft Sentinel & Ingest Identity Logs

Provision a Log Analytics workspace, deploy Microsoft Sentinel, configure the Microsoft Entra ID data connector, verify log ingestion with KQL, and create your first analytics rule to detect suspicious sign-in patterns.

๐Ÿ“‹ Overview

About This Lab

In this hands-on lab you will build a fully operational Microsoft Sentinel deployment from scratch. Starting with a dedicated resource group and Log Analytics workspace, you will onboard Sentinel, connect your Microsoft Entra ID tenant to stream identity telemetry, explore sign-in and audit log schemas using KQL, and create a scheduled analytics rule that detects brute-force credential attacks. By the end of this lab you will have a working cloud-native SIEM that actively monitors identity-based threats.

๐Ÿข Enterprise Use Case

A mid-size financial services company with 2,500 employees operates a hybrid identity infrastructure spanning on-premises Active Directory and Microsoft Entra ID. Their security team has identified gaps in visibility: credential-stuffing attacks against employee accounts go undetected for days, conditional access policy violations are only discovered during quarterly audits, and suspicious access patterns from unfamiliar geolocations are not flagged in real time. The CISO has mandated centralized security monitoring to detect credential attacks, policy violations, and anomalous access patterns. all funneled into a single pane of glass with automated alerting and incident management.

๐ŸŽฏ What You Will Learn

  1. Provision and configure a Log Analytics workspace for security data
  2. Deploy Microsoft Sentinel as your cloud-native SIEM
  3. Connect the Microsoft Entra ID data connector for identity telemetry
  4. Write KQL queries to explore sign-in and audit log schemas
  5. Understand ResultType codes and authentication failure patterns
  6. Create a scheduled analytics rule for brute-force detection
  7. Map entities for automated incident correlation
  8. Validate detections with controlled test events

๐Ÿ”‘ Why This Matters

Identity is the #1 attack vector in modern cybersecurity. Over 80% of breaches involve compromised credentials. from password spraying and credential stuffing to phishing-based token theft. Traditional on-premises SIEM solutions struggle with cloud-scale identity data and lack native integration with Microsoft Entra ID. Microsoft Sentinel provides a cloud-native SIEM & SOAR platform purpose-built for this challenge: it ingests identity logs at cloud scale, applies machine learning and analytics rules to detect attacks in real time, and orchestrates automated response through playbooks. Mastering Sentinel's identity monitoring capabilities is essential for any security operations team defending a Microsoft 365 or hybrid environment.

โš™๏ธ Prerequisites

  • Azure subscription . Owner or Contributor role at the subscription level (required to create resources and enable Sentinel)
  • Microsoft Entra ID P1 or P2 license . Required for sign-in log availability; sign-in logs are not generated on free-tier Entra ID
  • Security Administrator or Global Administrator role . Needed to configure diagnostic settings and grant permissions to the data connector
  • Basic familiarity with the Azure portal . You should be comfortable navigating resource groups, blades, and the search bar
  • Azure CLI (optional) . Install the Azure CLI if you prefer command-line provisioning
๐Ÿ’ก Pro Tip: Review the full prerequisites checklist in the official documentation before starting: Microsoft Sentinel prerequisites

Step 1 ยท Create a Resource Group

A resource group is a logical container that holds all the Azure resources for this lab. Using a dedicated resource group makes it easy to track costs, manage permissions, and clean up when you are finished.

Portal Instructions

  • Sign in to the Azure portal
  • Search for Resource groups in the top search bar and select it
  • Click + Create
  • Select your Subscription
  • Enter a Resource group name: rg-sentinel-lab
  • Select a Region close to your location (e.g., East US, West Europe)
  • Click Review + create, then Create

Azure CLI

# Set variables for reuse across all lab steps
RESOURCE_GROUP="rg-sentinel-lab"   # Logical container for all lab resources
LOCATION="eastus"                  # Azure region - choose one close to you

# Create the resource group
# --name        : Unique name within subscription; "rg-" prefix follows naming convention
# --location    : Datacenter region where metadata is stored
# --tags        : Key-value pairs for cost tracking and cleanup - filter by these later
# Expected output: JSON object with "provisioningState": "Succeeded"
az group create \
  --name $RESOURCE_GROUP \
  --location $LOCATION \
  --tags Environment=Lab Project=SentinelLab

PowerShell Alternative

# Set variables for reuse across all lab steps
$ResourceGroup = "rg-sentinel-lab"   # Logical container - all lab resources go here
$Location = "eastus"                 # Azure region - pick one near you for lower latency

# Create the resource group
# -Name     : Must be unique within the subscription
# -Location : Determines where resource group metadata is stored
# -Tag      : Hashtable of tags for filtering and cost management
# Expected output: ResourceGroupName, Location, ProvisioningState = Succeeded
New-AzResourceGroup `
  -Name $ResourceGroup `
  -Location $Location `
  -Tag @{ Environment = "Lab"; Project = "SentinelLab" }
๐Ÿ’ก Pro Tip: Always tag your lab resources with identifiers like Environment=Lab. This makes it trivially easy to find and delete them later using az group delete --name rg-sentinel-lab --yes --no-wait.

Step 2 ยท Create a Log Analytics Workspace

Microsoft Sentinel sits on top of a Log Analytics workspace, which is the underlying data store. All ingested security data. sign-in logs, audit logs, alerts, incidents. is stored here as tables that you query using KQL (Kusto Query Language).

Portal Instructions

  • In the Azure portal, search for Log Analytics workspaces
  • Click + Create
  • Select the subscription and resource group rg-sentinel-lab
  • Enter a name: law-sentinel-lab
  • Select the same region as your resource group
  • Click Review + create, then Create
  • After deployment, navigate to the workspace โ†’ Settings โ†’ Usage and estimated costs โ†’ Data Retention
  • Set retention to 90 days (default is 30 days; 90 days is included free with Sentinel)

Azure CLI

# Set variables - reuse these in subsequent steps
RESOURCE_GROUP="rg-sentinel-lab"
WORKSPACE_NAME="law-sentinel-lab"   # "law-" prefix = Log Analytics Workspace naming convention
LOCATION="eastus"                   # Must match the resource group region

# Create the Log Analytics workspace - this is the data store Sentinel sits on
# --retention-time 90 : Keep logs for 90 days (first 90 days free with Sentinel)
# --sku PerGB2018     : Pay-as-you-go pricing tier; best for lab/dev workloads
# Expected output: JSON with "provisioningState": "Succeeded"
az monitor log-analytics workspace create \
  --resource-group $RESOURCE_GROUP \
  --workspace-name $WORKSPACE_NAME \
  --location $LOCATION \
  --retention-time 90 \
  --sku PerGB2018

# Verify the workspace was created and confirm settings
# --query : JMESPath expression to extract specific fields into a clean table
# --output table : Formats output as a human-readable table
# Expected output: Table showing Name, Location, 90-day Retention, PerGB2018 SKU
az monitor log-analytics workspace show \
  --resource-group $RESOURCE_GROUP \
  --workspace-name $WORKSPACE_NAME \
  --query "{Name:name, Location:location, Retention:retentionInDays, Sku:sku.name}" \
  --output table
โš ๏ธ Important: Data retention beyond 90 days incurs additional costs. For production environments, carefully plan your retention based on regulatory requirements and budget. The first 90 days of retention are included free when Sentinel is enabled on the workspace. See Sentinel pricing for details.
๐Ÿ’ก Pro Tip: Use the PerGB2018 pricing tier for lab workloads. For high-volume production environments (500+ GB/day), consider Commitment Tiers to save up to 65% on ingestion costs.

Step 3 ยท Deploy Microsoft Sentinel

Microsoft Sentinel is enabled as a solution on top of your Log Analytics workspace. Once deployed, it adds the Sentinel blades. Incidents, Workbooks, Analytics, Hunting, Data Connectors, and more. to your workspace.

Portal Instructions

  • In the Azure portal, search for Microsoft Sentinel
  • Click + Create (or Add)
  • Select the workspace you just created: law-sentinel-lab
  • Click Add
  • Wait for the deployment to complete (typically 1ยท2 minutes)
  • Once deployed, explore the Sentinel Overview dashboard. note the widgets for Events, Alerts, and Incidents
  • Navigate through the left menu to familiarize yourself with: Incidents, Workbooks, Hunting, Data connectors, Analytics, and Automation

Azure CLI

# Install the Sentinel CLI extension (if not already installed)
# --upgrade : Updates to latest version if already present
az extension add --name sentinel --upgrade

# Get the workspace resource ID - needed for Sentinel onboarding
# --query id   : Extracts just the ARM resource ID string
# --output tsv : Returns plain text (no quotes) for use in variables
WORKSPACE_ID=$(az monitor log-analytics workspace show \
  --resource-group $RESOURCE_GROUP \
  --workspace-name $WORKSPACE_NAME \
  --query id --output tsv)

# Enable Microsoft Sentinel on the workspace
# --name "default"            : Standard onboarding state name
# --customer-managed-key false: Use Microsoft-managed encryption (standard for labs)
# This adds SIEM capabilities (Incidents, Analytics, Hunting, etc.) to your workspace
az sentinel onboarding-state create \
  --resource-group $RESOURCE_GROUP \
  --workspace-name $WORKSPACE_NAME \
  --name "default" \
  --customer-managed-key false

# Verify Sentinel is enabled
echo "Microsoft Sentinel has been enabled on workspace: $WORKSPACE_NAME"
๐Ÿ’ก Pro Tip: After enabling Sentinel, check the Content hub in the left menu. Microsoft provides 300+ out-of-the-box solutions including prebuilt analytics rules, workbooks, hunting queries, and playbooks. For this lab, we will build rules from scratch to understand the fundamentals. but in production, always start with the Content hub.

Step 4 ยท Configure the Microsoft Entra ID Data Connector

The Microsoft Entra ID (formerly Azure Active Directory) data connector streams identity telemetry into your Sentinel workspace. This includes sign-in logs (interactive and non-interactive), audit logs, provisioning logs, and managed identity sign-in logs.

Portal Instructions

  • In Microsoft Sentinel, navigate to Content hub in the left menu
  • Search for Microsoft Entra ID and select the solution
  • Click Install (or Update if already installed) . this installs the data connector, workbooks, and analytics rules
  • After installation, navigate to Data connectors in the left menu
  • Search for Microsoft Entra ID and click on the connector
  • Click Open connector page
  • Under Configuration, check the following log types:
    • Sign-in logs . Interactive user sign-ins
    • Audit logs . Directory changes and admin activities
    • Non-interactive user sign-in logs (optional but recommended)
    • Service principal sign-in logs (optional but recommended)
  • Click Apply Changes
  • Wait for the status to change to Connected (green indicator)
  • Verify in the Data received graph that data points start appearing
โš ๏ธ Important: You must have Security Administrator or Global Administrator role in Microsoft Entra ID to configure the diagnostic settings. Additionally, a Microsoft Entra ID P1 or P2 license is required. sign-in logs are not available on free-tier tenants.

Alternative: Diagnostic Settings (Manual)

If the data connector does not configure automatically, you can set up diagnostic settings directly:

  • Navigate to Microsoft Entra ID โ†’ Diagnostic settings
  • Click + Add diagnostic setting
  • Name: sentinel-identity-logs
  • Check: SignInLogs, AuditLogs, NonInteractiveUserSignInLogs
  • Destination: Send to Log Analytics workspace โ†’ select law-sentinel-lab
  • Click Save
๐Ÿ’ก Pro Tip: For full documentation on connecting Entra ID, see: Connect Microsoft Entra ID data to Microsoft Sentinel

Step 5 ยท Verify Data Ingestion with KQL

Before building detections, confirm that identity log data is flowing into your workspace. Open the Logs blade in Sentinel (or directly in your Log Analytics workspace) and run the following KQL queries.

Query 1: Verify Sign-in Logs

// Retrieve the 10 most recent sign-in log entries
// PURPOSE: Verify that sign-in data is flowing into the workspace
// If this returns 0 results, the Entra ID connector is not yet active
SigninLogs
| take 10                         // Grab any 10 rows (fastest way to verify data exists)
| project
    TimeGenerated,                // UTC timestamp of the authentication event
    UserPrincipalName,            // User's email-style identity (e.g., user@contoso.com)
    ResultType,                   // Error code: 0 = success, 50126 = bad password, etc.
    ResultDescription,            // Human-readable text for the ResultType code
    IPAddress,                    // Source IP of the sign-in request
    AppDisplayName,               // Target app (e.g., "Azure Portal", "Microsoft Teams")
    Location,                     // Geo-location derived from IPAddress
    ClientAppUsed,                // Auth protocol: "Browser", "Mobile Apps", "IMAP", etc.
    ConditionalAccessStatus       // "success", "failure", or "notApplied"

Query 2: Verify Audit Logs

// Retrieve the 10 most recent audit log entries
// PURPOSE: Verify that directory change/admin activity data is being ingested
// AuditLogs capture admin actions like user creation, role changes, app registrations
AuditLogs
| take 10                         // Grab any 10 rows to confirm data flow
| project
    TimeGenerated,                // UTC timestamp of the directory operation
    OperationName,                // Action performed (e.g., "Add user", "Update policy")
    Result,                       // "success" or "failure" - track admin action outcomes
    InitiatedBy,                  // Who/what triggered it (user UPN or app/service principal)
    TargetResources,              // The object acted upon (user, group, app, role, etc.)
    Category                      // Category grouping: "UserManagement", "Policy", etc.

Query 3: Check Ingestion Volume

// Check how many records have been ingested in the last 24 hours
// PURPOSE: Validate data volume and confirm both log types are actively flowing
// A healthy tenant typically generates hundreds to thousands of sign-ins/day
union SigninLogs, AuditLogs       // Combine both tables into a single result set
| where TimeGenerated > ago(24h)  // Filter to only the last 24 hours
| summarize
    TotalRecords = count(),                       // Total events across both tables
    SignIns = countif(Type == "SigninLogs"),       // Count of authentication events only
    Audits = countif(Type == "AuditLogs")          // Count of directory change events only
| project TotalRecords, SignIns, Audits
// Expected output: Single row with three columns showing ingestion counts
// If SignIns = 0, check Entra ID diagnostic settings and P1/P2 license
// If Audits = 0, verify AuditLogs checkbox is enabled in the data connector
โš ๏ธ Important: It can take 5ยท15 minutes for the first logs to appear after enabling the data connector. If you see no results, wait and try again. In some tenants, initial ingestion can take up to 30 minutes. You can verify the connector status in the Data connectors blade. look for a green "Connected" status and a non-zero "Data received" graph.
๐Ÿ’ก Pro Tip: If data is not appearing, go to the Log Analytics workspace โ†’ Tables and search for SigninLogs. If the table does not exist, the diagnostic settings may not have been applied correctly. Re-check Step 4.

Step 6 ยท Explore the Sign-in Log Schema

Understanding the schema is critical for writing effective detection rules. The SigninLogs table contains rich telemetry about every authentication event. Let's explore its structure and key fields.

Query: Get the Full Schema

// List all columns in the SigninLogs table
// PURPOSE: Discover every available field for building detection queries
// This is essential before writing KQL - know what data you have to work with
SigninLogs
| getschema                       // Returns metadata about the table structure (not data)
| project ColumnName, ColumnType, DataType  // Show column name, KQL type, and storage type
| order by ColumnName asc         // Alphabetical for easy reference
// Expected output: ~40+ columns including TimeGenerated, UserPrincipalName,
// ResultType, IPAddress, LocationDetails, ConditionalAccessStatus, MfaDetail, etc.

Key Fields Reference

Field Description
TimeGeneratedUTC timestamp of the sign-in event
UserPrincipalNameThe user's UPN (email-style identifier)
ResultTypeNumeric error code (0 = success)
ResultDescriptionHuman-readable description of the result
IPAddressSource IP of the authentication request
LocationGeolocation (country/city) from the IP
AppDisplayNameApplication the user signed into
ClientAppUsedClient protocol (browser, mobile app, etc.)
ConditionalAccessStatusConditional Access evaluation result
RiskLevelDuringSignInRisk level at sign-in time (none, low, medium, high)
MfaDetailMFA method and result details

Critical ResultType Codes

Code Meaning Security Relevance
0SuccessSuccessful authentication
50126Invalid username or passwordBrute force / credential stuffing indicator
50053Account lockedLockout due to too many failed attempts
53003Blocked by Conditional AccessCA policy enforcement. may indicate policy bypass attempts
50076MFA requiredUser has not completed MFA challenge
50074Strong auth requiredMFA challenge was issued
50140Keep me signed in interruptUser was prompted for KMSI
๐Ÿ’ก Pro Tip: Bookmark the full sign-in log schema reference: SigninLogs table reference. The complete list of Entra ID error codes is available at Entra ID error codes reference.

Step 7 ยท Write a Failed Sign-in Detection Query

Now that you understand the schema, let's write KQL queries to detect brute-force sign-in attacks. We'll start with a basic detection and then add context for richer incident data.

Query 1: Basic Brute Force Detection

This query identifies users with 10 or more failed sign-in attempts within a 1-hour window. a strong indicator of credential brute-forcing or password spraying.

// Brute Force Detection: 10+ failed sign-ins per user in 1 hour
// PURPOSE: Identify accounts under active credential attack
// MITRE ATT&CK: T1110 - Brute Force
// WHY: Attackers automate password guessing; 10+ failures in 1h is abnormal
SigninLogs
| where TimeGenerated > ago(1h)                    // Look at the last hour only
| where ResultType in ("50126", "50053", "50074")  // Filter to authentication failures:
  // 50126 = Invalid username or password (most common brute-force indicator)
  // 50053 = Account is locked (lockout triggered by too many failures)
  // 50074 = Strong authentication required (MFA challenge issued but not completed)
| summarize
    FailedAttempts = count(),                  // Total failed attempts per user
    DistinctIPs = dcount(IPAddress),           // Unique source IPs - >1 suggests distributed attack
    IPAddresses = make_set(IPAddress, 10),     // Collect up to 10 unique IPs for investigation
    Applications = make_set(AppDisplayName, 5),// Which apps were targeted (Portal, Teams, etc.)
    FirstAttempt = min(TimeGenerated),         // When the attack started
    LastAttempt = max(TimeGenerated)            // Most recent attempt
  by UserPrincipalName                         // Group by targeted user account
| where FailedAttempts >= 10                   // Threshold: 10+ failures = likely attack
| sort by FailedAttempts desc                  // Most-attacked accounts first
// Expected output: Users under attack with source IPs, apps, and timeline
// ACTION: Investigate high-count users; check if a success followed the failures

Query 2: Enriched with Location Context

This enriched version adds geolocation data and checks whether a successful sign-in followed the failures. a critical indicator of account compromise.

// Enriched Brute Force Detection with Location and Success Check
// PURPOSE: Detect brute-force attacks AND check if the attacker succeeded
// WHY: Failures alone are noisy - failures FOLLOWED BY success = likely compromise
// MITRE ATT&CK: T1110 - Brute Force (with post-compromise correlation)
let threshold = 10;       // Min failed attempts to trigger - tune based on your environment
let timeWindow = 1h;      // Detection window - 1 hour balances speed vs. noise
//
// STEP 1: Find users with excessive failed sign-ins
let failedSignIns = SigninLogs
| where TimeGenerated > ago(timeWindow)
| where ResultType in ("50126", "50053")    // 50126 = bad password, 50053 = account locked
| summarize
    FailedAttempts = count(),                // Total failures per user
    DistinctIPs = dcount(IPAddress),         // Multiple IPs = distributed/botnet attack
    IPAddresses = make_set(IPAddress, 10),   // Source IPs for threat intel lookups
    Locations = make_set(Location, 10),      // Geographic origins of the attack
    Applications = make_set(AppDisplayName, 5), // Targeted applications
    FirstAttempt = min(TimeGenerated),       // Attack start time
    LastAttempt = max(TimeGenerated)          // Attack end time
  by UserPrincipalName
| where FailedAttempts >= threshold;         // Only users exceeding the threshold
//
// STEP 2: Check if ANY of those users also had a successful sign-in
let successfulSignIns = SigninLogs
| where TimeGenerated > ago(timeWindow)
| where ResultType == "0"                   // ResultType 0 = successful authentication
| summarize SuccessCount = count(), SuccessIPs = make_set(IPAddress, 5) by UserPrincipalName;
//
// STEP 3: Correlate - join failures with successes to find compromised accounts
failedSignIns
| join kind=leftouter (successfulSignIns) on UserPrincipalName  // leftouter: keep all failures
| extend FollowedBySuccess = iff(isnotempty(SuccessCount), true, false) // Flag compromises
| project
    UserPrincipalName,
    FailedAttempts,
    DistinctIPs,
    IPAddresses,
    Locations,
    Applications,
    FirstAttempt,
    LastAttempt,
    FollowedBySuccess,   // TRUE = CRITICAL: attacker likely guessed the password
    SuccessIPs           // IP that succeeded - compare with FailedIPs for attribution
| sort by FollowedBySuccess desc, FailedAttempts desc
// Expected output: Users sorted by risk - FollowedBySuccess=true at top
// ACTION: Immediately investigate FollowedBySuccess=true rows - reset password & revoke sessions

Threshold Tuning Guidance

  • 10 failures/hour . Good starting point; catches aggressive brute-force attacks while avoiding noise from users who simply mistype passwords
  • 5 failures/hour . More sensitive; may generate false positives in organizations with complex passwords or frequent password changes
  • 20+ failures/hour . Lower sensitivity; focuses on high-confidence automated attacks but may miss slow-and-low credential attacks
  • Consider adding dcount(IPAddress) > 3 as an additional filter. distributed attacks from multiple IPs are more suspicious than a single user retrying from one device
๐Ÿ’ก Pro Tip: The FollowedBySuccess field is critical in triage. Failed attempts followed by a success may indicate a compromised account . the attacker guessed the correct password. Prioritize these incidents for immediate investigation.

Step 8 ยท Create a Scheduled Analytics Rule

Now let's turn the KQL query into a scheduled analytics rule that automatically creates incidents when brute-force attacks are detected.

Portal Instructions

  • In Microsoft Sentinel, navigate to Analytics in the left menu
  • Click + Create โ†’ Scheduled query rule

Tab 1: General

  • Name: Brute Force Detection. Multiple Failed Sign-ins
  • Description: Detects accounts with 10 or more failed sign-in attempts within a 1-hour window, indicating potential brute-force or password spray attacks. Enriched with source IP, geolocation, and success-after-failure correlation.
  • Severity: Medium
  • MITRE ATT&CK: Initial Access โ†’ T1110. Brute Force
  • Status: Enabled

Tab 2: Set Rule Logic

Paste the following KQL query into the Rule query field:

// Analytics Rule Query: Brute Force Detection
// This query runs on a schedule (every 1h) and generates alerts automatically
// MITRE ATT&CK: T1110 - Brute Force
SigninLogs
| where ResultType in ("50126", "50053")    // 50126 = wrong password, 50053 = locked out
| summarize
    FailedAttempts = count(),                // Total failures - used for threshold check
    DistinctIPs = dcount(IPAddress),         // Unique IPs - distributed attacks use many
    IPAddresses = make_set(IPAddress, 10),   // Collect IPs for entity mapping in incidents
    Locations = make_set(Location, 10),      // Geo data for investigation context
    Applications = make_set(AppDisplayName, 5), // Which apps were targeted
    FirstAttempt = min(TimeGenerated),       // Attack window start
    LastAttempt = max(TimeGenerated)          // Attack window end
  by UserPrincipalName                       // One row per targeted user
| where FailedAttempts >= 10                 // Alert threshold - tune for your environment
// Sentinel Entity Mapping: Account โ†’ UserPrincipalName, IP โ†’ IPAddresses

Query Scheduling

  • Run query every: 1 hour
  • Lookup data from the last: 1 hour

Alert Threshold

  • Generate alert when number of query results: Is greater than 0

Entity Mapping

Entity mapping enables Sentinel to correlate entities across incidents and power the investigation graph. Configure the following mappings:

  • Account โ†’ Identifier: FullName โ†’ Column: UserPrincipalName
  • IP โ†’ Identifier: Address โ†’ Column: IPAddresses

Tab 3: Incident Settings

  • Incident creation: Enabled
  • Alert grouping: Enabled. Group related alerts into a single incident
  • Group alerts triggered by this analytics rule into a single incident by: Grouping alerts into a single incident if the selected entities match โ†’ Account
  • Re-open closed matching incidents: Enabled
  • Limit group to alerts created within: 24 hours

Tab 4: Automated Response (Optional)

  • For this lab, skip automation rules (we will cover playbooks in a future lab)
  • In production, consider adding automation to: send Teams notification, block user, require MFA step-up
  • Click Review + create
  • Review all settings and click Create
  • Verify the rule appears in the Analytics blade with status Enabled
๐Ÿ’ก Pro Tip: After creating the rule, click on it and select Run to test it immediately against historical data. This does not wait for the next scheduled run and helps you validate that the query returns the expected results.

Step 9 ยท Validate the Detection

With the analytics rule in place, let's generate controlled test events and verify that Sentinel creates an incident.

Generate Test Events

  • Open a private/incognito browser window
  • Navigate to https://portal.azure.com or https://myapps.microsoft.com
  • Enter a valid username from your tenant (e.g., a test account)
  • Enter an incorrect password . repeat this 10+ times within a few minutes
  • Each failed attempt generates a SigninLogs entry with ResultType = 50126
โš ๏ธ Important: Use a dedicated test account for this exercise, not a production admin account. Repeated failed sign-ins may trigger account lockout policies or Conditional Access blocks depending on your tenant configuration. If your tenant has Smart Lockout enabled, the account may be temporarily locked after ~10 attempts.

Verify KQL Results

After waiting 5ยท15 minutes for log ingestion, run this query to confirm your test events appear:

// Check for your test events - run this after generating failed sign-ins
// PURPOSE: Confirm test data appeared in the SigninLogs table
// Wait 5-15 min after test attempts for log ingestion latency
SigninLogs
| where TimeGenerated > ago(1h)              // Last hour - matches the analytics rule window
| where ResultType == "50126"                // 50126 = invalid password (our test scenario)
| summarize FailedAttempts = count()         // Count failures per user+IP combination
    by UserPrincipalName, IPAddress
| where FailedAttempts >= 10                 // Same threshold as the analytics rule
| sort by FailedAttempts desc
// Expected output: Your test account + your IP address with 10+ failures
// If empty: wait longer or check that test failures used a valid tenant UPN

Check the Incidents Blade

  • Navigate to Microsoft Sentinel โ†’ Incidents
  • Look for a new incident titled "Brute Force Detection. Multiple Failed Sign-ins"
  • Click the incident to open the detail pane
  • Review: severity, entity mapping, timeline, and alert details
  • Click Investigate to open the Investigation Graph

Explore the Investigation Graph

  • The investigation graph visually maps relationships between entities (users, IPs, hosts)
  • Expand the Account node to see related alerts and activities
  • Expand the IP node to check if the same IP is associated with other suspicious activity
  • This graph is powered by the entity mappings you configured in Step 8
๐Ÿ’ก Pro Tip: If the incident does not appear immediately, remember that the analytics rule runs on a schedule (every 1 hour). You can force an immediate evaluation by selecting the rule in the Analytics blade and clicking Run. Alternatively, reduce the run frequency to every 5 minutes for testing (but remember to set it back to 1 hour for production use).

Step 10 ยท Review & Clean Up

What You Built

Congratulations! In this lab you have built a complete identity threat detection pipeline:

  • A dedicated resource group for organized resource management
  • A Log Analytics workspace with 90-day retention for security data
  • Microsoft Sentinel deployed as your cloud-native SIEM
  • The Microsoft Entra ID data connector streaming sign-in and audit logs
  • KQL proficiency for exploring identity log schemas and writing detections
  • A scheduled analytics rule for brute-force detection mapped to MITRE T1110
  • Entity mappings for automated incident correlation
  • A validated detection with a real incident in the Incidents blade

๐Ÿ’ฐ Cost Estimation

  • Log Analytics ingestion: ~$2.76/GB (Pay-As-You-Go). A small tenant generates approximately 100 MBยท1 GB/day of identity logs
  • Sentinel: ~$2.46/GB on top of Log Analytics ingestion costs
  • Estimated daily cost for a small lab: $0.50ยท$5.00 depending on log volume
  • Free tier: The first 10 GB/day of data ingestion is free for the first 31 days on new workspaces
  • Use the Azure Pricing Calculator for precise estimates

๐Ÿงน Clean Up Resources

If this is a lab environment and you want to avoid ongoing charges, delete all resources:

# Delete the entire resource group and all resources within it
# WARNING: This permanently deletes the workspace, Sentinel, all data, and all rules
# --yes     : Skip the confirmation prompt (use cautiously)
# --no-wait : Return immediately - deletion continues in the background
az group delete \
  --name rg-sentinel-lab \
  --yes \
  --no-wait

# Verify the deletion is in progress
# Expected output: "Deleting" while in progress, error when fully deleted
az group show --name rg-sentinel-lab --query "properties.provisioningState" --output tsv
โš ๏ธ Important: If you are using this in a production environment, do not delete the resource group. Instead, consider disabling the analytics rule or reducing the data connector scope to control costs. Navigate to Analytics โ†’ select the rule โ†’ click Disable.

๐Ÿš€ Next Steps

  • Explore the Content hub for prebuilt Microsoft Entra ID analytics rules and workbooks
  • Build additional detections for impossible travel, new MFA method registration, and privilege escalation
  • Create a Logic App playbook to auto-respond when brute-force incidents are triggered
  • Configure workbooks for executive dashboards showing identity threat trends
๐Ÿ’ก Pro Tip: Even for lab environments, keep the workspace running for a few days to accumulate enough data for meaningful KQL practice. A workspace with 3ยท7 days of identity logs provides excellent query exploration opportunities. especially if you sign in from different devices, locations, and applications.

๐Ÿ“š Documentation Resources

ResourceDescription
Microsoft Sentinel documentationComprehensive product docs covering all Sentinel capabilities
KQL quick referenceCheat sheet for Kusto Query Language operators and functions
Entra ID sign-in log schema (SigninLogs table)Full column reference for the SigninLogs table
Create custom analytics rulesBest practices for scheduled query rules in Sentinel
Microsoft Sentinel best practicesOperational best practices for production deployments
Azure Pricing CalculatorEstimate costs for Log Analytics and Sentinel
Connect Microsoft Entra ID to SentinelData connector setup guide
Entra ID authentication error codesComplete list of ResultType codes and their meanings

Summary

What You Accomplished

  • Created a Log Analytics workspace for centralised security log collection
  • Deployed Microsoft Sentinel on top of the workspace
  • Connected data sources using built-in and custom data connectors
  • Configured analytics rules for automated threat detection
  • Set up alert notifications for security operations workflows

Next Steps

โ† All Labs Next Lab โ†’