Most Office hardening guides make macros sound simple: block them. In a real organisation, it rarely works that way.
I’m currently working through an Essential Eight project, and the macro control is proving to be one of the harder parts to implement properly. Like many organisations that have been around for a while, we have legacy spreadsheets, templates and small business tools that people still rely on. Some were written years ago, and in some cases the person who created them no longer works here.
The security answer is obvious: don’t allow arbitrary macros to run. The business answer is less obvious: don’t break the processes people depend on every day.
The approach I’m taking is to start with the Microsoft 365 Apps security baseline in Intune, work out exactly who still has a business requirement for macros, and then put progressively stronger controls around the macros that remain. The interesting part is what happens when you get to trusted locations, ASR rules and old VBA code.
Start with the Microsoft 365 Apps security baseline
Intune includes a security baseline for Microsoft 365 Apps for enterprise, under Endpoint security > Security baselines. It’s a pre-built set of recommended Office settings, and it’s the fastest way to lift your starting point. Among other things, it enables the policy that blocks macros in Office files from the internet, which Microsoft recommends as part of the baseline (Microsoft Learn: Macros from the internet are blocked by default). Microsoft also publishes specific Essential Eight guidance for configuring Microsoft 365 Apps (Microsoft Learn: Configure Microsoft Office macro settings for Essential Eight).
The important thing is not to treat the baseline as the finished configuration. It doesn’t know which legacy applications you depend on, where those files are stored, or which users genuinely need macros. Before applying it broadly, I’d do three things:
- Pilot it first. Assign it to a small test group, and include people who actually use macro-enabled documents. Testing only with IT isn’t enough. A macro that works for an IT administrator tells you nothing about the spreadsheet someone in finance opens every morning.
- Watch for conflicting policies. If you also configure Office settings through the Settings Catalog, Administrative Templates or other profiles, make sure you aren’t setting the same value in more than one place. A baseline and a separate profile can easily end up fighting over the same setting, and a conflicted setting may not apply at all.
- Treat it as the foundation. The baseline gets you started. The next question matters much more: who actually needs macros?
What Essential Eight actually asks for
“Configure Microsoft Office macro settings” is one of the Essential Eight mitigation strategies, and the controls get stronger at each maturity level. The macro requirements can be summarised like this (ASD: Essential Eight maturity model):
| Macro control | ML1 | ML2 | ML3 |
|---|---|---|---|
| Macros disabled for users without a demonstrated business requirement | Yes | Yes | Yes |
| Macros in files originating from the internet are blocked | Yes | Yes | Yes |
| Macro antivirus scanning is enabled | Yes | Yes | Yes |
| Users can’t change macro security settings | Yes | Yes | Yes |
| Macros are blocked from making Win32 API calls | No | Yes | Yes |
| Allowed and blocked macro executions are logged | No | Yes | Yes |
| Only macros in a sandbox, a trusted location or signed by a trusted publisher can run | No | No | Yes |
| Macros are checked for malicious code before being signed or placed in a trusted location | No | No | Yes |
| Only privileged users responsible for checking macros can write to or modify trusted locations | No | No | Yes |
| Macros signed by an untrusted publisher can’t be enabled from the Message Bar or Backstage View | No | No | Yes |
| Macros with signatures other than V3 can’t be enabled from the Message Bar or Backstage View | No | No | Yes |
| The list of trusted publishers is validated at least annually | No | No | Yes |
You don’t need to implement all of ML3 just because you have a handful of legacy macros. But if you’re working towards ML3, putting files in a trusted folder isn’t enough. You also need to control who can modify that location, and to check that macros are safe before they’re trusted. ASD’s assessment guidance also calls out the Win32 API ASR rule and macro execution logging as the ML2 additions (ASD: Essential Eight Assessment Process Guide).
ASD updates the maturity model from time to time, so check the current version before using a summary like this as assessment evidence.
Step one: find out who actually uses macros
The first requirement at every level is that macros are disabled for users without a demonstrated business requirement. That sounds easy until you ask who actually needs them. Don’t rely only on what people tell you. Build an inventory.
Find macro-enabled files. Search file shares, SharePoint and OneDrive for .xlsm, .xlam, .docm, .pptm and older .xls files. The .xls files deserve attention because they can contain VBA even though the extension doesn’t tell you. The inventory doesn’t need to be perfect on day one. You’re looking for the business-critical macros and the teams that depend on them.
Talk to the business. Ask each team which macro-enabled files they use, where they’re stored, who uses them, what the macro actually does, who maintains it, and what happens if it stops working. That last question is the most revealing. A spreadsheet nobody can explain but which is apparently “critical” needs a different level of investigation from a documented process with a named owner.
Use audit data. Running ASR rules in audit mode first gives you evidence of what Office applications are actually doing on your devices.
The goal is a macro register that records, for each macro: the file and its location, the business owner, the users who need it, what it does, whether it needs Win32 API calls or other ASR exclusions, whether it has been reviewed, and where it will be allowed to run. Once you have that, the macro problem becomes much more manageable.
Block by default, then deal with the exceptions
The design I prefer is straightforward. Users with no demonstrated business requirement have macros disabled. Users who genuinely need macros don’t automatically get unrestricted macro execution. Instead, you put controls around the small number of macros that remain:
- block macros in files from the internet
- stop users changing macro security settings
- use trusted locations for legacy macros where appropriate, and restrict who can write to them
- use trusted publishers where practical
- apply ASR rules to limit what macros can do
- monitor and record the exceptions
The key distinction is that “this user needs macros” doesn’t mean “this user should be able to run any macro.”
Trusted locations: treat them as a security boundary
Trusted locations are attractive because they solve a very real problem. You have an old spreadsheet the business needs, Office blocks the macro, you put the spreadsheet in a trusted location, and the macro runs. Problem solved.
Not quite. A trusted location is effectively a bypass around Office’s macro protections. Office trusts the location. It doesn’t independently decide that every macro stored there is safe, so the security of the whole arrangement depends on who can put files there.
Imagine \\fileserver\FinanceMacros, where everyone in finance has read and write access, configured as an Office trusted location. A user receives a malicious macro-enabled attachment, saves it into that folder and opens it. The file is now somewhere Office has been told to trust. You’ve built a path around the very control you were trying to implement.
Restrict who can write to them
If you use trusted locations for legacy macros, separate the people who use the macros from the people allowed to change them:
Approved macro location
|
+-- Users Read / Execute
|
+-- Macro reviewers Modify / WriteUsers who need a macro should be able to read and run it, not replace it. On a file server, enforce this with share and NTFS permissions. Keep the location narrow, too. Don’t make an entire departmental share trusted when you only need one folder holding a handful of approved files.
Network paths need extra care
Office’s handling of files from network locations depends partly on Windows security zones and how the location is referenced. If users reach a share by its IP address, Windows may treat it as an internet location and block the macros anyway (Microsoft Learn: Macros from the internet are blocked by default). Use a consistent server name or fully qualified name in the trusted location, make sure users access files the same way, and test the real user workflow rather than assuming the path will work. For network locations to be trusted at all, the policy allowing trusted locations on the network also has to be enabled.
Trusted publishers are the better long-term model
Trusted locations are useful for getting legacy macros under control, but they aren’t where you want to finish. Microsoft’s Essential Eight guidance recommends trusted publishers wherever possible, because every macro in a trusted location has to be vetted individually (Microsoft Learn: Configure Microsoft Office macro settings for Essential Eight).
The model changes from “anything in this folder is trusted” to “macros signed by this approved publisher are trusted.” When a user opens the file, Office checks that the macro is digitally signed and that the certificate matches a trusted publisher before allowing it to run. That’s a much better security boundary.
Getting legacy macros signed and managed properly takes more work, particularly when the original developer has long gone. So I’d treat trusted locations as the practical answer for legacy macros while gradually moving the important, maintained ones to a signed and controlled model.
ASR rules: where legacy macros can really break
Office macro controls decide whether a macro can run. Attack surface reduction rules restrict what Office and the macro are allowed to do.
For Essential Eight, the key macro rule is Block Win32 API calls from Office macros, which has the GUID 92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b. It stops VBA macros making Win32 API calls, which malicious VBA abuses to do far more than normal spreadsheet automation. The catch is that some legitimate legacy macros do exactly that. An old spreadsheet might call a Windows API to interact with another application or do something standard VBA can’t. When you enable the rule, that macro may stop working. So don’t jump straight to Block.
Audit before you enforce
Microsoft recommends testing ASR rules in audit mode before moving them to Block or Warn. You can check a device’s ASR configuration with PowerShell, pairing each rule ID with its action:
$p = Get-MpPreference
0..([Math]::Min(
$p.AttackSurfaceReductionRules_Ids.Count,
$p.AttackSurfaceReductionRules_Actions.Count
) - 1) | ForEach-Object {
[PSCustomObject]@{
Id = $p.AttackSurfaceReductionRules_Ids[$_]
Action = $p.AttackSurfaceReductionRules_Actions[$_]
}
}The action values are 0 for off, 1 for block, 2 for audit and 6 for warn.
Then reproduce the business process. Don’t just ask the user whether the spreadsheet works: open it and run the macro yourself. If it breaks, check the ASR activity. Block events are recorded as event ID 1121 and audit events as event ID 1122 in the Microsoft-Windows-Windows Defender/Operational log, and if you have Microsoft Defender for Endpoint, you can investigate the same activity centrally.
Don’t exclude the whole application
When an old Excel macro is blocked by the Win32 API rule, the temptation is to add a broad exclusion for Excel and move on. That defeats much of the point of the control. Work out exactly what the macro does first. There are usually five options:
- Rewrite the macro without the restricted behaviour.
- Replace the business process with a modern application or workflow.
- Sign the macro and bring it under control.
- Add a narrowly scoped ASR exclusion.
- Retire the macro, because it’s no longer genuinely needed.
An exclusion should be an exception, not the normal operating model, and it should be recorded with a reason, an owner and a review date.
Scanning, internet macros and logging
Three more controls sit alongside trusted locations and ASR, and each solves a different problem.
Macro antivirus scanning. Macro blocking and macro scanning are separate controls, and Essential Eight requires scanning at every level. Office can pass macro code to your antivirus at run time, so even an allowed macro is scanned as it executes. The relevant Office policies are Force Runtime AV Scan and Macro Runtime Scan Scope, with the scan scope set to cover all documents. That matters especially for legacy macros: being allowed to run doesn’t make a macro inherently safe.
Macros from the internet. Keep this policy enabled even when you use trusted locations. A trusted location says “we’ve deliberately approved this location.” The internet control says “don’t let a macro from an external source run just because a user opened the file.” Configure the policy explicitly rather than relying on Office’s default, which could change or be overridden elsewhere.
Logging. From Maturity Level Two, allowed and blocked macro executions must be logged so you can investigate an incident. ASR audit and block events give you part of that picture, and Defender for Endpoint adds more. Whatever you use, forward the events to your SIEM or log platform, because logs that stay on a device can be lost or cleared. Confirm with your assessor what evidence they’ll expect for this control.
It’s a process, not just a setting
This is where the project becomes more than an Intune configuration exercise. At ML3, ASD requires macros to be checked for malicious code before they’re signed or placed in a trusted location, and only the privileged users responsible for that checking can write to or modify trusted locations. That means you need a process as well as a policy.
It can be as formal or as lightweight as your organisation needs, but it should cover the same steps each time: identify the business owner, review what the macro does, check it for malicious code, and then either approve it, by signing it or placing it in a controlled location, or retire it. The important part is that somebody is responsible for deciding whether a macro is safe enough to trust.
Keep an exception register
Alongside the macro register, keep a register of exceptions. For each one, record the macro or application, the business owner, the affected users, the reason, which control is being bypassed, any compensating controls, who approved it, when it started, the review date, and the plan to remediate or replace it.
It becomes invaluable six months later, when someone asks why an old Excel macro still has an ASR exclusion. Without a record, the answer is usually “because it broke something once,” and that isn’t a security control. ASD’s own guidance is that exceptions should be minimised, documented and approved.
Office hardening is broader than macros
The macro strategy sits inside a larger hardening project. Essential Eight’s User Application Hardening strategy covers related Office controls, such as blocking Office applications from creating child processes, creating executable content or injecting code into other processes, blocking the activation of OLE packages, and preventing users from changing Office security settings.
These complement macro hardening rather than replacing it. A macro that’s allowed to run should still have its ability to behave like malware restricted wherever practical. Microsoft’s Essential Eight guidance includes Intune-oriented configuration for these controls too, which helps if you’re building the configuration directly into endpoint management.
One thing to drop from older guides: Application Guard for Office. Microsoft retired it in April 2024 and is removing it from Office through 2026 and 2027, with files opening in Protected View instead (Microsoft 365 Message Center MC1182696). It was never a macro answer anyway, because it disables macros in the documents it opens.
Rolling it out without breaking the business
The technical configuration is relatively straightforward. The rollout is the hard part. This is the order I’m working in:
- Build the macro register of users, files, locations, owners and business requirements.
- Deploy the Microsoft 365 Apps baseline to a pilot group that includes real macro users.
- Disable macros for everyone without a demonstrated requirement, keeping internet macros blocked and macro scanning enabled.
- Deploy the Office ASR rules in audit mode.
- Test the actual business processes that depend on macros.
- Create controlled trusted locations for legacy macros, with write access restricted to reviewers.
- Investigate ASR events and handle legitimate exceptions, recording each one.
- Move tested ASR rules to Block in deployment rings.
- Expand gradually, team by team.
- Move important macros to trusted publishers over time.
The point is to avoid one big switch. When something breaks, you want to know exactly which control caused it.
Communicate before you enforce
If finance has used a spreadsheet for ten years and its macro suddenly stops working, telling them “Essential Eight requires it” won’t help much. Before enforcing anything, tell affected users what’s changing and why, which of their macros have been identified, where approved macros will live, what to do if one stops working, and who owns the approval process. That turns a security control from an unexpected IT problem into a managed business change.
Checklist: Essential Eight macro settings with legacy macros
- Pilot the Microsoft 365 Apps security baseline with real macro users.
- Build a macro register of files, owners, users and business requirements.
- Disable macros for users without a demonstrated business requirement.
- Keep macros from the internet blocked by explicit policy, and stop users changing macro settings.
- Enable macro antivirus scanning for all documents.
- Deploy “Block Win32 API calls from Office macros” and the other Office ASR rules, in audit mode first.
- Log allowed and blocked macro executions, and forward the logs off the device.
- Use narrow, centrally defined trusted locations for legacy macros, never a whole departmental share.
- Restrict write access to trusted locations to the people who review macros.
- Review macros before placing them in a trusted location or signing them.
- Record every exception with an owner and a review date.
- Move important macros to trusted publishers over time, and validate trusted publishers at least annually for ML3.
The goal isn’t to break every macro
The goal is to make macro execution deliberate. For users who don’t need macros, block them. For legacy processes that genuinely need them, understand what the macro does and put controls around it. For macros that are still important and maintained, move towards a trusted publisher model. And for everything else, ask whether the macro still needs to exist at all.
That’s the part I think gets lost in a lot of Essential Eight guidance. The objective isn’t to make an Intune policy turn green. It’s to move from a place where anyone can run a macro, nobody really knows which macros exist, and legacy files are “too important to touch,” to one where every macro that runs has a known business requirement, has been reviewed, runs under controlled conditions, and is monitored until it’s eventually signed or replaced.
For organisations with years of accumulated Excel and Office automation, that’s a much more realistic way to approach Essential Eight macro hardening.
Sources
- ASD: Essential Eight maturity model
- ASD: Essential Eight Assessment Process Guide (PDF)
- Microsoft Learn: Configure Microsoft Office macro settings for Essential Eight
- Microsoft Learn: Macros from the internet are blocked by default in Office
- Microsoft 365 Message Center MC1182696: Application Guard for Office is being removed

From my early days on the helpdesk through roles as a service desk manager, systems administrator, and network engineer, I’ve spent more than 25 years in the IT world. As I transition into cyber security, my goal is to make tech a little less confusing by sharing what I’ve learned and helping others wherever I can.

