Activate Defender for Servers on Azure VMs, configure auto-provisioning for agents, review Secure Score, run vulnerability assessments, investigate security alerts, and remediate recommendations to protect your server workloads.
Microsoft Defender for Servers is a workload protection plan within Microsoft Defender for Cloud that provides threat detection, vulnerability management, and security posture hardening for Azure VMs and hybrid servers. Plan 2 includes all Plan 1 capabilities plus vulnerability assessment powered by Microsoft Defender Vulnerability Management, file integrity monitoring, adaptive application controls, and just-in-time VM access. In this lab you will activate Defender for Servers Plan 2, configure auto-provisioning of agents, review your initial Secure Score, and resolve security recommendations. By the end of this lab, your Azure VMs will have full workload protection with continuous vulnerability scanning and threat detection enabled.
Scenario: NorthWind Retail operates 200 Azure VMs running e-commerce services across two Azure regions (East US and West Europe). The VMs host web front-ends, API services, and backend processing for online orders, customer accounts, and payment processing.
The security team needs vulnerability management and real-time threat detection for all server workloads to comply with PCI DSS requirements. Recent industry reports show that unpatched web servers are the top initial access vector for retail breaches.
Success criteria: all VMs protected, Secure Score above 70%, vulnerability scanning active, alert notifications configured.
Server workloads are primary targets for attackers: they run critical applications, store sensitive data, and often have elevated privileges. Research shows that unprotected VMs exposed to the internet are compromised within hours, not days. Without workload protection, your VMs lack vulnerability visibility, threat detection, and security posture assessment. Defender for Servers provides a unified security layer that covers detection, prevention, and compliance in a single plan. Enabling Plan 2 provides the deepest protection: integrated vulnerability management, file integrity monitoring, and adaptive controls eliminate coverage gaps.
Before enabling any workload protection plan, you should understand how Defender for Cloud pricing tiers work and what each plan includes.
# List every Defender plan and whether it is Free or Standard (paid).
# Output: table of plan names (VirtualMachines, SqlServers, etc.) with their tier.
az security pricing list --query "[].{Name:name, Tier:pricingTier}" -o table
# Drill into the VirtualMachines plan (portal label: "Defender for Servers").
# Shows the tier (Free|Standard) and sub-plan (P1 or P2).
az security pricing show --name VirtualMachines --query "{Plan:name, Tier:pricingTier, SubPlan:subPlan}" -o json# Install the Az.Security PowerShell module (required once per machine).
# -AllowClobber overwrites any conflicting cmdlets from older modules.
Install-Module -Name Az.Security -Force -AllowClobber
# Display every Defender plan with its pricing tier and sub-plan.
# Look for PricingTier = "Standard" to confirm a plan is enabled.
Get-AzSecurityPricing | Select-Object Name, PricingTier, SubPlan | Format-Table
# Show details for the Servers plan specifically.
# Expect SubPlan = P2 for full vulnerability assessment and JIT access.
Get-AzSecurityPricing -Name "VirtualMachines"Now you will enable Defender for Servers Plan 2 on your target subscription. You can do this through the Azure portal, Azure CLI, or PowerShell.
# Switch context to the subscription where you want to enable Defender.
# Replace YOUR_SUBSCRIPTION_ID with the actual GUID or friendly name.
az account set --subscription "YOUR_SUBSCRIPTION_ID"
# Enable Defender for Servers Plan 2 on the current subscription.
# --tier Standard turns on paid protection (Free = no protection).
# --subplan P2 enables the full feature set (vulnerability scanning,
# JIT access, adaptive application controls, file integrity monitoring).
az security pricing create \
--name VirtualMachines \
--tier Standard \
--subplan P2
# Confirm the plan is active. Tier should read "Standard" and SubPlan "P2".
az security pricing show \
--name VirtualMachines \
--query "{Plan:name, Tier:pricingTier, SubPlan:subPlan}" \
-o json# Authenticate to Azure (opens a browser login if not already authenticated).
Connect-AzAccount
# Switch to the subscription you want to protect.
# Replace with your actual subscription GUID.
Set-AzContext -SubscriptionId "YOUR_SUBSCRIPTION_ID"
# Enable Defender for Servers with the Plan 2 feature set.
# Plan 2 adds: vulnerability assessment, JIT VM access,
# adaptive application controls, and file integrity monitoring.
Set-AzSecurityPricing -Name "VirtualMachines" -PricingTier "Standard" -SubPlan "P2"
# Verify activation. PricingTier should be "Standard", SubPlan "P2".
Get-AzSecurityPricing -Name "VirtualMachines" | Format-List Name, PricingTier, SubPlanAuto-provisioning automatically installs the required monitoring agents on your Azure VMs. This ensures that new VMs are protected immediately without manual intervention.
# Show all auto-provisioning toggles (Log Analytics agent, VA, Guest Config).
az security auto-provisioning-setting list -o table
# Check whether the default Log Analytics agent auto-provisioning is On or Off.
# "On" means new VMs automatically receive the monitoring agent.
az security auto-provisioning-setting show \
--name "default" \
--query "{Name:name, AutoProvision:autoProvision}" \
-o json
# Turn on auto-provisioning so every new VM is instrumented automatically.
# Existing VMs will also receive the agent within 15-30 minutes.
az security auto-provisioning-setting create \
--name "default" \
--auto-provision "On"# List all installed VM extensions and their provisioning status.
# Replace "myResourceGroup" and "myVM" with your actual values.
az vm extension list \
--resource-group "myResourceGroup" \
--vm-name "myVM" \
--query "[].{Name:name, Status:provisioningState}" \
-o table
# Expected extensions after auto-provisioning:
# MicrosoftMonitoringAgent (Windows) / OmsAgentForLinux (Linux)
# - sends security data to Log Analytics workspace.
# MDE.Windows / MDE.Linux
# - Defender for Endpoint sensor for real-time threat detection.
# Status should read "Succeeded" for both.Secure Score is a measurement of your organization's security posture. It ranges from 0% to 100%, with higher scores indicating a stronger security configuration. Reviewing your baseline score before making changes lets you track improvement over time.
// Retrieve the latest Secure Score snapshot per subscription.
// Requires continuous export to Log Analytics (covered in later labs).
// Output columns:
// CurrentScore - points earned from healthy resources.
// MaxScore - maximum achievable points.
// Percentage - overall security posture (target > 70%).
SecureScores
| where TimeGenerated > ago(30d)
| summarize arg_max(TimeGenerated, *) by SubscriptionId
| project TimeGenerated, SubscriptionId,
CurrentScore = Properties.score.current,
MaxScore = Properties.score.max,
Percentage = Properties.score.percentage
| order by TimeGenerated descSecurity recommendations are actionable findings that tell you exactly what to fix and why. After enabling Defender for Servers, new VM-specific recommendations will appear within minutes.
// Count how many VM-related security issues exist, grouped by recommendation title.
// Filters to "Unhealthy" state only (unresolved findings).
// Sorts by severity (High first) so you remediate the riskiest items first.
SecurityRecommendation
| where TimeGenerated > ago(7d)
| where RecommendationState == "Unhealthy"
| where tolower(ResourceGroup) contains "vm"
or tolower(RecommendationDisplayName) contains "virtual machine"
or tolower(RecommendationDisplayName) contains "server"
| summarize Count = count() by RecommendationDisplayName, RecommendationSeverity
| order by RecommendationSeverity asc, Count desc// List each unhealthy VM alongside the specific recommendation it violates.
// Useful for assigning remediation tasks to VM owners.
// split(ResourceId, "/")[-1] extracts the VM name from the full resource path.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationState == "Unhealthy"
| where ResourceType == "microsoft.compute/virtualmachines"
| project TimeGenerated, ResourceName = tostring(split(ResourceId, "/")[-1]),
Recommendation = RecommendationDisplayName,
Severity = RecommendationSeverity
| order by Severity asc, ResourceName ascDefender for Servers Plan 2 includes integrated vulnerability assessment powered by Microsoft Defender Vulnerability Management. Scans run automatically once the agent is deployed, but you can also trigger manual scans.
# Retrieve vulnerability scan findings for a specific VM.
# --assessed-resource-id: full ARM path to the target VM (replace placeholders).
# --assessment-name: the GUID "1195afff-..." identifies the built-in
# "Machines should have vulnerability findings resolved" assessment.
# Output: CVE identifier, severity (Critical/High/Medium/Low), and description.
az security sub-assessment list \
--assessed-resource-id "/subscriptions/YOUR_SUB_ID/resourceGroups/myRG/providers/Microsoft.Compute/virtualMachines/myVM" \
--assessment-name "1195afff-c881-495e-9bc5-1486211ae03f" \
--query "[].{CVE:id.azureResourceId, Severity:status.severity, Description:displayName}" \
-o tableNow that you have visibility into your security posture, remediate the highest-impact recommendations. Focus on findings that close management ports, apply patches, and enable encryption.
# Enable Just-in-Time (JIT) VM access to lock down management ports.
# JIT keeps RDP (3389) and SSH (22) blocked at the NSG level and only
# opens them for a limited window when an authorised user requests access.
# "maxRequestAccessDuration": "PT3H" - ports open for max 3 hours per request.
# "allowedSourceAddressPrefix": "*" - any source IP can request (you can
# restrict this to a corporate CIDR for tighter control).
az security jit-policy create \
--resource-group "myResourceGroup" \
--location "eastus" \
--name "default" \
--virtual-machines '[{
"id": "/subscriptions/YOUR_SUB_ID/resourceGroups/myRG/providers/Microsoft.Compute/virtualMachines/myVM",
"ports": [
{"number": 3389, "protocol": "TCP", "allowedSourceAddressPrefix": "*", "maxRequestAccessDuration": "PT3H"},
{"number": 22, "protocol": "TCP", "allowedSourceAddressPrefix": "*", "maxRequestAccessDuration": "PT3H"}
]
}]'# View your current Secure Score after remediation.
# Percentage = CurrentScore / MaxScore (target > 70% for a healthy baseline).
Get-AzSecuritySecureScore | Select-Object DisplayName, CurrentScore, MaxScore, Percentage
# Show the top 10 remaining unhealthy recommendations to plan next actions.
# Resolving these will continue to raise your Secure Score.
Get-AzSecurityTask | Where-Object { $_.State -eq "Unhealthy" } |
Select-Object RecommendationType, ResourceId -First 10Configure email notifications to ensure your security team is alerted immediately when Defender for Cloud detects threats against your server workloads.
# Display existing security contact configuration (email addresses, toggles).
az security contact list -o json
# Set (or update) the security contact for alert notifications.
# --emails: distribution list or address that receives High/Medium alerts.
# --alert-notifications On: send email when Defender for Cloud raises an alert.
# --alerts-admins On: also notify subscription Owner and Contributor roles.
az security contact create \
--name "default" \
--emails "soc-team@northwindretail.com" \
--alert-notifications "On" \
--alerts-admins "On"Defender for Servers generates alerts when it detects suspicious activity on your VMs. In this step, you will trigger a sample alert and walk through the investigation workflow.
// Retrieve the 25 most recent High/Medium security alerts from Defender for Servers.
// ProductName "Azure Security Center" covers all Defender for Cloud workload alerts.
// Key output columns:
// AlertName - short title describing the detected threat.
// Tactics - MITRE ATT&CK stage (InitialAccess, Execution, etc.).
// RemediationSteps - suggested actions to contain and resolve the threat.
SecurityAlert
| where TimeGenerated > ago(7d)
| where ProductName == "Azure Security Center"
| where AlertSeverity in ("High", "Medium")
| project TimeGenerated, AlertName, AlertSeverity,
Description, RemediationSteps,
ResourceId, Tactics, Techniques
| order by TimeGenerated desc
| take 25// Count alerts by MITRE ATT&CK tactic and severity over the last 30 days.
// mv-expand flattens the Tactics array so each tactic gets its own row.
// Use this for trend dashboards - a spike in "LateralMovement" or
// "CredentialAccess" may indicate an active intrusion.
SecurityAlert
| where TimeGenerated > ago(30d)
| where ProductName == "Azure Security Center"
| mv-expand Tactics = todynamic(Tactics)
| summarize AlertCount = count() by tostring(Tactics), AlertSeverity
| order by AlertCount descThe regulatory compliance dashboard maps your security posture to industry standards and regulatory frameworks. Enabling Defender for Servers improves your compliance score by covering server-specific controls.
// Count how many distinct resources fail each server-related compliance control.
// Filters to the five most impactful server hardening recommendations.
// dcount(ResourceId) gives the unique number of non-compliant resources,
// so you can prioritise the control that affects the most machines.
SecurityRecommendation
| where TimeGenerated > ago(1d)
| where RecommendationState == "Unhealthy"
| where RecommendationDisplayName has_any ("endpoint protection", "system updates",
"disk encryption", "management ports", "vulnerability")
| summarize FailedResources = dcount(ResourceId) by RecommendationDisplayName
| order by FailedResources descaz security pricing create --name VirtualMachines --tier Free| Resource | Description |
|---|---|
| Defender for Servers overview and plan comparison | Compare Plan 1 and Plan 2 features for server protection |
| Tutorial: Configure security policies in Defender for Cloud | Step-by-step guide to setting up and managing security policies |
| Secure Score and security controls in Defender for Cloud | Understand how Secure Score measures your overall security posture |
| Deploy vulnerability assessment for Azure VMs | Enable and run vulnerability scans on your virtual machines |
| Configure just-in-time VM access | Set up time-limited management port access for Azure VMs |
| Configure email notifications for security alerts | Route high-severity security alerts to your team via email |
| Security alerts in Microsoft Defender for Cloud | Understand alert types, severity levels, and investigation workflows |
| Regulatory compliance dashboard | Track compliance against PCI DSS, CIS, and other frameworks |
| File integrity monitoring overview | Detect unauthorized changes to critical OS and application files |
| Microsoft Defender for Cloud pricing | Review per-server hourly billing and plan cost estimates |