By the end of this you have the Azure compute security baseline assigned in audit against a pilot scope, its per-setting result read rather than its headline percentage, a deliberate choice between visible drift and silent auto-correction, the machines that were already adrift remediated in a change window, and the meter and its waivers confirmed before you widen it. This lands the two decisions the doctrine article said you could not avoid, and it names the real policy, the real modes, and the real commands so you can reproduce it. The portal walk comes first, then the same thing as a script.
Before Step 1: Arc-connected machines (the machine configuration agent ships inside the Connected Machine agent, so there is nothing to install), rights to assign Azure Policy at your chosen scope and to create a remediation task, and a pilot resource group or a tag you can scope to. The name to know throughout is Azure machine configuration, which is what guest configuration is now called.
Step 1: Assign the built-in baseline in audit, at a pilot scope
Start in audit every time, because you want to see what the baseline would flag before anything changes. In Azure Policy, open Definitions, find the built-in definition named “Windows machines should meet requirements for the Azure compute security baseline” (the portal may still render this as “of the Azure compute security baseline”), and assign it scoped to your pilot resource group. This definition is AuditIfNotExists, so it reports compliance and changes nothing. Leave it reporting and collect the truth about your current state.
| Setting | Value | Why |
|---|---|---|
| Definition | Windows machines should meet requirements for the Azure compute security baseline | A built-in, maintained for you. Author a custom package only when no built-in fits. |
| Scope | The pilot resource group, not a management group | A management group reaches every server beneath it. Prove the baseline small before you widen it. |
| Effect | AuditIfNotExists | Reports compliant or not and changes nothing, so you see the blast radius before you accept it. |
The same as a script. You assign the built-in definition to the pilot resource group by its definition id:
az policy assignment create \
--name "MC-ComputeBaseline-Pilot" \
--display-name "Windows compute security baseline (audit, pilot)" \
--policy "<compute-baseline-definition-id>" \
--scope "/subscriptions/<sub-id>/resourceGroups/rg-arc-servers-pilot"
Expected result: the assignment appears and, after the first evaluation, the pilot machines report compliant or not against each setting. Failure mode: assigning at a management group “to cover everything” reaches your whole estate at once, which is the opposite of a pilot. On Arc there is nothing else to install, because the machine configuration agent is part of the Connected Machine agent already.
Step 2: Read the per-setting result, and expect lag
Give it time before you trust the number. The in-guest service requests its assignment list every five minutes, and the compliance rollup you see can trail the real state, so a machine that reads non-compliant for a few minutes after assignment is normal, not broken. Read the per-setting detail in the compliance view, not just the headline percentage, because that detail is where you learn which controls will actually change something when you move to enforcement. A baseline that flags forty settings you already meet is a different decision from one that flags three you do not.
Step 3: Promote to enforcement, and make the drift decision
The built-in definition you assigned in Step 1 only audits; it has no apply mode and never will, because its effect is AuditIfNotExists. Enforcement is a separate definition. On current Windows estates the enforcing path is the customizable security baseline, generally available since late May 2026, which runs on the OSConfig engine and lets you include or exclude individual rules and edit their expected values, or a custom machine configuration package you author when no baseline fits. Either one is delivered by a definition whose effect is DeployIfNotExists, and it is that enforcing definition, not the audit one, that carries an apply mode. This is the moment the doctrine article warned about, because the mode you choose decides whether you can prove drift happened later. Choose it per baseline, deliberately, and record why.
| Mode | Behavior | Choose it when |
|---|---|---|
| Audit | Reports state, makes no change | You are still assessing, or something else owns enforcement |
| ApplyAndMonitor | Applies once, then reports drift without correcting it. Drift stays visible and is only fixed by a remediation run. | You need drift visible for audit or investigation more than you need it auto-healed |
| ApplyAndAutoCorrect | Re-asserts state at every evaluation; the machine reads Compliant continuously. There is no timestamped record of the drift interval, so you keep the compliance history but lose how long the machine was wrong. | Continuous enforcement matters more than a timestamped drift trail |
Keep two effects straight, because it is the easiest thing to get wrong here. The baseline you assigned in Step 1 is AuditIfNotExists, which only reports. The definitions that push changes inside the machine use the DeployIfNotExists effect, and that is also what the remediation path in the next step runs on. Auditing and enforcing are different definitions, not a toggle on one. The customizable security baseline that carries the apply behavior is generally available and runs on the OSConfig engine, so you include or exclude individual rules and edit their expected values rather than accept the fixed built-in wholesale, and it is delivered as a DeployIfNotExists assignment you can run alongside the Step 1 audit assignment without conflict.
Step 4: Remediate the machines that were already adrift
A machine that comes online after the enforcing assignment is in place is brought into line by the normal evaluation cycle. A machine that already existed and was already non-compliant does not self-heal from the assignment alone; it needs a remediation task run once against it. In the portal, open the assignment’s Remediation tab and create a remediation task. It runs under the system-assigned managed identity that belongs to the policy assignment itself, the one created and granted a role when you set up the enforcing assignment, not the identity of the machine, which is why a DeployIfNotExists assignment must be created with an identity and the correct role. Run the task deliberately, in a change window, because for these machines this is the moment state actually changes.
az policy remediation create \
--name "remediate-compute-baseline-pilot" \
--policy-assignment "MC-ComputeBaselineEnforce-Pilot" \
--resource-group "rg-arc-servers-pilot"
Expected result: the pre-existing machines move to compliant after the task completes, and the in-guest agent maintains the state going forward. Failure mode: if the managed identity is missing or lacks the role its remediation needs, the task completes without changing anything and the machine stays adrift, which reads as success until you look at the settings.
Step 5: Confirm the meter and its waivers
Before you widen the scope to the fleet, know what it costs. Machine configuration bills at roughly six dollars per server per month, on a combined meter with change tracking and inventory, and that charge is waived under conditions worth checking against your estate rather than assuming.
| Situation | Machine configuration charge |
|---|---|
| Plain Arc machine, no qualifying licensing | Billed on the combined per-server meter, about six dollars per server per month |
| Windows Server with active Software Assurance or subscription licenses, attested | Waived under Windows Server Management enabled by Azure Arc |
| Defender for Servers Plan 2 enabled on the subscription | Included at no additional cost |
| Machine enrolled in Extended Security Updates through Arc | Included for the enrolled machine |
A worked example
Take a pilot of three Windows file servers that carry Software Assurance. You assign “Windows machines should meet requirements for the Azure compute security baseline” to rg-arc-servers-pilot in audit, and reading the per-setting result you see the baseline would tighten SMB signing and disable a legacy protocol the application team still relies on. Because you need that change to be visible and reversible rather than silently healed, you stand up the enforcing assignment, the customizable baseline as a DeployIfNotExists policy, in ApplyAndMonitor rather than ApplyAndAutoCorrect. The three servers predate that enforcing assignment, so you run a remediation task against it during Saturday’s window and confirm they move to compliant. The meter reads zero for them, because they are attested under Windows Server Management enabled by Azure Arc, so widening to the rest of the file-server fleet adds settings governance at no new cost. Every choice here was a decision you can defend, not a default you accepted.
Naming convention
Name assignments so a compliance dashboard reads cleanly at a glance. Use a prefix and purpose, for example MC-ComputeBaseline-Pilot and later MC-ComputeBaseline-Prod, and keep the same scheme across every baseline you assign. Scope pilots by a dedicated resource group or a Stage=Pilot tag so promotion to production is a scope change, not a new invention. Consistent assignment names are what let you read fleet compliance by baseline rather than by hunting through a list.
The end-to-end test
Prove the enforcement path on one machine before you trust it across the fleet. On a test server carrying the enforced baseline, deliberately change one governed setting out of compliance, then wait for the next evaluation. If you chose ApplyAndMonitor, the machine should report the drift and leave it for you. If you chose ApplyAndAutoCorrect, the setting should return to its enforced value on its own within an evaluation cycle. Seeing the mode behave exactly as designed on a setting you broke on purpose is the difference between believing the baseline works and knowing it does.
Rolling it back
This is the rollback with the sharpest caveat in the series, so read the caveat before the steps: removing an assignment stops future enforcement, it does not revert settings already applied to a machine. A baseline you enforced and then rolled back leaves the machine configured the way the baseline wanted it. If you need the previous state back, you need a deliberate change, not a deletion.
- Delete the remediation task first, so nothing is mid-flight while you remove what it targets:
az policy remediation delete --name "remediate-compute-baseline-pilot" --resource-group "rg-arc-servers-pilot". - Remove the enforcing DeployIfNotExists assignment:
az policy assignment delete --name "MC-ComputeBaselineEnforce-Pilot" --resource-group "rg-arc-servers-pilot". Removing the assignment also orphans the system-assigned managed identity it created, so clean up its role assignment rather than leaving a privileged identity with nothing to do. - Remove any guest assignment the enforcing policy left behind on the machine. Deleting the policy assignment in Azure does not necessarily remove the guest configuration assignment resource that was created against the machine, and a leftover guest assignment keeps reporting on a baseline nobody owns anymore.
- Remove the audit assignment, for example
MC-ComputeBaseline-Pilot, once you no longer want the compliance reporting either. Keeping audit while dropping enforce is a perfectly reasonable half-rollback, and often the right one. - Confirm the settings on one machine by hand and decide explicitly whether to leave them. This is the step people skip, and it is the only one that tells you what your estate is actually configured like now.
- Check the meter, because machine configuration bills on a combined per-server meter with change tracking and inventory. If change tracking arrived alongside this baseline and you leave it running, the charge does not go away just because the baseline did.
Before you widen the scope
- Baseline assigned in audit first, at a pilot scope, with the per-setting result read before enforcing.
- Enforcement mode chosen per baseline, with the drift-visibility trade recorded, not defaulted, and the AuditIfNotExists-versus-DeployIfNotExists distinction kept straight.
- Remediation task run for pre-existing non-compliant machines in a change window, with the managed identity confirmed so it actually changes state.
- Meter confirmed, and any waiver (Software Assurance attestation, Defender Plan 2, ESU enrollment) verified against the real machines.
- End-to-end test passed: a deliberately broken setting was caught or corrected exactly as the chosen mode dictates.
With settings under control, the other half of what the domain did for a server comes next: keeping it patched. The following article takes up Azure Update Manager and the WSUS story it is written to replace.
Azure Arc
‹ Previous: [ARC 3] Policy and Machine Configuration: The GPO Question, Answered Honestly
Next: [ARC 4] Update Manager: Patching After WSUS ›




