← Back to Learning Portal

AZ-500 Study Manual

Exam study guide for Azure Security Engineer Associate.

📘 AZ-500 EXAM STUDY GUIDE 2026

Comprehensive Guide with PowerShell/CLI Labs and Checklists

Exam: AZ-500 — Microsoft Azure Security Engineer Associate
Format: Deep-dive reference with hands-on labs and skill checklists

WEEK 1 STUDY GUIDE: IDENTITY AND ACCESS

Domain 1 Deep Dive — Manage Identity and Access

Skill Checklist: Microsoft Entra ID

  • [ ] Explain the difference between Entra ID Free, P1, and P2 licences
  • [ ] Create and manage users, groups, and group membership rules
  • [ ] Configure guest access and external collaboration settings
  • [ ] Understand device states: registered, joined, hybrid joined
  • [ ] Configure SSPR (Self-Service Password Reset)
  • [ ] Explain Entra Connect sync methods (PHS, PTA, Federation)

Skill Checklist: Azure RBAC

  • [ ] List and explain all built-in roles with their boundaries
  • [ ] Create a custom role using JSON or PowerShell
  • [ ] Assign a role at different scopes (MG, subscription, RG, resource)
  • [ ] Understand deny assignments and when they apply
  • [ ] Configure resource locks (ReadOnly, CanNotDelete)
  • [ ] Audit role assignments using Azure Policy or Log Analytics

Skill Checklist: Managed Identities

  • [ ] Enable system-assigned managed identity on a VM
  • [ ] Create a user-assigned managed identity
  • [ ] Grant Key Vault access to a managed identity
  • [ ] Use managed identity to access a storage account from App Service

Lab 1A: RBAC Custom Role — PowerShell

# Get the subscription ID
$subId = (Get-AzContext).Subscription.Id

# Define the custom role
$role = @{
    Name = "VM Start/Stop Operator"
    Description = "Can start and stop virtual machines but cannot manage them."
    Actions = @(
        "Microsoft.Compute/virtualMachines/start/action",
        "Microsoft.Compute/virtualMachines/deallocate/action",
        "Microsoft.Compute/virtualMachines/read"
    )
    NotActions = @()
    DataActions = @()
    NotDataActions = @()
    AssignableScopes = @("/subscriptions/$subId")
}

# Create the role
$roleDefinition = New-AzRoleDefinition -Role $role
Write-Host "Created role: $($roleDefinition.Name)"

# Assign the role to a user
New-AzRoleAssignment `
    -SignInName "user@contoso.com" `
    -RoleDefinitionName "VM Start/Stop Operator" `
    -Scope "/subscriptions/$subId/resourceGroups/prod-rg"

Lab 1B: Managed Identity + Key Vault — CLI

# Create a user-assigned managed identity
az identity create \
  --name "app-identity" \
  --resource-group "security-rg"

# Get the identity's principal ID
PRINCIPAL_ID=$(az identity show \
  --name "app-identity" \
  --resource-group "security-rg" \
  --query principalId --output tsv)

# Assign Key Vault Secrets User role to the identity
az role assignment create \
  --assignee "$PRINCIPAL_ID" \
  --role "Key Vault Secrets User" \
  --scope "/subscriptions/{sub}/resourceGroups/security-rg/providers/Microsoft.KeyVault/vaults/myvault"

# Assign the identity to an App Service
az webapp identity assign \
  --resource-group "security-rg" \
  --name "mywebapp" \
  --identities "/subscriptions/{sub}/resourceGroups/security-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/app-identity"

Lab 2A: Conditional Access Policy — PowerShell (Graph)

# Install required module
Install-Module Microsoft.Graph -Scope CurrentUser

# Connect
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"

# Create a Conditional Access policy requiring MFA for all users on Azure Portal
$policy = @{
    displayName = "Require MFA for Azure Portal"
    state = "enabled"
    conditions = @{
        users = @{
            includeUsers = @("All")
            excludeUsers = @("emergency-admin@contoso.com")  # Break-glass account
        }
        applications = @{
            includeApplications = @("797f4846-ba00-4fd7-ba43-dac1f8f63013")  # Azure Management
        }
    }
    grantControls = @{
        operator = "OR"
        builtInControls = @("mfa")
    }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

Lab 2B: PIM Role Assignment — PowerShell

# Connect to Microsoft Graph with PIM permissions
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"

# Get the role definition ID for "Security Reader"
$roleDef = Get-MgRoleManagementDirectoryRoleDefinition `
    -Filter "displayName eq 'Security Reader'"

# Get the user
$user = Get-MgUser -Filter "userPrincipalName eq 'alice@contoso.com'"

# Create an eligible PIM assignment
New-MgRoleManagementDirectoryRoleEligibilityScheduleRequest -BodyParameter @{
    action = "AdminAssign"
    justification = "Security team member needs eligible Security Reader role"
    roleDefinitionId = $roleDef.Id
    directoryScopeId = "/"
    principalId = $user.Id
    scheduleInfo = @{
        startDateTime = (Get-Date).ToUniversalTime().ToString("o")
        expiration = @{
            type = "noExpiration"
        }
    }
}
Write-Host "Eligible assignment created for $($user.UserPrincipalName)"

WEEK 2 STUDY GUIDE: SECURE NETWORKING

Domain 2 Deep Dive — Secure Networking

Skill Checklist: NSGs

  • [ ] Create an NSG with inbound and outbound rules
  • [ ] Understand default rules and priority evaluation
  • [ ] Configure Application Security Groups (ASGs)
  • [ ] Enable NSG Flow Logs and Traffic Analytics
  • [ ] Associate NSG with subnet and NIC

Skill Checklist: Azure Firewall

  • [ ] Deploy Azure Firewall in a hub VNet
  • [ ] Create DNAT, Network, and Application rules
  • [ ] Configure threat intelligence in Alert and Deny mode
  • [ ] Create a Firewall Policy with parent-child hierarchy
  • [ ] Route spoke VNet traffic through the firewall (UDR)

Skill Checklist: WAF + DDoS

  • [ ] Deploy Application Gateway with WAF_v2 SKU
  • [ ] Configure WAF in Prevention mode
  • [ ] Create a custom WAF rule
  • [ ] Enable DDoS Network Protection on a VNet
  • [ ] Understand DDoS mitigation telemetry

Lab 3A: Deploy Azure Firewall — CLI

# Create VNet with firewall subnet
az network vnet create \
  --resource-group security-rg \
  --name hub-vnet \
  --address-prefixes 10.0.0.0/16 \
  --subnet-name AzureFirewallSubnet \
  --subnet-prefixes 10.0.0.0/26

# Create public IP for firewall
az network public-ip create \
  --resource-group security-rg \
  --name fw-pip \
  --sku Standard \
  --allocation-method Static

# Create Azure Firewall
az network firewall create \
  --resource-group security-rg \
  --name hub-firewall \
  --location eastus \
  --sku-tier Standard

# Configure firewall IP
az network firewall ip-config create \
  --firewall-name hub-firewall \
  --resource-group security-rg \
  --name fw-ipconfig \
  --public-ip-address fw-pip \
  --vnet-name hub-vnet

# Get firewall private IP
FW_PRIVATE_IP=$(az network firewall show \
  --resource-group security-rg \
  --name hub-firewall \
  --query "ipConfigurations[0].privateIPAddress" -o tsv)

# Create application rule collection (allow Windows Update)
az network firewall application-rule create \
  --resource-group security-rg \
  --firewall-name hub-firewall \
  --collection-name "AllowWindowsUpdate" \
  --priority 200 \
  --action Allow \
  --name "WindowsUpdate" \
  --protocols Http=80 Https=443 \
  --fqdn-tags WindowsUpdate

# Create network rule (allow DNS)
az network firewall network-rule create \
  --resource-group security-rg \
  --firewall-name hub-firewall \
  --collection-name "AllowDNS" \
  --priority 100 \
  --action Allow \
  --name "DNS" \
  --protocols UDP \
  --source-addresses "*" \
  --destination-fqdns "*.dns.azure.com" \
  --destination-ports 53

# Create route table to force traffic through firewall
az network route-table create \
  --resource-group security-rg \
  --name spoke-rt

az network route-table route create \
  --resource-group security-rg \
  --route-table-name spoke-rt \
  --name DefaultRoute \
  --address-prefix 0.0.0.0/0 \
  --next-hop-type VirtualAppliance \
  --next-hop-ip-address $FW_PRIVATE_IP

Lab 3B: NSG with ASGs — PowerShell

$rg = "security-rg"
$location = "eastus"

# Create Application Security Groups
$webASG = New-AzApplicationSecurityGroup `
    -ResourceGroupName $rg `
    -Name "WebServers-ASG" `
    -Location $location

$dbASG = New-AzApplicationSecurityGroup `
    -ResourceGroupName $rg `
    -Name "DatabaseServers-ASG" `
    -Location $location

# Create NSG
$nsg = New-AzNetworkSecurityGroup `
    -ResourceGroupName $rg `
    -Name "app-nsg" `
    -Location $location

# Add rule: Allow web traffic from internet to web servers
$nsg | Add-AzNetworkSecurityRuleConfig `
    -Name "Allow-HTTP-HTTPS-Inbound" `
    -Priority 100 `
    -Direction Inbound `
    -Access Allow `
    -Protocol Tcp `
    -SourceAddressPrefix Internet `
    -DestinationApplicationSecurityGroup $webASG `
    -DestinationPortRange @(80, 443) | Set-AzNetworkSecurityGroup

# Add rule: Allow SQL from web servers to database servers only
$nsg | Add-AzNetworkSecurityRuleConfig `
    -Name "Allow-SQL-from-Web" `
    -Priority 200 `
    -Direction Inbound `
    -Access Allow `
    -Protocol Tcp `
    -SourceApplicationSecurityGroup $webASG `
    -DestinationApplicationSecurityGroup $dbASG `
    -DestinationPortRange 1433 | Set-AzNetworkSecurityGroup

Write-Host "NSG with ASGs created successfully"

WEEK 3 STUDY GUIDE: COMPUTE, STORAGE, AND DATABASE SECURITY

Domain 3 Deep Dive — Secure Compute, Storage, and Databases

Skill Checklist: Azure Key Vault

  • [ ] Create a Key Vault with RBAC access model
  • [ ] Store and retrieve secrets, keys, and certificates
  • [ ] Enable soft-delete and purge protection
  • [ ] Configure Key Vault firewall with private endpoint
  • [ ] Rotate a key manually and configure auto-rotation

Skill Checklist: Storage Security

  • [ ] Generate a User Delegation SAS token
  • [ ] Configure storage firewall with VNet integration
  • [ ] Assign RBAC data roles for blob access
  • [ ] Enable Customer-Managed Keys (CMK) for storage
  • [ ] Configure immutable storage policies

Skill Checklist: SQL Database Security

  • [ ] Enable Transparent Data Encryption with CMK
  • [ ] Configure Dynamic Data Masking rules
  • [ ] Enable Microsoft Defender for SQL
  • [ ] Configure auditing to Log Analytics
  • [ ] Set up Always Encrypted for a column

Lab 4A: Azure Key Vault — Full Setup

$rg = "security-rg"
$location = "eastus"
$vaultName = "my-kv-$(Get-Random -Max 9999)"

# Create Key Vault with RBAC access model and purge protection
$vault = New-AzKeyVault `
    -ResourceGroupName $rg `
    -VaultName $vaultName `
    -Location $location `
    -Sku Standard `
    -EnableRbacAuthorization `  # Use RBAC model (not access policies)
    -EnableSoftDelete `
    -SoftDeleteRetentionInDays 90 `
    -EnablePurgeProtection

Write-Host "Created vault: $($vault.VaultName)"

# Assign 'Key Vault Administrator' role to yourself
$myId = (Get-AzADUser -UserPrincipalName (Get-AzContext).Account.Id).Id
New-AzRoleAssignment `
    -ObjectId $myId `
    -RoleDefinitionName "Key Vault Administrator" `
    -Scope $vault.ResourceId

# Create a secret
$secret = ConvertTo-SecureString "MySecretPassword123!" -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName $vaultName -Name "db-connection-string" -SecretValue $secret

# Create an RSA key
Add-AzKeyVaultKey -VaultName $vaultName -Name "encryption-key" -Destination Software -KeyType RSA -Size 2048

# Enable diagnostic logging
Set-AzDiagnosticSetting `
    -ResourceId $vault.ResourceId `
    -Name "kv-diagnostics" `
    -WorkspaceId "/subscriptions/{sub}/resourceGroups/security-rg/providers/Microsoft.OperationalInsights/workspaces/security-law" `
    -Enabled $true `
    -Category @("AuditEvent")

Lab 4B: Storage Security — User Delegation SAS

# Grant yourself Storage Blob Data Contributor (needed for user delegation SAS)
az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee "$(az account show --query user.name -o tsv)" \
  --scope "/subscriptions/{sub}/resourceGroups/security-rg/providers/Microsoft.Storage/storageAccounts/mystorageaccount"

# Generate User Delegation SAS (uses your Entra ID identity - most secure)
az storage blob generate-sas \
  --account-name mystorageaccount \
  --container-name mycontainer \
  --name myblob.txt \
  --permissions r \
  --expiry "$(date -u -d '1 hour' +%Y-%m-%dT%H:%MZ)" \
  --auth-mode login \
  --as-user \
  --https-only

# Configure storage firewall - deny all, allow specific VNet
az storage account update \
  --resource-group security-rg \
  --name mystorageaccount \
  --default-action Deny \
  --bypass AzureServices

# Add VNet rule (requires service endpoint on subnet)
az storage account network-rule add \
  --resource-group security-rg \
  --account-name mystorageaccount \
  --vnet-name "hub-vnet" \
  --subnet "app-subnet"

Lab 5: Azure SQL Database Security — PowerShell

$serverName = "my-sql-server"
$dbName = "my-database"
$rg = "security-rg"

# Enable Transparent Data Encryption (should be on by default)
Set-AzSqlDatabaseTransparentDataEncryption `
    -ResourceGroupName $rg `
    -ServerName $serverName `
    -DatabaseName $dbName `
    -State Enabled

# Enable Entra ID administrator (disables SQL auth for admins)
Set-AzSqlServerActiveDirectoryAdministrator `
    -ResourceGroupName $rg `
    -ServerName $serverName `
    -DisplayName "SQL-Admins-Group" `
    -ObjectId (Get-AzADGroup -DisplayName "SQL-Admins-Group").Id

# Enable Microsoft Defender for SQL
Set-AzSqlServerAdvancedDataSecurityPolicy `
    -ResourceGroupName $rg `
    -ServerName $serverName `
    -Enable $true

# Configure SQL auditing to Log Analytics
Set-AzSqlServerAudit `
    -ResourceGroupName $rg `
    -ServerName $serverName `
    -WorkspaceResourceId "/subscriptions/{sub}/resourceGroups/security-rg/providers/Microsoft.OperationalInsights/workspaces/security-law" `
    -State Enabled

# Add Dynamic Data Masking rule
New-AzSqlDatabaseDataMaskingRule `
    -ResourceGroupName $rg `
    -ServerName $serverName `
    -DatabaseName $dbName `
    -MaskingFunction "Email" `
    -SchemaName "dbo" `
    -TableName "Customers" `
    -ColumnName "EmailAddress"

Write-Host "SQL security configured successfully"

WEEK 4 STUDY GUIDE: SECURITY OPERATIONS

Domain 4 Deep Dive — Manage Security Operations

Skill Checklist: Defender for Cloud

  • [ ] Enable Defender plans for: Servers, Storage, SQL, Containers
  • [ ] Review and action Secure Score recommendations
  • [ ] Configure workflow automation for High severity alerts
  • [ ] Export security data to Sentinel
  • [ ] Configure regulatory compliance standards
  • [ ] Enable JIT VM Access for a VM

Skill Checklist: Microsoft Sentinel

  • [ ] Create a Log Analytics workspace and enable Sentinel
  • [ ] Connect data connectors: Entra ID, Activity Log, Defender for Cloud
  • [ ] Create a scheduled analytics rule with KQL
  • [ ] Respond to and close an incident
  • [ ] Create a playbook (Logic App) triggered by incident
  • [ ] Run a hunting query and bookmark results
  • [ ] Enable UEBA

Skill Checklist: Azure Policy

  • [ ] Assign the Azure Security Benchmark initiative
  • [ ] Create a custom Deny policy
  • [ ] Create a DeployIfNotExists policy with managed identity
  • [ ] Create and run a remediation task
  • [ ] View and export compliance report

Lab 6A: Enable Defender for Cloud Plans — PowerShell

# Enable Defender for Servers Plan 2
Set-AzSecurityPricing -Name "VirtualMachines" -PricingTier "Standard" -SubPlan "P2"

# Enable Defender for Storage
Set-AzSecurityPricing -Name "StorageAccounts" -PricingTier "Standard"

# Enable Defender for SQL (Azure SQL Databases)
Set-AzSecurityPricing -Name "SqlServers" -PricingTier "Standard"

# Enable Defender for Containers
Set-AzSecurityPricing -Name "Containers" -PricingTier "Standard"

# Enable Defender for Key Vault
Set-AzSecurityPricing -Name "KeyVaults" -PricingTier "Standard"

# Enable Defender for ARM
Set-AzSecurityPricing -Name "Arm" -PricingTier "Standard"

# Enable Defender for App Service
Set-AzSecurityPricing -Name "AppServices" -PricingTier "Standard"

# List all enabled Defender plans and their tiers
Get-AzSecurityPricing | Select-Object Name, PricingTier, FreeTrialRemainingTime

Lab 6B: Microsoft Sentinel Setup — CLI

# Create Log Analytics workspace
az monitor log-analytics workspace create \
  --resource-group security-rg \
  --workspace-name security-sentinel-law \
  --location eastus \
  --retention-time 90

LAW_ID=$(az monitor log-analytics workspace show \
  --resource-group security-rg \
  --workspace-name security-sentinel-law \
  --query id -o tsv)

# Enable Microsoft Sentinel on the workspace
az sentinel workspace create \
  --resource-group security-rg \
  --workspace-name security-sentinel-law

# Enable data connector: Azure Activity
az sentinel data-connector create \
  --resource-group security-rg \
  --workspace-name security-sentinel-law \
  --data-connector-id "AzureActivity" \
  --name "AzureActivityConnector"

echo "Sentinel workspace ready: $LAW_ID"

Lab 6C: Azure Policy — Deny and DeployIfNotExists

# Assign built-in policy: Deny storage accounts without HTTPS
New-AzPolicyAssignment `
    -Name "Deny-Storage-HTTP" `
    -DisplayName "Deny storage accounts that allow HTTP" `
    -PolicyDefinition (Get-AzPolicyDefinition -Name "404c3081-a854-4457-ae30-26a93ef643f9") `
    -Scope "/subscriptions/{subscriptionId}/resourceGroups/security-rg"

# Create custom Deny policy — require tags on resources
$policyDef = @{
    mode = "All"
    policyRule = @{
        if = @{
            field = "tags['Environment']"
            exists = "false"
        }
        then = @{
            effect = "Deny"
        }
    }
}

$policy = New-AzPolicyDefinition `
    -Name "Require-Environment-Tag" `
    -DisplayName "Require Environment tag on all resources" `
    -Policy ($policyDef | ConvertTo-Json -Depth 10)

# Assign the custom policy
New-AzPolicyAssignment `
    -Name "Require-Tag-Assignment" `
    -PolicyDefinition $policy `
    -Scope "/subscriptions/{subscriptionId}/resourceGroups/security-rg"

# Check compliance state
Get-AzPolicyState `
    -PolicyAssignmentName "Require-Tag-Assignment" `
    -ResourceGroupName "security-rg" |
    Select-Object ResourceId, ComplianceState, PolicyDefinitionName

Lab 6D: Key KQL Queries for Security Operations

// ---- AUTHENTICATION EVENTS ----

// Failed sign-in attempts by location
SignInLogs
| where TimeGenerated > ago(24h)
| where ResultType != 0
| summarize FailedAttempts = count() by Location, UserPrincipalName
| top 20 by FailedAttempts

// Successful sign-ins from high-risk locations
SignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| where RiskLevelDuringSignIn in ("medium", "high")
| project TimeGenerated, UserPrincipalName, IPAddress, Location, RiskLevelDuringSignIn
| order by TimeGenerated desc

// ---- PRIVILEGED ACTIVITY ----

// New global admin assignments
AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName == "Add member to role"
| extend RoleName = tostring(parse_json(tostring(TargetResources[0].modifiedProperties))
    [1].newValue)
| where RoleName contains "Global Administrator"
| project TimeGenerated, Initiator = tostring(InitiatedBy.user.userPrincipalName),
          TargetUser = tostring(TargetResources[0].userPrincipalName), RoleName

// ---- RESOURCE CHANGES ----

// High-impact Azure ARM operations (deletes, security changes)
AzureActivity
| where TimeGenerated > ago(24h)
| where ActivityStatusValue == "Succeeded"
| where OperationNameValue has_any ("delete", "Write/securityPolicies", "Write/locks")
| project TimeGenerated, Caller, OperationNameValue, ResourceGroup, _ResourceId
| order by TimeGenerated desc

// ---- DEFENDER ALERTS ----

// High severity Defender for Cloud alerts
SecurityAlert
| where TimeGenerated > ago(7d)
| where AlertSeverity == "High"
| where ProviderName has "ASC"
| project TimeGenerated, AlertName, Description, RemediationSteps, Entities
| order by TimeGenerated desc

// ---- NETWORK EVENTS ----

// NSG Flow Logs — denied traffic
AzureNetworkAnalytics_CL
| where TimeGenerated > ago(1h)
| where FlowType_s == "ExternalPublic"
| where FlowStatus_s == "D"  // Denied
| project TimeGenerated, DestIP_s, DestPort_d, SrcIP_s, NSGList_s
| summarize Count = count() by SrcIP_s, DestPort_d
| top 20 by Count

Key Azure Security Architecture Patterns

Defence-in-Depth (Azure Implementation)

Layer 1: Identity (Conditional Access, MFA, PIM)
Layer 2: Perimeter (DDoS, Azure Firewall, WAF)
Layer 3: Network (NSGs, VNet isolation, Private Endpoints)
Layer 4: Compute (JIT access, Disk Encryption, Defender for Servers)
Layer 5: Application (Key Vault, App Service auth, API keys)
Layer 6: Data (Storage encryption, SQL TDE, Always Encrypted)

Zero Trust Principles in Azure

  1. 1. Verify explicitly: Conditional Access validates EVERY request (identity, device, location, risk)
  2. 2. Least privilege: PIM for JIT access, RBAC at minimum scope, Managed Identities over service accounts
  3. 3. Assume breach: Sentinel for SIEM, Defender for threat detection, segmentation via NSGs + Firewall

🔑 Pre-Exam Checklist

Domain 1 — Identity

  • [ ] Know ALL Entra ID P2 features by heart
  • [ ] Can explain PIM eligible vs active WITHOUT looking at notes
  • [ ] Know every Conditional Access condition and grant control
  • [ ] Understand the difference between Identity Protection risk policies and Conditional Access
  • [ ] Know managed identity use cases cold

Domain 2 — Networking

  • [ ] NSG rule evaluation order with subnet + NIC
  • [ ] Azure Firewall rule processing: DNAT → Network → Application
  • [ ] Firewall SKU features (especially Premium features)
  • [ ] WAF Detection vs Prevention — which blocks, which logs
  • [ ] Private endpoint DNS: what breaks without the private DNS zone

Domain 3 — Compute/Storage/DB

  • [ ] Key Vault access policies vs RBAC — mutually exclusive
  • [ ] Soft-delete retention vs purge protection — and that purge protection CANNOT be disabled
  • [ ] SAS types — User Delegation SAS = most secure (uses Entra ID)
  • [ ] ADE vs SSE vs encryption at host
  • [ ] SQL Always Encrypted vs DDM — encryption vs masking

Domain 4 — Security Operations

  • [ ] ALL Defender plans and what each protects
  • [ ] Sentinel analytics rule types (Scheduled, NRT, Fusion, ML)
  • [ ] Azure Policy effects in order
  • [ ] DeployIfNotExists requires managed identity
  • [ ] KQL: can write a basic query with where, summarize, project

*AZ-500 Study Guide 2026 — aligned with official exam objectives*