You spent the afternoon fixing things. You turned on encryption, you locked down a storage account, you enabled MFA for two admins — exactly what Microsoft Defender for Cloud told you to do. You refresh the Secure Score tile expecting a satisfying jump, and the number is identical. Or worse, it went down. So you do what everyone does: you re-fix the same thing, you click refresh fifteen times, you wonder whether the whole feature is broken. It isn’t. Secure Score is a calculated value that lags reality on purpose, sees a specific slice of your environment, and rewards a very specific definition of “done” — and once you understand those three things, a stuck score stops being a mystery and becomes a five-minute lookup.
This article is the diagnostic playbook for exactly that frustration. Secure Score is Defender for Cloud’s single percentage that summarises how well your Azure (and connected AWS/GCP/on-prem) resources follow Microsoft’s security best practices. Under it sits a layer of security recommendations, each backed by an assessment that the platform runs against your resources on a schedule and marks Healthy, Unhealthy, or Not applicable. The score is just arithmetic over those assessments — so when it won’t move, the answer is always one of a handful of concrete causes: the assessment hasn’t re-run yet, you fixed a resource the assessment doesn’t cover, the recommendation is exempted, the data source feeding it (an agent, an extension, a Defender plan) is missing or off, or you fixed one resource out of fifty and the control only pays out in proportion.
By the end you will stop re-remediating in circles. When the score sits still you will know whether to wait, widen your view, check an exemption, fix the data pipeline, or finish the job — and confirm which in ninety seconds. Every diagnosis below comes with the exact portal path and the precise az command, plus Bicep where you’d set the thing as code.
What problem this solves
Defender for Cloud is a feedback loop: it scores your posture, tells you what to fix, you fix it, the score rises, leadership sees a green trend. That loop is wonderful when it turns and maddening when it appears stuck, because the loop has latency and hidden state you can’t see from the score tile. The bare number tells you nothing about why it’s where it is — and the most common reaction (remediate the same item again) does nothing, because the item was never the problem.
What breaks without this knowledge is trust and time. A team reports “Secure Score is broken” and waits on a support ticket while the real cause — an assessment that hadn’t refreshed in its 24-hour window — would have resolved by morning. An engineer “fixes” encryption on one VM, sees no movement, and concludes the control is bugged, when it’s averaging across forty VMs and they moved one. A compliance lead screenshots a 68% score for an audit without realising the scope picker was on a single dev subscription while production sits at 41%. None of these are platform faults; all are diagnosable in minutes once you know where the truth lives.
Who hits this: essentially everyone who runs Defender for Cloud — security engineers chasing a posture target, cloud admins on a “raise the score to X by quarter-end” mandate, compliance teams mapping the score to a framework, and beginners who reasonably expect “I fixed it” to equal “the number goes up immediately.” It bites hardest right after a remediation sprint, right after onboarding a new subscription, and right after someone enables an exemption or a governance rule that quietly changes what counts.
To frame the whole field before the deep dive, here is every reason a Secure Score realistically refuses to improve, the question it forces, and the first place to look:
| Reason class | What’s really happening | First question to ask | First place to look |
|---|---|---|---|
| Assessment hasn’t refreshed | The fix is real; the score is stale | Has the refresh window elapsed? | Recommendation → resource still Unhealthy but timestamp is old |
| Scope mismatch | The score you see ≠ the resource you fixed | Am I looking at the right subscription/MG? | The scope/subscription picker at the top |
| Partial remediation | You fixed some resources, not all | How many resources are still Unhealthy? | Recommendation → Affected resources count |
| Exemption / waiver | The item is excluded from scoring | Was this recommendation exempted? | Recommendation → Exempt; exemptions list |
| Missing data source | No agent / extension / plan = no assessment | Is the resource actually being assessed? | Inventory; agent/extension status; plan state |
| Not-applicable / preview | The control doesn’t count toward score | Does this recommendation affect score at all? | Recommendation detail → “affects your secure score” |
Learning objectives
By the end of this article you can:
- Explain in one breath how Secure Score is calculated — controls, the per-control maximum, and the healthy-vs-unhealthy ratio — so you can predict how much a fix is worth before you make it.
- Tell the difference between a recommendation and the assessment behind it, and read an assessment’s
Healthy/Unhealthy/NotApplicablestate. - Diagnose a stuck score as one of six concrete causes — refresh delay, scope mismatch, partial remediation, exemption, missing data source, or non-scoring recommendation — and confirm which with an exact command or portal path.
- Use the core tools fluently: the Secure Score and Recommendations blades, Inventory, the Regulatory compliance view, and the
azcommands forsecurity secure-scores,security secure-score-controls, andsecurity assessment. - Recognise the data-pipeline prerequisites — the Azure Monitor Agent, machine extensions, Defender plans, and auto-provisioning — that a recommendation needs before it can ever turn Healthy.
- Understand exemptions (Waiver vs Mitigated), governance rules, and score drift (why a score can fall with no action of yours), and reason about each correctly.
- Avoid the classic beginner traps: re-remediating before the refresh, fixing one resource and expecting full credit, and confusing the foundational (free) CSPM with the paid Defender CSPM plan.
Prerequisites & where this fits
You should know the Azure resource hierarchy — that a subscription holds resource groups and resources, and that management groups sit above subscriptions (the Azure Resource Hierarchy Explained covers this, and Management Groups 101 covers the layer above). You should be comfortable opening the Azure portal, running az in Cloud Shell, and reading JSON output. No prior Defender for Cloud expertise is assumed — that’s the point of a Basic article — but a working idea of what a “security recommendation” is will help.
This sits at the front of the Security posture & governance track. Defender for Cloud is the Cloud Security Posture Management (CSPM) tool for Azure: it continuously assesses configuration against best practice and a built-in policy initiative, and Secure Score is its headline metric. The recommendations it raises are, under the hood, Azure Policy evaluations — so understanding Azure Policy Effects Decoded and Policy Definitions vs Initiatives makes the whole system click, because “why is this Unhealthy” is often “what is this policy actually checking.” It pairs with Azure Monitor and Application Insights for the agent/log plumbing, and with Managed Identities Demystified for the identity some assessments rely on.
A quick map of who owns what during a “the score won’t move” investigation, so you ask the right person:
| Layer | What lives here | Who usually owns it | What it can break |
|---|---|---|---|
| Secure Score tile | The single % and trend | Security / posture team | Misread scope or stale number |
| Recommendations | The findings + assessments | Security + resource owners | Unhealthy resources, exemptions |
| Azure Policy initiative | The rules behind assessments | Governance team | A disabled/replaced policy = no assessment |
| Defender plans | Paid coverage per resource type | Security + finance | Plan off → recommendation never appears |
| Agents / extensions | Data from VMs/servers | Platform / server team | No agent → resource never assessed |
| Connected clouds / Arc | AWS, GCP, on-prem onboarding | Cloud / hybrid team | Connector down → those resources missing |
Core concepts
Five mental models make every later diagnosis obvious.
The score is arithmetic, not a vibe. Secure Score is computed from security controls — logical groups of related recommendations (for example, “Enable MFA,” “Encrypt data in transit,” “Manage access and permissions”). Each control has a maximum score, and you earn a fraction of it equal to how many of the affected resources are healthy — so you must make every resource in a control healthy to get the control’s full points (the next section does the full arithmetic). Once you internalise “controls, not recommendations, score — and proportionally,” the partial-credit confusion disappears.
A recommendation is a question; an assessment is the answer for one resource. A security recommendation (“Storage accounts should restrict network access”) is backed by an assessment that the platform evaluates against each in-scope resource and stamps with a status: Healthy (passes), Unhealthy (fails — needs remediation), or NotApplicable (the check doesn’t apply here). The recommendation you see in the list is the rollup; the per-resource statuses underneath are the ground truth. When the score won’t move, you almost always need to drop from the recommendation down to which resources are still Unhealthy.
The answer is cached and refreshed on a schedule, not live. Defender for Cloud does not re-evaluate every assessment the instant you change a resource. Assessments refresh periodically — many within roughly 24 hours, and some heavier ones can take longer — so a correct fix you made five minutes ago can leave the resource showing Unhealthy and the score unchanged until the next evaluation cycle. This single fact explains the majority of “I fixed it and nothing happened” reports. The fix is real; the measurement is pending.
No data source, no assessment, no score. Many recommendations depend on a data pipeline: a virtual machine needs the Azure Monitor Agent (AMA) and the relevant extension to report OS-level posture; some recommendations only exist if the matching Defender plan (a paid per-resource-type capability, e.g. Defender for Servers, for Storage, for SQL) is enabled; connected AWS/GCP accounts need a healthy connector; on-prem and other-cloud machines need Azure Arc. If the pipeline is missing, the assessment can’t run, the resource shows as unmonitored rather than Healthy, and remediating “in the resource” changes nothing the platform can see.
The set of things that count can change under you — that’s score drift. Your Secure Score is relative to what’s currently in scope and currently scored. Add a new subscription full of misconfigured resources and your percentage falls even though you changed nothing on existing resources. Microsoft also evolves the built-in recommendation set; a newly added recommendation (once it leaves preview) introduces new unhealthy resources and can lower the score. An exemption removes an item from scoring and can raise it. So a moving score with no remediation of yours is usually drift, not a bug — and reading the trend plus what changed in scope explains it.
The vocabulary in one table
Before the deep sections, pin down every moving part. The glossary at the end repeats these for lookup; this is the mental model side by side:
| Term | One-line definition | Where it lives | Why it matters to a stuck score |
|---|---|---|---|
| Secure Score | The single % summarising posture | Defender for Cloud → Secure Score | The number you’re trying to move |
| Security control | A group of related recommendations with a max score | Inside Secure Score | The unit that actually scores (proportionally) |
| Recommendation | A best-practice finding to act on | Recommendations blade | The thing you remediate |
| Assessment | Per-resource pass/fail behind a recommendation | Under each recommendation | Unhealthy here = no points |
| Healthy / Unhealthy / Not applicable | The three assessment states | Per resource | Only Healthy earns credit; N/A is excluded |
| Defender plan | A paid per-resource-type capability | Environment settings → Defender plans | Off → some recommendations never appear |
| Foundational CSPM | The free posture features (incl. Secure Score) | On by default | Distinguishes free vs paid coverage |
| Exemption | Excluding a resource/recommendation from scoring | Recommendation → Exempt | Removes the item from the score math |
| Governance rule | Assigns owners/ETAs to recommendations | Governance blade | Doesn’t fix; can reshape what you track |
| AMA / extension | Agent feeding OS-level posture data | On the VM / Arc machine | Missing → resource isn’t assessed |
| Scope | The MG/subscription you’re viewing | Top-of-page picker | Wrong scope = looking at the wrong score |
| Refresh cadence | The periodic re-evaluation (~24h+) | Platform behaviour | Why a real fix shows late |
How Secure Score is actually calculated
This is the section that makes everything else obvious. The score is not a black box; it is a published formula you can do the arithmetic on yourself.
A security control bundles related recommendations and is assigned a maximum number of points (the value differs per control — some are worth more than others; many top out around 10 or fewer). For a given control, the platform looks at every resource that the control’s recommendations apply to, counts how many are Healthy, and awards points in proportion:
control points earned ≈ (Healthy resources ÷ total applicable resources) × control maximum
You only get the control’s full points when all its applicable resources are Healthy — fixing some of them earns a fraction. Your overall Secure Score percentage is then the sum of points earned across all in-scope controls divided by the sum of all available points, expressed as a percentage (and the portal also shows it as “X of Y points”). Two consequences trip up beginners constantly: (1) fixing one resource in a fifty-resource control nudges the number by a sliver, not a leap; and (2) controls are weighted differently, so two fixes that each say “+1 recommendation done” can move the score by very different amounts.
Here is how to reason about what a fix is worth, and the common misreadings:
| If you… | The score will… | Because… |
|---|---|---|
| Fix all resources in a control | Gain that control’s full points | The control pays out fully only at 100% healthy |
| Fix half the resources in a control | Gain roughly half that control’s points | Credit is proportional to healthy ratio |
| Fix one of many resources | Move slightly (or imperceptibly) | One healthy resource is a small fraction |
| Fix a resource in a high-max control | Move more than the same fix elsewhere | Controls are weighted differently |
| Mark a recommendation exempt | Possibly rise | The unhealthy resources leave the score math |
| Onboard a new, messy subscription | Fall | New unhealthy resources enter the denominator |
A worked example clears it up. Suppose the “Encrypt data in transit” control has a maximum of 10 points and applies to 20 resources, of which 12 are Healthy. The control currently earns about 12/20 × 10 = 6 points. You fix 4 more resources (now 16/20 Healthy): the control earns about 8 points — a 2-point gain on that control, which might be a fraction of a percent on the overall score depending on the total points available. If you’d expected “+1 recommendation fixed = +1%,” this is why the tile looked frozen.
Confirm the math yourself from the CLI — pull the controls with their max and current scores:
# All security controls in the subscription: current score, max, and % achieved
az security secure-score-controls list \
--query "value[].{control:displayName, current:score.current, max:score.max, pct:score.percentage}" \
-o table
# The overall Secure Score for the default scope (the 'ascScore' aggregation)
az security secure-scores show --name ascScore \
--query "{current:score.current, max:score.max, percentage:score.percentage}" -o json
The percentage is your headline number; current/max are the points. If max looks larger than you expected, you have controls in scope you forgot about — and every unhealthy resource in them is dragging the percentage.
Reading a recommendation: from finding to per-resource truth
When a fix doesn’t register, you descend one level: from the recommendation rollup to the per-resource assessment statuses. A recommendation typically shows an affected resources breakdown — counts of Unhealthy, Healthy, and Not applicable. The number that matters is Unhealthy: as long as it’s above zero, the control isn’t fully paid and the score reflects that.
The three states and what each means for scoring:
| Assessment status | Meaning | Counts toward score? | What to do |
|---|---|---|---|
| Healthy | Resource passes the check | Yes — earns its share | Nothing; this is the goal |
| Unhealthy | Resource fails the check | Yes — earns nothing until fixed | Remediate this resource |
| Not applicable | Check doesn’t apply (or excluded) | No — removed from the math | Confirm why it’s N/A (exemption? config?) |
List the assessments and find what’s still failing:
# Every assessment in the subscription with its status — filter to the unhealthy ones
az security assessment list \
--query "[?status.code=='Unhealthy'].{name:displayName, status:status.code, resource:resourceDetails.id}" \
-o table
In the portal the same truth is Microsoft Defender for Cloud → Recommendations → (pick the recommendation) → Affected resources, where each resource shows Healthy/Unhealthy and you can click into why. If a resource you just fixed still says Unhealthy with an old evaluation timestamp, you’re in the refresh-delay case (below), not a failed fix.
The data pipeline: why some resources are never even assessed
A resource can sit in a state that is neither Healthy nor Unhealthy because the platform has no data for it — the trap that wastes the most time, because remediating “inside the resource” changes nothing the score can see. The missing piece is the pipeline, not the config.
Three pipeline prerequisites, in plain terms:
- Defender plans. Defender for Cloud has a free foundational CSPM layer (on by default for every subscription) that gives you Secure Score, the recommendations from the built-in initiative, and asset inventory. Deeper coverage — and certain recommendations — only appear when you enable the matching Defender plan for that resource type (Defender for Servers, for Storage, for SQL, for Containers, for App Service, and so on), which is billed per resource. If a recommendation you expect simply isn’t listed, the plan that produces it may be off.
- Agents and extensions on machines. OS-level posture for VMs and Arc-enabled servers flows through the Azure Monitor Agent (AMA) and resource-type extensions. (Older deployments used the now-retired Log Analytics / Microsoft Monitoring Agent (MMA); if you still depend on it, migrate to AMA — see the agent table below.) Auto-provisioning can install these for you across a subscription; without the agent, machine-level assessments stay un-evaluated.
- Connectors and Arc for non-Azure. AWS and GCP accounts report through cloud connectors; on-prem and other-cloud servers report through Azure Arc. If the connector is unhealthy or a server isn’t Arc-enabled, those resources are simply absent from the score (see Azure Arc Explained and Onboarding Servers to Azure Arc).
The pipeline prerequisites and what their absence looks like:
| Prerequisite | What it feeds | If it’s missing you see… | How to confirm |
|---|---|---|---|
| Foundational CSPM (free) | Secure Score, built-in recommendations, inventory | (Always on) — baseline posture | Environment settings → it’s enabled by default |
| Defender plan (paid) | Plan-specific recommendations & alerts | The recommendation never appears | az security pricing list → tier per plan |
| Azure Monitor Agent (AMA) | OS-level machine posture | Machine recommendations “not assessed” | Recommendation “machines should have AMA installed” |
| Resource extension | Specific data (e.g. vulnerability assessment) | That assessment blank for the VM | VM → Extensions; recommendation status |
| Auto-provisioning | Auto-installs agents at scale | New VMs un-monitored until manual install | Environment settings → Auto-provisioning |
| Cloud connector (AWS/GCP) | Multicloud resources & recommendations | Those resources absent from score | Environment settings → the connector’s health |
| Azure Arc | On-prem / other-cloud machine posture | Servers absent from inventory | Azure Arc → machine connected status |
Check which Defender plans are on (the most common “missing recommendation” cause):
# Per-plan pricing tier: 'Standard' = plan on (paid), 'Free' = plan off
az security pricing list \
--query "value[].{plan:name, tier:pricingTier}" -o table
// Enable a Defender plan as code (example: Storage). Standard = on, Free = off.
resource defenderStorage 'Microsoft.Security/pricings@2024-01-01' = {
name: 'StorageAccounts'
properties: {
pricingTier: 'Standard'
}
}
If the plan shows Free, its recommendations won’t drive your score until you switch it to Standard — and that’s a billing decision, covered under Cost & sizing.
Exemptions, governance, and score drift
Three mechanisms change what counts without you touching a single resource — and each is a frequent reason a score moved (or refused to) in a way that looks inexplicable.
Exemptions (Waiver and Mitigated)
An exemption removes a recommendation from the Secure Score math for a chosen scope — a specific resource, a resource group, or a subscription. You create one when a finding is a genuine false positive for you, or is mitigated by a compensating control you manage elsewhere. Defender for Cloud records an exemption category: Waiver (you accept the risk as-is) or Mitigated (you’ve handled it another way). Exempted items are shown as Not applicable and are excluded from scoring — which is exactly why an exemption can raise the score, and why a recommendation you swear you never fixed can show as resolved.
The two categories and when to use which:
| Exemption category | Meaning | Use when | Caution |
|---|---|---|---|
| Waiver | Risk accepted, no compensating control | The finding doesn’t apply / is acceptable risk | You’ve removed it from the score — document why |
| Mitigated | Handled by another control | A third-party tool or design covers it | Auditors will ask for the evidence |
List existing exemptions so a “mystery green” doesn’t surprise you (exemptions are Azure Policy exemptions under the hood):
# Policy exemptions in the subscription — Defender exemptions surface here
az policy exemption list \
--query "[].{name:name, category:exemptionCategory, scope:resourceGroup}" -o table
Governance rules
A governance rule assigns an owner and a remediation due date (ETA) to recommendations, and can produce reminders and a grace period. This is workflow, not remediation: a governance rule does not make anything Healthy and does not directly change the score. Beginners sometimes assume “assigning an owner” or “setting an ETA” fixed the finding — it didn’t; it organised the work. The score still waits on the actual remediation plus the refresh.
Score drift — when the number moves on its own
Because the score is relative to current scope and the current recommendation set, it can change with no action of yours:
| Drift event | Effect on score | Why |
|---|---|---|
| New subscription onboarded | Usually down | Adds unhealthy resources to the denominator |
| New resources deployed (misconfigured) | Down | More unhealthy resources in existing controls |
| Microsoft adds a new recommendation (GA) | Often down | New checks find new unhealthy resources |
| A recommendation moves out of preview | Possibly down | Preview ones don’t score; GA ones do |
| Exemption created | Up | Unhealthy items leave the math |
| Resources deleted / decommissioned | Up or down | Changes the healthy/unhealthy ratio |
The takeaway: before declaring a drop a bug, look at the Secure Score over time trend and ask “what entered or left scope, and did the recommendation set change?” Nine times out of ten that explains it.
Architecture at a glance
Hold this mental model and every diagnosis has a home. Picture the score as the top of a pipeline, with data flowing upward through four layers, each of which can stall the result.
At the bottom are your resources — Azure VMs, storage accounts, SQL databases, plus AWS/GCP resources via connectors and on-prem servers via Azure Arc. Sitting on the machines (where relevant) are agents and extensions — chiefly the Azure Monitor Agent — that report OS-level posture; for many resource types the platform reads configuration directly through Azure Resource Manager with no agent at all. Above the resources sit the Defender plans: the always-on free foundational CSPM that produces Secure Score and the built-in recommendations, plus the paid plans (Servers, Storage, SQL, …) that add resource-type-specific recommendations and alerts. The middle layer is the assessment engine: for each in-scope resource it evaluates the relevant checks — most of them expressed as the built-in Azure Policy security initiative — and writes a Healthy / Unhealthy / Not applicable status, refreshing periodically (commonly within ~24 hours) rather than instantly. At the top, those per-resource statuses roll up into recommendations, the recommendations group into security controls (each with a maximum score), and the controls’ proportional points sum into the Secure Score percentage you see — filtered by whatever scope (management group or subscription) is selected in the page header, and adjusted by any exemptions that pull items out of the math.
Trace a failure with that picture: a fix that “didn’t work” is a status that hasn’t refreshed (assessment-engine latency) or a resource you didn’t fix (the per-resource layer), a missing recommendation is a disabled plan (the plan layer) or an absent agent (the resource/agent layer), a wrong-looking score is the scope filter at the very top, and a surprise green is an exemption skimming items off before the rollup. The score is the last thing in the chain — which is precisely why staring at the number tells you nothing, and walking down the pipeline tells you everything.
Real-world scenario
Northwind Retail runs a modest Azure estate — two subscriptions (sub-prod and sub-dev), about 40 VMs, a dozen storage accounts, a handful of SQL databases — and has been told by their new CISO to get Secure Score from 62% to 75% before the quarterly board review, six weeks out. Priya, a cloud admin two years into Azure, owns the number.
Week one goes well: she works the Recommendations list top-down — secure transfer on storage, NSG rules, MFA for the admin group — and by Friday has actioned eleven recommendations. She opens Secure Score expecting high-60s and sees 61%, a point lower than when she started. Everything she fixed is genuinely fixed in the resource blades, so she re-applies three storage fixes “just in case,” refreshes the tile a dozen times, and files a support case convinced the feature is broken.
It wasn’t. Three causes from this playbook overlapped. Refresh delay: Friday’s fixes were hours old and their assessments hadn’t re-evaluated — resources still showed Unhealthy with stale timestamps; by Monday, with no further action, the score had climbed to 66% as the cycle caught up. Score drift: midweek the team had onboarded sub-dev (previously outside Defender), dumping dozens of misconfigured dev resources into the denominator — that’s what pushed the number down despite real progress; setting the scope picker to sub-prod only, production read 69%. Partial remediation: the AMA/endpoint-protection control covered all 40 VMs, but auto-provisioning had reached only about half — the other 20 were un-assessed, not unhealthy, contributing nothing.
The fix that finally moved the needle wasn’t more remediation — it was understanding the measurement. Priya stopped re-fixing, scoped reporting to production, enabled auto-provisioning for the Azure Monitor Agent across sub-prod, exempted two genuine false positives (documented Mitigated, a third-party tool covered them), and let the 24-hour cycle run between changes. Production Secure Score reached 76% with a week to spare. Her runbook note: “Fix, then wait a day before judging. Check the scope before screenshotting. A resource with no agent isn’t unhealthy — it’s invisible. And the score can fall because the world grew, not because you failed.”
Advantages and disadvantages
Secure Score is a genuinely useful instrument, but its design choices cut both ways. Knowing the trade-offs keeps you from fighting the tool.
| Advantages | Disadvantages |
|---|---|
| One number leadership understands at a glance | One number hides why — you must drill down to act |
| Proportional control scoring rewards steady progress | Big estates move the % slowly; effort feels invisible |
| Recommendations map to concrete, actionable fixes | Refresh delay (~24h) breaks the “fix = instant feedback” loop |
| Free foundational CSPM gives the score at no cost | Deeper recommendations need paid Defender plans |
| Exemptions let you handle real false positives cleanly | Exemptions can be abused to “game” the score |
| Multicloud + Arc bring AWS/GCP/on-prem into one view | Those need healthy connectors/agents or resources vanish |
| Built on Azure Policy — transparent, inspectable checks | A changed/disabled policy silently removes a check |
When each side matters: the single-number clarity is perfect for board slides but dangerous as the only thing you look at — always pair it with the trend and the scope. Proportional scoring is honest yet demoralising on a 5,000-resource estate where a hard week nudges 62% to 63%, so report controls completed alongside the percentage. The refresh delay is the right engineering choice but the biggest source of “it’s broken” confusion — bake “wait a day” into every runbook. And the free vs paid split means a recommendation’s absence is sometimes a billing setting, not a clean environment.
Hands-on lab
Walk the score end-to-end: read it, drop to a recommendation, find an unhealthy resource, exempt one, and watch the math — all using the free foundational CSPM, no paid plan required. Run in Cloud Shell (Bash). (You need at least Reader on a subscription plus permission to create a policy exemption for the optional step; Security Admin is ideal.)
Step 1 — Set your subscription and confirm the scope you’re scoring.
az account set --subscription "<your-subscription-id>"
az account show --query "{name:name, id:id}" -o table
This is the single most important habit: know which subscription’s score you’re about to read.
Step 2 — Read the overall Secure Score (points and percentage).
az security secure-scores show --name ascScore \
--query "{current:score.current, max:score.max, percentage:score.percentage}" -o json
Expected: a JSON object like { "current": 28.0, "max": 50.0, "percentage": 0.56 }. The percentage (×100) is your headline number; current/max are the points behind it.
Step 3 — List the controls so you can see what’s weighing the score down.
az security secure-score-controls list \
--query "value[].{control:displayName, current:score.current, max:score.max, pct:score.percentage, unhealthy:unhealthyResourceCount}" \
-o table | sort -t'|' -k5 -n
Expected: a table of controls. The ones with a high max, a low pct, and a high unhealthy count are your best return on effort.
Step 4 — Pick one Unhealthy recommendation and see the failing resources.
# Show the unhealthy assessments and the exact resource IDs failing
az security assessment list \
--query "[?status.code=='Unhealthy'].{name:displayName, resource:resourceDetails.id}" \
-o table | head -20
Expected: rows pairing a recommendation name with a specific resource ID. Note one resource ID — that’s a real thing to remediate (or, here, to exempt).
Step 5 — (Optional) Exempt one finding and observe it leave the score. Pick a recommendation that’s genuinely a false positive in your dev subscription. In the portal this is Recommendations → (the recommendation) → Exempt → choose scope, category Waiver/Mitigated, reason. To inspect existing exemptions from the CLI:
az policy exemption list \
--query "[].{name:name, category:exemptionCategory, expires:expiresOn}" -o table
Expected: any exemptions you (or others) created, with their category. An exempted item shows as Not applicable and stops dragging the control.
Step 6 — Re-read the score (but mind the cadence).
az security secure-scores show --name ascScore --query "score.percentage" -o tsv
Expected: if you only read (no remediation), the number is unchanged — correct. If you exempted something, the change appears after the next evaluation cycle, not instantly; re-running this command ten times in a row will not speed it up. That patience is the lesson.
Validation checklist. You located your scope, read the score as both points and a percentage, identified the highest-leverage controls, drilled to a specific unhealthy resource, saw how an exemption removes an item from the math, and confirmed the score does not update in real time. No paid plan, no agent install — purely the free posture surface.
| Step | What you did | What it proves |
|---|---|---|
| 1 | Set + show subscription | The score is always per-scope |
| 2 | Read overall score | The % is points-earned ÷ points-available |
| 3 | List controls | Controls (weighted) drive the number, not raw recommendation counts |
| 4 | Find unhealthy resources | The score lives at the per-resource layer |
| 5 | Inspect/create an exemption | Exemptions remove items (and can raise the score) |
| 6 | Re-read the score | The refresh is periodic, not live |
Cleanup. Nothing to delete — you only read data (and optionally created a policy exemption, which you can remove with az policy exemption delete --name <name>). Reading Defender for Cloud posture data is free.
Common mistakes & troubleshooting
This is the playbook — the part you bookmark. First a scannable table you can read mid-investigation, then the same entries with the full confirm-detail underneath. It spans the basic traps (refresh, scope, partial fixes) and the deeper ones (plans, agents, policy, connectors).
| # | Symptom | Root cause | Confirm (exact cmd / portal path) | Fix |
|---|---|---|---|---|
| 1 | Fixed a resource, score unchanged minutes later | Assessment hasn’t refreshed (~24h cycle) | Recommendation → resource still Unhealthy but evaluation timestamp is hours old | Wait for the cycle; re-check next day before re-acting |
| 2 | Score lower than a teammate’s for “the same” tenant | Scope picker on a different MG/subscription | Top-of-page scope selector; az account show |
Set scope to the intended subscription/MG |
| 3 | Fixed the recommendation, control still not full | Only some affected resources are Healthy | Recommendation → Affected resources: Unhealthy count > 0 | Remediate the remaining unhealthy resources |
| 4 | A recommendation you expect isn’t listed at all | The Defender plan that produces it is off | az security pricing list → tier = Free for that plan |
Enable the plan (set tier Standard) if you want it |
| 5 | VMs show “not assessed,” neither Healthy nor Unhealthy | No Azure Monitor Agent / extension on the machine | Recommendation “machines should have AMA”; VM → Extensions | Enable auto-provisioning / install AMA |
| 6 | Score “wrong” right after onboarding a subscription | Score drift — new unhealthy resources entered scope | Secure Score over time trend; compare per-subscription | Scope per subscription; remediate the new ones |
| 7 | Recommendation went green but you never fixed it | An exemption (Waiver/Mitigated) excluded it | Recommendation → status; az policy exemption list |
Confirm it’s intentional; document the reason |
| 8 | Score fell with no change on your side | New GA recommendation, or resources deployed | Secure Score over time; recent recommendations | Expected drift; remediate the newly flagged items |
| 9 | Set an owner/ETA, finding still Unhealthy | Governance rule organises work, doesn’t fix it | Governance blade shows the assignment; resource still Unhealthy | Perform the actual remediation; rule just tracks it |
| 10 | AWS/GCP resources missing from the score | Cloud connector unhealthy or not onboarded | Environment settings → connector health | Reconnect/repair the AWS/GCP connector |
| 11 | On-prem servers absent from recommendations | Servers not Azure Arc-enabled | Azure Arc → connected machines list | Onboard the servers to Azure Arc |
| 12 | Remediated via a recommendation’s “Fix” but nothing changed | Fix applied to one resource; or async + refresh pending | Recommendation → Fix log; per-resource status + timestamp | Apply to all resources; wait for re-evaluation |
| 13 | “Configure missing prerequisites” never clears | Auto-provisioning off, or RBAC blocked the deploy | Environment settings → Auto-provisioning; Activity log for deploy errors | Enable auto-provisioning; grant the needed role |
| 14 | An expected recommendation vanished after a policy change | The underlying built-in policy was disabled/replaced | Policy → Assignments for the Defender initiative; assessment missing | Restore the default security initiative assignment |
| 15 | Score stuck at a ceiling; remaining items “can’t” be fixed | Items need a paid plan, or are not-applicable to you | Recommendation detail → “affects your secure score”; plan tier | Enable plan, or exempt true non-applicables (documented) |
The expanded form, with the reasoning for the six that bite hardest (the table above covers the rest):
Refresh delay — you remediated and the score is unchanged minutes later. Root cause: Defender for Cloud refreshes assessments periodically (commonly within ~24 hours), not on change. The fix is real; the measurement is pending. Confirm: Open the recommendation → the resource still shows Unhealthy, but its last-evaluation timestamp is hours old — the engine hasn’t looked again yet. Fix: Wait for the next cycle and re-check the following day before taking any further action. Re-remediating or hammering refresh changes nothing.
Partial remediation — you fixed “the recommendation” but its control still isn’t full. Root cause: A control scores proportionally; the recommendation applies to many resources and only some are Healthy. Confirm: Recommendation → Affected resources — the Unhealthy count is still above zero. Fix: Remediate the remaining unhealthy resources. A control pays its full points only when all applicable resources are Healthy.
Missing plan — a recommendation you expected isn’t in the list at all.
Root cause: The recommendation is produced by a Defender plan that isn’t enabled (it lives behind paid coverage, not the free foundational layer).
Confirm: az security pricing list shows that plan’s pricingTier as Free (off).
Fix: If you want that coverage, enable the plan (tier Standard) — a billing decision. If you don’t, accept that those recommendations won’t appear or score.
Missing agent — machines show as “not assessed” rather than Healthy or Unhealthy. Root cause: The machine has no Azure Monitor Agent / required extension, so the platform has no OS-level data to evaluate. (If you still run the retired MMA/Log Analytics agent, migrate to AMA.) Confirm: Look for the “machines should have the Azure Monitor Agent installed” recommendation; or VM → Extensions shows the agent missing. Fix: Turn on auto-provisioning for AMA (Environment settings → Auto-provisioning), or install it per machine. Then wait a cycle for the data to flow.
Surprise green — a recommendation shows healthy but nobody fixed it.
Root cause: An exemption (Waiver or Mitigated) excluded the resource/recommendation, so it reads Not applicable and left the score math.
Confirm: Recommendation status shows exempt; az policy exemption list enumerates the exemptions and their categories.
Fix: Verify the exemption is intentional and documented (auditors will ask). Remove it if it was created in error.
Score drift — the number fell and you changed nothing. Root cause: Either Microsoft added a new GA recommendation that found unhealthy resources, or new (misconfigured) resources — often a freshly onboarded subscription — entered scope and grew the denominator. Confirm: Secure Score over time plus the recently-added recommendations explain the delta; per-subscription scores reveal which scope is low. Fix: Treat as normal drift; remediate the newly-flagged items and report per-subscription where it matters. The tool got stricter or your estate grew — neither is a bug.
Best practices
- Fix, then wait a day before you judge. The ~24-hour refresh is the number-one source of “it’s broken.” Bake a one-cycle wait into every remediation runbook so nobody re-fixes in circles.
- Always confirm the scope first. Before reading, comparing, or screenshotting a score, check the management-group/subscription picker. A “low” score is often the wrong scope, not a real regression.
- Score controls, not recommendation counts. Plan work by control: high max-score, low percentage, many unhealthy resources = best return. “Recommendations closed” is a misleading progress metric on its own.
- Finish controls to completion. Because credit is proportional and full points come only at 100% healthy, prioritise finishing a control over scratching the surface of ten.
- Get the data pipeline right before chasing findings. Enable auto-provisioning for the Azure Monitor Agent and confirm connectors/Arc are healthy — un-assessed resources contribute nothing and waste remediation effort.
- Use exemptions deliberately and document them. Reserve Waiver/Mitigated for genuine false positives or real compensating controls, always with a reason and (where possible) an expiry. Don’t game the score.
- Manage Defender plans and policy as code. Set
Microsoft.Security/pricingsand the security initiative in Bicep/Terraform so a human can’t silently disable the very thing that produces your recommendations. - Report the trend and the controls, not just the percentage. Pair the number with Secure Score over time and “controls completed this period” so steady progress on a big estate is visible to leadership.
- Expect and explain drift. When the score moves with no remediation, look at what entered/left scope and whether the recommendation set changed — communicate it as drift, not failure.
- Separate dev from prod in reporting. A messy dev subscription will drag a blended score; scope production separately for any audit or board metric.
- Treat the free foundational layer as the baseline, plans as a choice. Know which recommendations are free (foundational CSPM) and which need paid plans, so a missing finding is never mistaken for a clean environment.
Security notes
- Right-size who can change the score’s inputs. Creating exemptions, disabling Defender plans, or unassigning the security initiative all change posture measurement. Limit those actions with RBAC — broadly, Security Admin to manage Defender settings, Reader/Security Reader for those who only consume the score — so the metric can’t be quietly gamed.
- Audit exemptions as a control of their own. An exemption is an accepted (or relocated) risk. Review the exemptions list periodically, require a documented reason and category, and prefer time-boxed exemptions so accepted risk doesn’t become permanent invisible debt.
- Protect the policy initiative behind the score. The built-in security initiative is what produces assessments; an accidental or malicious change to it can blank out whole swathes of recommendations. Manage it as code, restrict who can edit assignments, and alert on changes.
- Use managed identity for connectors and automation, not secrets. Where Defender for Cloud automation or multicloud connectors authenticate, prefer managed identities over stored credentials (see Managed Identities Demystified); a leaked connector secret is a posture-data exposure.
- Don’t let “raise the score” become “hide the risk.” Exempting findings or scoping reporting to a tidy subscription can make the number look better without improving security. Keep the score honest — it’s a safety instrument, not a vanity metric — and review remediations for substance, not just status.
- Mind data residency and access for posture data. Recommendations and assessments describe your weaknesses; treat that telemetry as sensitive, control who can read it, and keep it within your governed boundary.
Cost & sizing
The good news for a Basic reader: Secure Score itself is free. It’s part of the foundational CSPM layer that’s on by default for every subscription — you get the score, the recommendations from the built-in initiative, asset inventory, and exemptions at no charge. You can run the entire diagnostic workflow in this article (and the lab) without enabling a single paid plan.
What costs money is deeper coverage, and it’s the most common reason a recommendation is missing rather than a score being stuck:
- Defender plans are billed per resource, per plan (Defender for Servers per machine/hour, for Storage per account or per transaction depending on the sub-plan, for SQL per resource, for Containers per vCPU, and so on). Enabling a plan unlocks its recommendations and alerts — and starts its meter. Enable the plans whose coverage you actually need, and use the per-subscription plan settings to avoid paying for coverage on subscriptions that don’t need it.
- The paid Defender CSPM plan adds advanced posture features (agentless scanning, attack-path analysis, deeper insights) beyond the free foundational layer. It’s optional; the free layer already gives you Secure Score. Treat upgrading to it as a value decision, not a requirement for getting the score to move.
- Agents are largely free to run, but their telemetry can bill downstream. The Azure Monitor Agent itself is free; if you route data to a Log Analytics workspace, that ingestion is billed per GB. Right-size what you collect.
A rough mental model for a small estate (the Northwind scale — ~40 VMs, a dozen storage accounts, a few SQL): foundational CSPM and the score cost ₹0. Turning on Defender for Servers across those VMs plus Storage and SQL is a modest monthly figure that scales with resource count — a posture-coverage choice, not a prerequisite for diagnosing a stuck score. The cost levers and what each buys you:
| Cost item | What you pay for | Free? | What it changes |
|---|---|---|---|
| Foundational CSPM | Secure Score, built-in recommendations, inventory, exemptions | Yes | The score and most posture findings |
| Defender plan (per type) | Plan-specific recommendations + alerts | No — per resource | Whether certain recommendations exist at all |
| Defender CSPM (advanced) | Agentless scan, attack paths, deeper insights | No — add-on | Richer posture beyond the free baseline |
| Azure Monitor Agent | The agent process itself | Yes | Enables machine assessments (data plumbing) |
| Log Analytics ingestion | Per-GB telemetry storage | No — per GB | Where agent data lands (right-size it) |
Interview & exam questions
1. How is Secure Score calculated, in one or two sentences? It’s the sum of points earned across all in-scope security controls divided by the total available points, as a percentage. Each control has a maximum and pays out proportionally to the fraction of its applicable resources that are Healthy — full points only when every applicable resource is healthy.
2. You fixed a misconfiguration but the score didn’t change. What’s the most likely reason, and how do you confirm it? The assessment hasn’t refreshed — Defender for Cloud re-evaluates periodically (commonly within ~24 hours), not on change. Confirm by opening the recommendation: the resource still shows Unhealthy with a stale evaluation timestamp. Wait a cycle before re-acting.
3. What’s the difference between a recommendation and an assessment? A recommendation is the finding you act on (the rollup); an assessment is the per-resource evaluation behind it stamping each resource Healthy / Unhealthy / Not applicable. The score is computed from the assessment statuses, so diagnosis means dropping to the per-resource layer.
4. Why might fixing one VM in a control barely move the score? Controls score proportionally: one healthy resource out of many is a small fraction of that control’s points, and the overall percentage spreads that across all controls’ total points. Full credit requires all applicable resources healthy.
5. A recommendation you expected isn’t in the list at all. Why? The recommendation is produced by a paid Defender plan that isn’t enabled — the free foundational CSPM layer doesn’t include it. Confirm with az security pricing list (the plan’s tier is Free). Enabling the plan (tier Standard) is a billing decision.
6. Your VMs show as “not assessed.” What’s missing and how do you fix it? The Azure Monitor Agent (or a required extension) isn’t installed, so there’s no OS-level data to evaluate. Turn on auto-provisioning for AMA or install it per machine, then allow a cycle. (Migrate any legacy MMA/Log Analytics agent to AMA.)
7. The score dropped overnight with no action on your side. Give two plausible causes. Score drift: either Microsoft added a new GA recommendation that found unhealthy resources, or new misconfigured resources/subscriptions entered scope and grew the denominator. Both lower the percentage with no failure on your part; the Secure Score-over-time trend explains it.
8. What is an exemption, and how can it change the score? An exemption (category Waiver or Mitigated) excludes a resource/recommendation from scoring — it shows as Not applicable and leaves the math, which can raise the score. Use it only for genuine false positives or real compensating controls, and document the reason.
9. Does setting a governance rule (owner + ETA) improve the score? No. A governance rule assigns accountability and a remediation due date; it organises the work but doesn’t remediate anything or change the score. The score still depends on the actual fix plus the refresh.
10. What’s the difference between foundational CSPM and the Defender CSPM plan? Foundational CSPM is the free layer (on by default) giving Secure Score, built-in recommendations, inventory, and exemptions. Defender CSPM is the paid plan adding advanced posture features (agentless scanning, attack-path analysis). You don’t need the paid plan to get or move the score.
11. AWS resources aren’t appearing in your Secure Score. What do you check? The cloud connector for the AWS account — its health in Environment settings. If the connector is unhealthy or absent, those resources aren’t assessed and don’t count. Repair/re-create the connector and let it sync.
12. Why is “always confirm the scope” the first troubleshooting step? Because the score is per-scope (management group or subscription, set by the page picker). A score that looks wrong is frequently the wrong scope — a dev subscription, or a narrower MG. Confirming scope (az account show) prevents chasing a non-existent regression.
These map to SC-200 (Security Operations Analyst) — mitigate threats using Microsoft Defender for Cloud, manage posture and Secure Score — and AZ-500 (Azure Security Engineer) — implement and manage Defender for Cloud, Secure Score, and security policies. The policy mechanics also touch AZ-104 / AZ-305 governance objectives. A compact cert-mapping for revision:
| Question theme | Primary cert | Objective area |
|---|---|---|
| Score calculation, controls | SC-200 / AZ-500 | Manage security posture; Secure Score |
| Assessments, refresh, recommendations | SC-200 | Defender for Cloud operations |
| Defender plans & coverage | AZ-500 | Configure Defender for Cloud plans |
| Exemptions, governance rules | AZ-500 / SC-200 | Security policy & posture management |
| Policy initiative behind assessments | AZ-500 / AZ-305 | Governance with Azure Policy |
| Multicloud connectors / Arc | AZ-500 / SC-200 | Connect AWS/GCP/hybrid to Defender |
Quick check
- You remediated a storage account but Secure Score is identical five minutes later. What’s the single most likely reason, and what should you do?
- True or false: closing a recommendation always raises the score by a fixed, immediate amount.
- Your VMs show as “not assessed” rather than Healthy or Unhealthy. What’s missing?
- A recommendation you expected to see isn’t in the Recommendations list at all. Name the most likely cause.
- Your Secure Score is 41% but a teammate insists it’s 68% for the same tenant. What do you check first?
Answers
- The assessment hasn’t refreshed yet — Defender for Cloud re-evaluates periodically (commonly within ~24 hours), not the instant you change a resource. Wait for the next cycle and re-check the following day; re-remediating or hammering refresh does nothing.
- False. Controls score proportionally to the fraction of applicable resources that are healthy, controls are weighted differently, and the change appears only after the next refresh — so closing a recommendation can move the score by a sliver, a lot, or (until the cycle runs) not visibly at all.
- The Azure Monitor Agent (or a required extension) is not installed on those machines, so there’s no OS-level data to evaluate. Enable auto-provisioning (or install AMA per machine) and wait a cycle.
- The recommendation is produced by a paid Defender plan that isn’t enabled (the free foundational layer doesn’t include it). Check
az security pricing list; enabling the plan is a billing decision. - The scope — the management-group/subscription picker at the top of the page. The score is per-scope, so one of you is viewing a different subscription/MG. Confirm with the picker (and
az account show) before assuming a regression.
Glossary
- Microsoft Defender for Cloud — Azure’s cloud security posture management (CSPM) and workload protection service; it assesses configuration against best practice and produces Secure Score.
- Secure Score — the single percentage summarising how well in-scope resources follow Microsoft’s security recommendations; points earned ÷ points available across controls.
- Security control — a group of related recommendations assigned a maximum score; it earns points proportionally to the share of its applicable resources that are Healthy.
- Security recommendation — a best-practice finding to act on (the rollup of an assessment across resources).
- Assessment — the per-resource evaluation behind a recommendation, with status Healthy, Unhealthy, or Not applicable.
- Healthy / Unhealthy / Not applicable — the three assessment states; only Healthy earns credit, Not applicable is excluded from the math.
- Foundational CSPM — the free posture layer (on by default) providing Secure Score, built-in recommendations, inventory, and exemptions.
- Defender CSPM — the paid plan adding advanced posture features (agentless scanning, attack-path analysis) beyond the free layer.
- Defender plan — a paid, per-resource-type capability (Servers, Storage, SQL, Containers, …) that unlocks plan-specific recommendations and alerts and is billed per resource.
- Exemption — excluding a resource/recommendation from scoring, with category Waiver (risk accepted) or Mitigated (handled elsewhere); shows as Not applicable.
- Governance rule — assigns an owner and remediation due date (ETA) to recommendations; it tracks work but does not remediate or change the score.
- Azure Monitor Agent (AMA) — the agent that reports OS-level posture from VMs and Arc-enabled servers; required for many machine assessments (replaces the retired MMA/Log Analytics agent).
- Auto-provisioning — automatically installs required agents/extensions across a subscription so new resources are assessed without manual steps.
- Cloud connector — the integration onboarding AWS or GCP accounts into Defender for Cloud so their resources are assessed and scored.
- Azure Arc — the service that projects on-prem and other-cloud servers into Azure so Defender for Cloud can assess them.
- Scope — the management group or subscription currently selected in the page header, which determines exactly which resources the score reflects.
- Score drift — a change in Secure Score caused by what’s in scope or the recommendation set changing (onboarding, new GA recommendations, deletions), not by your remediation.
- Security initiative — the built-in Azure Policy set whose evaluations produce Defender for Cloud’s assessments; disabling or replacing it removes recommendations.
Next steps
You can now read Secure Score correctly, walk down the pipeline from number to per-resource truth, and name why a score is stuck in ninety seconds. Build outward:
- Next: Azure Policy Effects Decoded: Deny vs Audit vs Modify vs DeployIfNotExists — the policy mechanics behind every assessment that decides Healthy vs Unhealthy.
- Related: Policy Definitions vs Initiatives: When to Bundle Controls into a Set — how the security initiative that drives your recommendations is built.
- Related: Onboarding Servers to Azure Arc: Connected Machine Agent & Bulk Enrollment — get on-prem and other-cloud machines into the score in the first place.
- Related: Azure Monitor and Application Insights: Full-Stack Observability — the agent and log plumbing behind machine-level assessments.
- Related: Managed Identities Demystified: System vs User-Assigned and When to Use Each — the identity pattern for connectors and posture automation done safely.