Data Loss Prevention in Microsoft Purview is one policy engine projected across many workloads. The skill is not clicking through the wizard — it is matching the right detection (sensitive info type, EDM, fingerprint, classifier) to the right location, then rolling from simulation to block without a help-desk storm. This guide builds that end to end for Endpoint and Exchange.
1. DLP architecture: locations, precedence, and rule priority
A single DLP policy can target multiple locations (workloads). The two that matter here are Devices (Endpoint DLP) and Exchange email, but the same policy object can also cover SharePoint, OneDrive, Teams, on-prem repositories via the scanner, Fabric/Power BI, and third-party cloud apps through Defender for Cloud Apps.
Two ordering concepts trip people up, and they are different:
- Policy precedence vs. rule priority. Within one policy, rules are evaluated by priority (0 is highest); across different policies, the most restrictive action wins per workload — block beats allow.
- One action surface per match. If two rules in the same policy match, Purview applies the more restrictive enforcement and the highest-priority matching rule’s notifications. Order rules from most specific/most restrictive (priority 0) down to broad catch-alls.
Design the policy as a funnel: priority 0 is your high-confidence, high-count “block + no override” rule; lower-priority rules catch lower-confidence matches with notify-only. One policy then expresses graduated enforcement instead of fighting across overlapping policies.
Everything below works in the Microsoft Purview portal (purview.microsoft.com -> Data Loss Prevention), but the durable, reviewable way to manage it is Security & Compliance PowerShell. Connect once:
# Requires the Exchange Online Management module (v3+)
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Import-Module ExchangeOnlineManagement
# Connects to the Security & Compliance endpoint (separate from Connect-ExchangeOnline)
Connect-IPPSSession -UserPrincipalName admin@kloudvin.com
Connect-IPPSSession is the Security & Compliance PowerShell connection — distinct from Connect-ExchangeOnline. All the DLP, sensitive-info-type, and EDM cmdlets live behind it.
2. Onboard devices for Endpoint DLP and set egress restrictions
Endpoint DLP only sees a device after it is onboarded, and onboarding is shared with Microsoft Defender for Endpoint — a Windows 10/11 or macOS device already reporting to Defender for Endpoint is effectively onboarded for Endpoint DLP too.
Onboard from Purview portal -> Settings -> Device onboarding, using the method that matches your estate: Defender for Endpoint (devices flow in automatically — just turn on device monitoring), Intune (push the onboarding profile), or local script / GPO / Configuration Manager for unmanaged fleets. Onboarded devices appear under Settings -> Device onboarding -> Devices with a Last seen timestamp — your single best health signal.
Then configure Endpoint DLP settings (Settings -> Endpoint DLP settings) — global controls that your rules reference rather than redefine:
- File path exclusions so you do not scan build artifacts or AV quarantine.
- Restricted apps and app groups — name the apps you never want touching sensitive files (personal cloud sync clients, unsanctioned browsers).
- Browser and domain restrictions (service domains) — list allowed or blocked upload destinations and the unallowed browsers that bypass DLP. This is what lets a rule say “block upload to any domain except our sanctioned tenants.”
- Network share coverage, VPN settings, and Always audit file activity for devices (recommended on — gives you Activity Explorer signal even before a policy matches).
Endpoint DLP egress channels are explicit: copy to USB/removable media, copy to network share, print, copy to clipboard, upload to a cloud/web service, paste to a browser, and access by a restricted/unallowed app. You enable each channel as a condition inside the rule, not globally. A rule that blocks “upload to cloud service” does nothing to a USB copy unless you add that channel too.
3. Build the detections: custom SITs, keyword dictionaries, and EDM
Out-of-the-box sensitive information types (SITs) cover the common regulated identifiers (credit card, national IDs, etc.). For anything proprietary you build your own.
Custom sensitive information type
A SIT is a regex primary element plus optional supporting evidence (keywords/dictionaries/checksum) within a proximity window, scored to a confidence level. Example: a KloudVin internal customer ID like KV-1234567.
# Define the matching logic as a rule package (XML) for the custom SIT.
# The pattern: KV- followed by 7 digits, requiring a nearby keyword for higher confidence.
$xml = Get-Content -Path "C:\purview\kv-customer-id-rulepack.xml" -Encoding Byte -ReadCount 0
New-DlpSensitiveInformationTypeRulePackage -FileData $xml
The XML rule package is the supported, portable format for custom SITs (the portal’s “Create sensitive info type” wizard generates the same structure under the hood). Inside it you set the regex, the patterns at 65 / 75 / 85 confidence (more supporting evidence -> higher confidence), and a character proximity for keywords. Keep one idea per pattern: a bare ID at 65, ID + keyword at 85.
Keyword dictionary
For large, frequently-changing term lists (project codenames, controlled vocabulary), a keyword dictionary scales past the inline keyword limit:
# Up to ~1 MB of terms; reusable across multiple SITs
$terms = Get-Content "C:\purview\project-codenames.txt"
New-DlpKeywordDictionary -Name "KV Project Codenames" `
-Description "Confidential project names" `
-FileData ([System.Text.Encoding]::UTF8.GetBytes($terms -join "`r`n"))
Exact Data Match (EDM)
Regex SITs match shapes; EDM matches your actual values against a hashed, uploaded copy of a sensitive table — so “any 9-digit number” becomes “a 9-digit number that is a real SSN in our HR export.” EDM is the right tool when false positives on pattern-only SITs are unacceptable.
The EDM flow is four moving parts, in order:
- Schema — define the table columns and which are searchable/primary.
- EDM sensitive info type — links to the schema; sets the primary element + supporting columns.
- Hash and upload — the EDM Upload Agent salts and hashes the table on-prem; only the hash leaves your network, plaintext never reaches the service.
- Reference in rules like any other SIT.
# 1. Create/load the schema (XML defining columns + searchable fields)
$schema = Get-Content -Path "C:\edm\edm-schema-hr.xml" -Encoding Byte -ReadCount 0
New-DlpEdmSchema -FileData $schema
# 3. Hash + upload with the EDM Upload Agent (run on a domain-joined data host)
# Authorize once per data store:
.\EdmUploadAgent.exe /AuthorizeTenant /TenantId <tenant-guid>
# Generate the salted hash from the source CSV described by the schema:
.\EdmUploadAgent.exe /CreateHash `
/DataStoreName HRRecords `
/DataFile C:\edm\hr_export.csv `
/HashLocation C:\edm\hashed `
/Schema C:\edm\edm-schema-hr.xml
# Upload only the hash (no plaintext leaves the host):
.\EdmUploadAgent.exe /UploadData `
/DataStoreName HRRecords `
/DataFile C:\edm\hashed\hr_export.EdmHash
EDM is the strongest control for “match our records, not a pattern,” but it carries an operational tax: the hash must be refreshed on a schedule (a script + scheduled task on the data host) or it goes stale as records change. Treat the upload agent like a backup job — automated, monitored, alerting on failure.
4. Author a multi-rule DLP policy (confidence + instance count)
Now assemble the policy. Create it disabled-by-default-into-test, then add graduated rules. Below: an Exchange + Devices policy with two rules — a strict high-volume block at priority 0 and a notify-only low-volume rule at priority 1.
# Policy spanning Exchange email + all onboarded devices
New-DlpCompliancePolicy -Name "KV-Confidential-Egress" `
-ExchangeLocation All `
-EndpointDlpLocation All `
-Mode TestWithNotifications
# Priority 0: HIGH confidence + bulk -> block, no override
New-DlpComplianceRule -Name "Block bulk customer IDs (high)" `
-Policy "KV-Confidential-Egress" `
-Priority 0 `
-ContentContainsSensitiveInformation @(
@{ Name="KV Customer ID"; mincount="10"; minconfidence="85" }
) `
-BlockAccess $true `
-BlockAccessScope All `
-NotifyUser SiteAdmin,LastModifier,Owner `
-GenerateAlert SiteAdmin
# Priority 1: any single match at lower confidence -> notify only
New-DlpComplianceRule -Name "Notify on single customer ID (medium)" `
-Policy "KV-Confidential-Egress" `
-Priority 1 `
-ContentContainsSensitiveInformation @(
@{ Name="KV Customer ID"; mincount="1"; maxcount="9"; minconfidence="75" }
) `
-NotifyUser Owner,LastModifier `
-NotifyPolicyTipCustomText "This file contains KloudVin customer identifiers. Handle per the data-handling policy."
Three parameters carry the design intent:
| Parameter | What it controls | Why it matters |
|---|---|---|
minconfidence |
Match confidence (65/75/85) | Higher confidence = fewer false positives; pair high confidence with block |
mincount / maxcount |
Instance count of the SIT in the item | One ID is a leak risk; 10+ is a bulk exfil; gate severity on volume |
Priority |
Rule evaluation order | Most restrictive/specific at 0; broad catch-all last |
The -Mode values are the rollout dial: TestWithoutNotifications (silent simulation), TestWithNotifications (simulation + policy tips/emails so you can validate UX), Enable (fully enforced), and Disable. You walk a policy up this ladder — never start at Enable.
Instance count is the most under-used lever in DLP. A rule that fires on a single credit card buries you in noise; the same rule with
mincount=10surfaces the spreadsheet someone is about to exfiltrate. Build severity tiers on count, not just confidence.
5. Run in simulation and read the results
Both TestWithoutNotifications and TestWithNotifications put the policy in simulation mode: rules evaluate against real traffic and produce match telemetry, but with no enforcement and no end-user impact in the silent variant. This is your blast-radius preview, and the single most important step.
Let it run for a representative window — at least several days, ideally a week or two to catch month-end. Then review Purview portal -> Data Loss Prevention -> Policies -> [policy] -> Policy simulation. Read it for:
- Total matched items and the trend — flat, or spiked by a reporting cycle?
- Top rules by matches — a rule matching 100x the others is almost always too broad (wrong SIT, confidence too low, or count threshold of 1).
- Sample matched items — open them. Is this a true positive? This is where you find that your
KV-\d{7}regex is also hitting purchase-order numbers. - Per-location breakdown — a rule clean on email may be noisy on endpoint clipboard activity.
Tune in simulation, redeploy, re-simulate. Only promote to Enable once the matched set is dominated by true positives at your chosen thresholds.
# Promote out of simulation into full enforcement once tuned
Set-DlpCompliancePolicy -Identity "KV-Confidential-Egress" -Mode Enable
6. User notifications, policy tips, overrides, and justifications
Enforcement that users do not understand generates tickets and shadow IT. Configure the human-facing layer deliberately.
- Policy tips surface in context — the Outlook/OWA mailbar, and on endpoint as a toast — telling the user why an action was blocked or flagged. Set custom text per rule (
-NotifyPolicyTipCustomText) so the message names your actual policy. - Email notifications to senders/owners/admins via
-NotifyUser(Owner,LastModifier,SiteAdmin, or explicit SMTP addresses). - User overrides let a user proceed with a business justification, turning a hard block into an auditable, soft block — invaluable during early enforcement.
# Convert the priority-1 rule to a soft block: allow override with justification
Set-DlpComplianceRule -Identity "Notify on single customer ID (medium)" `
-BlockAccess $true `
-AllowOverride $true `
-NotifyAllowOverride WithJustification,WithAcknowledgement
WithJustification forces the user to pick or type a reason; WithoutJustification allows a one-click bypass (rarely what you want); WithAcknowledgement makes them attest. Every override is logged, so a justified bypass still becomes audit evidence and an Activity Explorer event — you keep visibility while reducing friction during rollout.
Stage your overrides. Phase 1: notify-only (no block). Phase 2: block with override + justification. Phase 3: remove override on the high-confidence/high-count rule only. Most orgs can live permanently at Phase 2 for medium rules and Phase 3 for the bulk-exfil rule.
7. Tune false positives: exceptions, fingerprints, trainable classifiers
When simulation shows true-positive precision below your bar, you have four tuning levers beyond raising confidence and count:
-
Exceptions on the rule — invert a condition. Exclude internal recipient domains, an approved security group, a specific sensitivity label, or content already encrypted. The cleanest false-positive killer is often
ExceptIfRecipientDomainIson internal traffic.# Don't fire on purely internal email or on already-labeled-and-allowed content Set-DlpComplianceRule -Identity "Block bulk customer IDs (high)" ` -ExceptIfRecipientDomainIs "kloudvin.com" ` -ExceptIfContentPropertyContainsWords "ClassificationOverride:Approved" -
Document fingerprinting — turn a standard form (patent template, HR offer letter, contract boilerplate) into a SIT. Purview hashes the empty template’s structure; documents based on it match even when filled in. Ideal for “our standard form X left the building.”
$template = Get-Content "C:\purview\patent-template.docx" -Encoding Byte -ReadCount 0 $fp = New-DlpFingerprint -FileData $template -Description "Patent application template" New-DlpSensitiveInformationType -Name "KV Patent Form" ` -Fingerprints $fp -Description "Matches our patent template" -
Trainable classifiers — ML models that recognize a category of content by example (source code, financial statements, customer complaints) rather than a pattern. Use a prebuilt classifier, or train a custom one on 50+ positive samples and validate against a test set before wiring it in as a DLP condition. They shine where regex/EDM cannot express the concept.
-
Named entities / enhanced SITs for full personal names or physical addresses that have no clean regex.
Layer these instead of loosening confidence: a rule of EDM SSN AND trainable: financial document, scoped with an internal-domain exception, is dramatically more precise than any single pattern at confidence 65.
8. Operationalize: analytics, Activity Explorer, and the alert queue
A DLP policy is a sensor; the value is in the response loop.
- DLP analytics / overview (Purview portal -> Data Loss Prevention -> Overview / Analytics) gives trends, top policies, top SITs, and surfaces potentially overmatching rules and coverage gaps — your tuning backlog.
- Activity Explorer (Purview portal -> Activity explorer, or under Data Loss Prevention) is the per-event log: every match and every override with its justification, filterable by policy, user, workload, SIT, and action. This is your forensic and “who bypassed what” view. (Recall the Always audit file activity for devices setting from Step 2 — it is what populates endpoint events.)
- Alerts (Purview portal -> Data Loss Prevention -> Alerts) is the triage queue. Rules with
-GenerateAlertpost here; you can aggregate (e.g. alert only when a user trips the policy N times in an hour) to cut noise. - Integration: high-severity DLP alerts flow to Microsoft Defender XDR and can be exported to a SIEM (Sentinel) via the Office 365 Management Activity API or the Defender connector, so DLP becomes part of your existing IR runbook instead of a portal someone has to remember to check.
# Tune alert aggregation on the strict rule: only alert past a threshold/volume
Set-DlpComplianceRule -Identity "Block bulk customer IDs (high)" `
-GenerateAlert SiteAdmin `
-AlertProperties @{ AggregationType="SimpleCount"; Threshold=5; TimeWindow=60 }
Enterprise scenario
A financial-services client pushed KV-Confidential-Egress from TestWithNotifications to Enable on a Friday after a clean two-week simulation. Within an hour the service desk lit up: the high-confidence EDM rule on their client account table — EDM AccountNumber at minconfidence=85, mincount=1 — had stopped all legitimate statement runs. Statements went out from a batch service account through an Exchange connector, every PDF carrying real account numbers, so every one was a true positive that was also entirely authorized.
The gotcha: their simulation window predated the month-end batch, so the simulation telemetry never saw the traffic. Lowering confidence was the wrong instinct (it was already correct); the fix was a scoped exception keyed on the authorized sender, not the content.
# Exempt the authorized statement-batch sender from the strict EDM rule.
# Sender-based exception keeps EDM strict for everyone else.
Set-DlpComplianceRule -Identity "Block bulk account numbers (high)" `
-ExceptIfFrom "statements-batch@kloudvin.com" `
-ExceptIfSenderIPRanges "203.0.113.40/29"
Pinning both ExceptIfFrom and ExceptIfSenderIPRanges meant a spoofed From header alone could not slip the exception — the mail also had to originate from the batch host’s egress range. The deeper lesson, now a standing rule on that team: simulation must cover a full business cycle including month-end and quarter-end, and any automated egress (statements, invoices, exports) gets enumerated and exempted by identity before enforcement flips on — never discovered by the help desk after. They also wired a synthetic test email into the batch pipeline so a future rule change that re-blocks it pages them, not the customers.
Verify
Validate on a test endpoint (onboarded) and a test mailbox before you trust the policy.
- Device health: Settings -> Device onboarding -> Devices shows your test device with a recent Last seen. No recent timestamp = no endpoint enforcement, full stop.
- Policy is live:
Get-DlpCompliancePolicy -Identity "KV-Confidential-Egress" | fl Name,Mode,ExchangeLocation,EndpointDlpLocationshows the expectedMode. - Exchange match: send a test email with 10+ fake KV-IDs to an external address. Expect the policy tip in OWA/Outlook and, once enabled, a block + NDR; the sender/owner notification arrives per
-NotifyUser. - Endpoint match: on the test device, try to upload a file with sensitive content to a non-sanctioned domain and copy one to USB. Each enabled channel should block (or audit in simulation); a disabled channel should not.
- Override path: on a soft-block rule, confirm the user is forced to enter a justification, the action proceeds, and the event with that justification appears in Activity Explorer.
- Telemetry: confirm matches in Activity Explorer and an entry in the Alerts queue for the high rule, then confirm the alert reached Defender XDR / your SIEM.
Checklist
Pitfalls
Three failures dominate real deployments. First, skipping simulation and going straight to Enable — you will block legitimate business email on day one and spend the next week in damage control; the simulation ladder exists precisely to prevent this. Second, letting the EDM hash go stale — an unrefreshed upload silently stops matching new records, and EDM’s whole value (matching your data) quietly erodes with no error in the portal. Third, tuning by lowering confidence instead of adding exceptions, fingerprints, or count thresholds — every drop in confidence trades a few caught leaks for a flood of false positives that trains your users to ignore policy tips. Get the rollout discipline right and DLP stops being a noise generator and becomes a precise, auditable control that your IR team actually trusts.