In this post, I will cover the steps to collect App Control for Business event logs. This is one of the most important steps when implementing App Control for Business on Windows devices. To begin, you create a base policy either by using the built-in control method in Intune or by using the App Control Policy Wizard. Whichever method you choose, the best practice is to start with Audit mode.
After creating a base policy in Audit mode, you deploy it to target devices through Intune. Audit mode allows you to safely observe how the policy would behave without actually blocking applications. This gives you the opportunity to collect event data, identify which applications are being flagged/blocked, and build an inventory of business-critical apps, scripts etc.
Once you have gathered enough data and refined your base and supplemental policies to allow business apps, you can confidently move toward Enforcement mode, minimizing the risk of disrupting end users.
To review the events captured in Audit mode, you can use two primary methods: Event Viewer on the client device or Advanced Hunting in the Microsoft Defender portal. Advanced Hunting requires a Microsoft Defender for Endpoint Plan 2 license. If you do not have this license, there are alternative methods available to collect events from devices. For example, you can use Log Analytics / Azure Monitor / Microsoft Sentinel to forward Code Integrity (CI) logs to a Log Analytics workspace, where you can then query the events using KQL (Kusto Query Language).
If you are using a third-party product that can forward events from devices to a central server for analysis, you can leverage that as well. The key is to use whichever method makes it easier to centralize and analyze Event Viewer data, so you can quickly identify which applications are being flagged by App Control for Business.
I have also written a few related guides that can help you collect Intune logs from Windows and macOS devices. Refer to below links for detailed steps:
Contents
Collect App Control Events Using Event Viewer Logs
When a base policy is deployed in Audit mode, App Control for Business records detailed logs in the Code Integrity Operational log. These events (3076) show exactly which applications, DLLs, or scripts would have been blocked if the policy were in Enforcement mode.
In Enforcement mode, you will see blocked enforcement events (3077) instead of 3076. These events indicate that applications were launched on the device, but were blocked by an active App Control policy.
- Sign in to one of the target Windows device where you have deployed App control base policy.
- Open Event viewer > Applications and Services Logs > Microsoft > Windows > CodeIntegrity > Operational. Right-click on it and click Filter Current log. Use below Event IDs to filter the Events.
- 3076 – Audit event (application would have been blocked)
- 3077 – Enforcement event (application blocked when in Enforcement mode)
- 3089 – Signing information associated with a block/audit event
- 3099 – Policy successfully loaded
Event ID 3076
Below are a few examples of Audit Event ID 3076, which show the Apps/DLLs impacted by the App Control policy.
- The first event shows the EPM Agent (System.Reactive.dll) being blocked because it did not meet the Enterprise signing level requirements. The app was allowed to run since the CI policy is in Audit mode.
- The second event is related to the 7-Zip app (7-zip.dll) for the same reason and was also allowed to run due to Audit mode.
There are several other 3076 information events; review each of them to see which applications, DLLs, and scripts are being blocked on devices. You can then compile a list of apps and decide which ones to allow or leave blocked.
Code Integrity determined that a process (\Device\HarddiskVolume3\Program Files\Microsoft EPM Agent\EPMService\EpmService.exe) attempted to load \Device\HarddiskVolume3\Program Files\Microsoft EPM Agent\EPMService\System.Reactive.dll that did not meet the Enterprise signing level requirements or violated code integrity policy (Policy ID:{2da0f72d-1688-4097-847d-c42c39e631bc}). However, due to code integrity auditing policy, the image was allowed to load.
App control Event ID 3076 (Audit Event) — for EPM Agent
Code Integrity determined that a process (\Device\HarddiskVolume3\Windows\explorer.exe) attempted to load \Device\HarddiskVolume3\Program Files\7-Zip\7-zip.dll that did not meet the Enterprise signing level requirements or violated code integrity policy (Policy ID:{c4d1b273-a2e9-4460-ba31-1d2b6828b1f1}). However, due to code integrity auditing policy, the image was allowed to load.
Another App control Event ID 3076 (Audit Event) — for 7zip app
To fetch Event ID 3076 events faster, you can also use below PowerShell script. I have customized the script specifically for this Event ID, the script may not provide the expected results when you change the Event ID number in the script. You can download this script from my GitHub repo as well: Get_Audit_Event_3076.ps1.
Get_Audit_Event_3076.ps1
Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -MaxEvents 300 |
Where-Object Id -eq 3076 |
ForEach-Object {
if ($_.Message -match '(?s)attempted to load\s+(?<path>.+?)\s+that did not meet.*Policy ID:\{(?<policyid>[0-9a-fA-F\-]+)\}\)\.\s+(?<action>.+)$') {
[pscustomobject]@{
TimeCreated = $_.TimeCreated
AttemptedPath = $matches['path']
'Violated Code Integrity Policy' = $matches['policyid']
ActionTaken = $matches['action']
}
}
} | Format-Table -AutoSize
The screenshot below shows the script’s output, which includes the following columns: TimeCreated, AttemptedPath, Violated Code Integrity Policy, and ActionTaken.
Event ID 3077
When you switch your base policy from Audit to Enforced mode. Applications, DLLs, scripts etc. which are not allowed by the app control policy will be blocked from running. An event ID 3077 will be written to the Event log every time an app is launched but was blocked by the policy.
- Open Event viewer > Applications and Services Logs > Microsoft > Windows > CodeIntegrity > Operational. Right-click on it and select Filter Current log, then use the Event ID 3077 to filter the logs. Below are few examples of the Event ID 3077.
Code Integrity determined that a process (\Device\HarddiskVolume3\Windows\explorer.exe) attempted to load \Device\HarddiskVolume3\Users\jatin.AzureAD\AppData\Local\Programs\RingCentral\RingCentral.exe that did not meet the Enterprise signing level requirements or violated code integrity policy (Policy ID:{dcc1024b-aab8-40a6-8db3-6305672b6979}).
Event ID 3077 — RingCentral.exe application blocked event
Code Integrity determined that a process (\Device\HarddiskVolume3\Windows\explorer.exe) attempted to load \Device\HarddiskVolume3\Program Files\Foxit Software\Foxit PDF Reader\FoxitPDFReader.exe that did not meet the Enterprise signing level requirements or violated code integrity policy (Policy ID:{dcc1024b-aab8-40a6-8db3-6305672b6979}).
Event ID 3077 — Foxit PDF reader application blocked event
There are several other 3077 information events; review each one to identify which applications, DLLs, and scripts are being blocked on devices. Go through all of them to verify and confirm whether these blocks are expected according to the policy.
Event ID 3099
Event ID 3099 indicates whether a Code Integrity (CI) App Control policy has been successfully loaded on the system. A key detail in this event log is the GUID of the policy. Compare it with the GUID of your deployed policy (Base Policy ID) to confirm that the policy has been successfully loaded on the system. Below is an example of an Event ID 3099.
Refreshed and activated Code Integrity policy {2da0f72d-1688-4097-847d-c42c39e631bc} Intune Windows Audit Supplemental_ManagedInstaller_ISG Policy. id 031017. Status 0x0
Event ID 3099 — Code Integrity Policy Activated Successfully
Collect App Control Events Using Advanced Hunting
For a broader view across your environment, you can use Advanced Hunting in the Microsoft Defender portal. This lets you query audit events centrally and build an inventory of all applications reported under Audit mode. Please note that this feature requires Microsoft Defender for Endpoint Plan 2.
- Sign in to the Microsoft Defender Portal > Investigation & response > Hunting > Advanced Hunting.
- Execute below device queries to gather the data for App control Events. Event ID 3076 (Audit mode), Event ID 3077 (enforced mode) and Event ID 3099 (Policy load status).
Gathering Audit Events Data
Copy and paste below query to list all applications that were blocked but allowed as the policy is in audit mode. You can update the condition Timestamp > ago(7d)
in the query to adjust the number of days for which you want to collect information from the device. The output will contain these columns: Timestamp, DeviceName, FileName, FilePath, FileHash, PolicyName, PolicyID. You can click on Export button to export the events to a CSV file.
AppControlCodeIntegrityPolicyAudited Events (Event ID 3076)
DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "AppControlCodeIntegrityPolicyAudited"
| extend AF = todynamic(AdditionalFields)
| extend PolicyName = tostring(AF.PolicyName),
PolicyID = tostring(AF.PolicyID),
FilePath = FolderPath,
FileName = FileName,
FileHash = SHA256
| project Timestamp, DeviceName, FileName, FilePath, FileHash, PolicyName, PolicyID
| order by Timestamp desc
AppControlCodeIntegrityPolicyAudited Events (Event ID 3076) — Summary
DeviceEvents
| where Timestamp > ago(14d)
| where ActionType == "AppControlCodeIntegrityPolicyAudited"
| summarize Count = count(), Devices = dcount(DeviceName)
by FileName, FolderPath, SHA256
| top 100 by Count desc
Gathering Enforced Events Data
When your base policy is in enforcement mode, blocked events are logged in Event Viewer with Event ID 3077. You can run the advanced hunting query below to view details of these events. Update the condition Timestamp > ago(7d)
in the query to adjust the number of days for which you want to collect information from the device. You can click on Export button to export the events to a CSV file.
- Timestamp
- DeviceName
- FileName
- FolderPath
- SHA256
- PolicyName
- PolicyID
- RuleName
- RuleID
- InitiatingProcessFileName
- InitiatingProcessAccountName
AppControlCodeIntegrityPolicyBlocked Events (Event ID 3077)
DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "AppControlCodeIntegrityPolicyBlocked" // 3077
| extend AF = todynamic(AdditionalFields)
| extend PolicyName = tostring(AF.PolicyName),
PolicyID = tostring(AF.PolicyID),
RuleName = tostring(AF.RuleName),
RuleId = tostring(AF.RuleId)
| project Timestamp, DeviceName, FileName, FolderPath, SHA256, PolicyName, PolicyID, RuleName, RuleId, InitiatingProcessFileName, InitiatingProcessAccountName
| order by Timestamp desc
Top blocked executables query (last 14 days data)
DeviceEvents
| where Timestamp > ago(14d)
| where ActionType == "AppControlCodeIntegrityPolicyBlocked"
| summarize BlockCount = count(), Devices = dcount(DeviceName)
by FileName, FolderPath, SHA256
| top 50 by BlockCount desc
Policy load status — Event ID 3099 data
DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "AppControlCodeIntegrityPolicyLoaded" // 3099
| extend AF = todynamic(AdditionalFields)
| extend PolicyName = tostring(AF.PolicyName),
PolicyID = tostring(AF.PolicyID)
| summarize arg_max(Timestamp, *) by DeviceId, PolicyID
| project Timestamp, DeviceName, PolicyName, PolicyID
| order by Timestamp desc
Monitor for repeated enforcement failures
DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "AppControlCodeIntegrityPolicyBlocked"
| summarize BlockCount = count() by DeviceName, UserName=InitiatingProcessAccountName
| where BlockCount > 20
| order by BlockCount desc
Conclusion
It is a best practice to start with a base policy in Audit mode and monitor the event logs to build an application inventory. Use Advanced Hunting or a Log Analytics workspace to simplify collecting logs from all devices, since manually gathering events from each endpoint is not practical at scale. Once you are confident that no additional business-critical applications are being flagged beyond those you have already documented, and you have already allowed all these apps via Supplemental rules, switch the App Control policy to Enforcement mode.