HOW-TO GUIDE | ENDPOINT SECURITY
Updated 10 min read

How to Build Your First Windows Defender Application Control (WDAC) Policy

Kernel
Enforcement level of WDAC: operates before code is loaded into memory, making bypass significantly harder than AppLocker's process-level enforcement
Audit mode
Required first step for WDAC deployment: runs the policy without blocking, logging what would be blocked for 1-2 weeks to build a baseline of legitimate code
3 types
WDAC rule types: publisher (code signing certificate), hash (file hash), and filepath (file location): publisher rules are recommended as they survive software updates
Microsoft recommended block list
Published list of known vulnerable drivers and LOLBins that WDAC should block: maintained by Microsoft and should be included in every policy

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

WDAC is the Windows application control feature that actually blocks code at the kernel level: before it can run, before it can inject into other processes, before it can establish C2 communications. Most malware, including LOLBin abuse and fileless attacks, can be blocked by a well-configured WDAC policy.

The challenge is deployment: a WDAC policy that blocks too aggressively breaks legitimate applications. The audit-mode-first workflow prevents this by capturing everything that legitimately runs in your environment before enforcing any blocks.

WDAC vs. AppLocker: Which to Use

Both WDAC and AppLocker are Microsoft application control technologies. Defenders frequently ask which to use:

FeatureWDACAppLocker
Enforcement levelKernel (before execution)User process (process launch)
Bypass difficultySignificantly harderMore easily bypassed
OS availabilityWindows 10/11, Server 2016+Windows 7+, Server 2008+
DeploymentIntune, Group Policy, MDMGroup Policy
Policy formatXML, deployed as binaryXML via Group Policy
Managed installer supportYesNo
Driver controlYes (kernel drivers)No
Script controlYes (PowerShell constrained language mode)Limited

Microsoft's recommendation: Use WDAC where possible; AppLocker is supplementary for systems where WDAC cannot be deployed. They can run simultaneously.

When to use WDAC: Modern Windows 10/11 or Server 2016+ environments where you can invest in proper policy management. WDAC provides significantly better security but requires more upfront investment.

When to use AppLocker: Legacy environments (pre-Windows 10), when you need a quick partial control while building toward WDAC, or for user-mode script control on systems that cannot fully enforce WDAC.

Step 1: Create a Base Policy in Audit Mode

Option 1: WDAC Wizard (Microsoft's GUI tool)

Download from: https://webapp-wdac-wizard.azurewebsites.net/

  • Provides a guided policy creation workflow
  • Generates signed or unsigned XML policies
  • Supports policy supplements and merging

Option 2: PowerShell: create a baseline policy from Microsoft's recommended templates:

# Requires: Windows 10/11 or Server 2016+, ConfigCI module (built-in)

# Start with Microsoft's default Windows mode template
# This allows Windows components, WHQL-signed drivers, and Windows Store apps
$PolicyPath = "C:\WDAC\BasePolicy.xml"

# Get the path to the default policy templates
$TemplatePath = "C:\Windows\schemas\CodeIntegrity\ExamplePolicies"
Get-ChildItem $TemplatePath  # Lists available templates

# Use the DefaultWindows template as a starting point
Copy-Item "$TemplatePath\DefaultWindows_Audit.xml" $PolicyPath

# Set the policy to Audit mode (0 = audit, 1 = enforce)
Set-RuleOption -FilePath $PolicyPath -Option 3  # Audit mode

# Enable script enforcement (blocks unsigned PowerShell scripts)
Set-RuleOption -FilePath $PolicyPath -Option 11  # Disabled:Script Enforcement (remove this option to enforce)

# Remove Audit Mode for enforcement later: but don't do this yet
# Set-RuleOption -FilePath $PolicyPath -Option 3 -Delete

# Set the policy ID and name
[xml]$policyXml = Get-Content $PolicyPath
$policyXml.SiPolicy.PolicyID = "{$(New-Guid)}"
$policyXml.SiPolicy.FriendlyName = "Corporate WDAC Policy v1"
$policyXml.Save($PolicyPath)

# Convert XML to binary format for deployment
ConvertFrom-CIPolicy -XmlFilePath $PolicyPath -BinaryFilePath "C:\WDAC\BasePolicy.p7b"

# Deploy to the local machine for testing
Copy-Item "C:\WDAC\BasePolicy.p7b" \
  "$env:windir\System32\CodeIntegrity\CIPolicies\Active\{policy-guid-here}.cip"

# Restart required for policy to take effect
# Restart-Computer (do this when ready)
Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Step 2: Capture Audit Events and Build Trust Rules

Run in audit mode for 1-2 weeks to capture all code that legitimately runs:

# Query Code Integrity audit events (Event ID 3076)
# These are files that WOULD be blocked in enforcement mode
Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' |
  Where-Object Id -eq 3076 |
  ForEach-Object {
    $xml = [xml]$_.ToXml()
    [PSCustomObject]@{
      TimeCreated = $_.TimeCreated
      FileName    = $xml.Event.EventData.Data | Where-Object Name -eq 'File Name' | Select-Object -ExpandProperty '#text'
      SHA256      = $xml.Event.EventData.Data | Where-Object Name -eq 'SHA256 Flat Hash' | Select-Object -ExpandProperty '#text'
      PolicyName  = $xml.Event.EventData.Data | Where-Object Name -eq 'Policy Name' | Select-Object -ExpandProperty '#text'
    }
  } | Export-Csv "C:\WDAC\audit-events.csv" -NoTypeInformation

# Review the blocked applications list
Import-Csv "C:\WDAC\audit-events.csv" | 
  Sort-Object FileName -Unique | 
  Select-Object FileName, SHA256 | 
  Format-Table -AutoSize

Create trust rules for legitimate software found in audit events:

# Option 1: Publisher rule (preferred: survives software updates)
# Extract signing certificate info from a file
$cert = (Get-AuthenticodeSignature -FilePath "C:\Program Files\SomeApp\app.exe").SignerCertificate
if ($cert) {
    # Create a publisher rule
    $rule = New-CIPolicyRule \
      -Level Publisher \
      -FilePath "C:\Program Files\SomeApp\app.exe"
    
    Add-CIPolicyRules -Policy $PolicyPath -Rules $rule
}

# Option 2: Generate rules from a reference machine
# (Best practice: run on a clean, fully configured machine)
New-CIPolicy \
  -Level Publisher \
  -Fallback Hash \
  -FilePath "C:\WDAC\ApplicationPolicy.xml" \
  -ScanPath "C:\Program Files" \
  -UserPEs  # Include user-mode executables

# Option 3: Generate rules from audit events directly
New-CIPolicy \
  -Level Publisher \
  -Fallback Hash \
  -FilePath "C:\WDAC\AuditDerivedPolicy.xml" \
  -Audit  # Scan audit event log to build policy from observed applications

# Merge application policy with base policy
Merge-CIPolicy \
  -PolicyPaths $PolicyPath, "C:\WDAC\ApplicationPolicy.xml" \
  -OutputFilePath "C:\WDAC\MergedPolicy.xml"

Step 3: Add the Microsoft Recommended Block Rules

Microsoft maintains a list of known vulnerable drivers and LOLBins that WDAC should block: attackers abuse these to bypass application control. Include these in every WDAC policy.

# Download the recommended block list from Microsoft
# https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/applications-that-can-bypass-wdac
# Save the XML as BlockList.xml

# Merge block rules into your policy
Merge-CIPolicy \
  -PolicyPaths "C:\WDAC\MergedPolicy.xml", "C:\WDAC\BlockList.xml" \
  -OutputFilePath "C:\WDAC\FinalPolicy.xml"

# The block list denies execution of:
# mshta.exe, wscript.exe, cscript.exe when used for policy bypass
# Known vulnerable signed drivers (LoLDrivers)
# Tools like PsExec, BGInfo, wmic used in specific bypass scenarios
# See: https://loldrivers.io/ for the full vulnerable driver list

Step 4: Switch to enforcement mode:

# Remove the Audit Mode option to enforce the policy
Set-RuleOption -FilePath "C:\WDAC\FinalPolicy.xml" -Option 3 -Delete

# Convert to binary
$policyGuid = ([xml](Get-Content "C:\WDAC\FinalPolicy.xml")).SiPolicy.PolicyID.Trim('{}')
ConvertFrom-CIPolicy \
  -XmlFilePath "C:\WDAC\FinalPolicy.xml" \
  -BinaryFilePath "C:\WDAC\{$policyGuid}.cip"

# Deploy via Intune (preferred for enterprise):
# Intune > Devices > Configuration Profiles > Create >
# Endpoint protection > Windows Defender Application Control
# Upload the .cip file as Custom OMA-URI:
# OMA-URI: ./Vendor/MSFT/ApplicationControl/Policies/{PolicyGUID}/Policy
# Data type: Base64
# Value: (base64-encode the .cip file)

# Or deploy via Group Policy:
Copy-Item "C:\WDAC\{$policyGuid}.cip" \
  "\\fileserver\Netlogon\WDAC\{$policyGuid}.cip"
# GPO: Computer Configuration > Windows Settings > Security Settings >
# Application Control Policies > Windows Defender Application Control

The bottom line

WDAC provides kernel-level code integrity enforcement that blocks unauthorized execution before it happens: more effective than AppLocker and significantly harder to bypass. Build a base policy from Microsoft's DefaultWindows template, deploy in audit mode for 1-2 weeks, review Event ID 3076 to identify legitimate software that would be blocked, create publisher rules for trusted applications, merge in Microsoft's recommended block list, then switch to enforcement mode. Deploy via Intune for enterprise scale or Group Policy for domain-joined environments.

Frequently asked questions

What is Windows Defender Application Control (WDAC)?

WDAC is a Windows kernel-level code integrity feature that prevents unauthorized code from executing: blocking unsigned binaries, untrusted drivers, and explicitly denied applications before they can run. Unlike AppLocker (which operates at process launch), WDAC enforcement happens in the kernel before code is loaded into memory, making it significantly harder to bypass. Policies are defined in XML, specify trust via publisher certificates or file hashes, and are deployed via Intune or Group Policy.

How do you deploy a WDAC policy without breaking applications?

Deploy in audit mode first (Option 3 in the policy XML). Audit mode logs what would be blocked (Event ID 3076 in Microsoft-Windows-CodeIntegrity/Operational) without actually blocking anything. Run for 1-2 weeks to capture all legitimate software. Review the audit events, create publisher or hash rules for each legitimate application, merge into the base policy, then remove the audit option to enforce. Never skip audit mode in production environments.

What is the difference between WDAC and AppLocker?

Both are Windows application control technologies but differ in architecture and enforcement level. AppLocker operates in user mode and enforces rules based on executable path, publisher, or file hash. It can be bypassed by kernel drivers and does not protect the boot process. WDAC (Windows Defender Application Control) enforces code integrity at the kernel level via the hypervisor (when VBS is enabled): it cannot be bypassed by user-mode code or standard admin privileges. WDAC is the Microsoft-recommended replacement for AppLocker in Windows 10/11 and Server 2016+. AppLocker is easier to deploy and manage; WDAC provides stronger security guarantees. Microsoft recommends using WDAC first, then AppLocker for user-mode supplemental rules if needed.

What is the WDAC Wizard and how does it simplify policy creation?

The WDAC Policy Wizard is a free Microsoft GUI tool that simplifies creating WDAC policies without hand-editing XML. It guides you through: selecting a base policy template (allow Microsoft mode, Windows works-only, or default Windows mode), adding publisher rules, adding path rules, and running a system scan to capture all currently running software as allowed rules. Download from Microsoft's GitHub. For deployment at scale, use the Microsoft Endpoint Configuration Manager (MECM/SCCM) WDAC integration or Microsoft Intune's Endpoint Security > Application Control policy to push WDAC policies to managed devices without Group Policy.

How do I write a WDAC rule to allow a specific application?

WDAC rules have three types: Publisher rules (most preferred — allow all files signed by a specific publisher, optionally scoped to a product name or version range), Hash rules (allow a specific file by its SHA256 hash — breaks when the file is updated), and Path rules (allow all files in a specific directory — weakest, can be exploited if the path is writable). For trusted commercial software (Adobe, Google, Microsoft), use Publisher rules: they automatically cover updates without rule changes. Use the Get-AppLockerFileInformation or New-CIPolicy PowerShell cmdlets to generate rules from existing files. Hash rules are appropriate for in-house applications that do not have Authenticode signatures.

How do I handle a software deployment that breaks after WDAC enforcement is turned on?

When a deployment fails after WDAC enforcement activates, the first step is checking Event ID 3077 in the Microsoft-Windows-CodeIntegrity/Operational log on the affected machine -- this records each blocked execution with the file name, hash, and policy name that blocked it. For a rapid unblock without disabling enforcement, add a hash rule for the specific blocked binary: run 'Get-FileHash <path> -Algorithm SHA256' and create a supplemental policy with a hash-based allow rule using New-CIPolicyRule -Level Hash -FilePath <path>, then merge it with your base policy and redeploy. For recurring issues with a vendor application, contact the vendor to obtain Authenticode-signed binaries -- most enterprise software vendors sign their installers; if they do not, escalate it as a security concern. For in-house tools, implement a code-signing workflow using your internal PKI and add the signing certificate as a publisher rule. Avoid the temptation to add path-based allow rules for writable directories such as temp folders -- attackers routinely exploit path rules by dropping malicious binaries into allowed paths.

Sources & references

  1. Microsoft: WDAC Design Guide
  2. Microsoft: WDAC Wizard
  3. NSA: WDAC Recommended Block Rules

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.