Deploy DLP policies for Teams chat, channels, and Exchange email. Configure policy tips for real-time user coaching, handle DLP in shared channels and meetings, and build incident management workflows.
DLP policies for Microsoft Teams and Exchange Online protect sensitive data shared through chat messages, channel posts, email, and attachments. Integrated with Defender XDR, these policies provide real-time alerts for data exfiltration attempts through collaboration and communication channels.
An organisation discovers employees sharing customer PII in Teams channels and sending unencrypted financial reports via email to external recipients. The security team must deploy DLP policies that block sensitive content in Teams messages, prevent external email transmission of financial data, and provide real-time coaching to users about data handling requirements.
Teams and email are the primary collaboration channels in most organisations. They are also the most common channels for accidental data exposure. A single Teams message containing customer SSNs sent to the wrong channel can constitute a reportable data breach. DLP policies provide the safety net that prevents these costly mistakes.
Connect-IPPSSession) and Exchange Online module (Connect-ExchangeOnline)Teams DLP policies intercept messages containing sensitive data in one-to-one chats, group chats, and channel conversations. When a policy match is detected, the message is blocked and replaced with a policy tip visible to the sender. Start by creating a policy scoped exclusively to Teams locations.
Use PowerShell to create the same policy programmatically for repeatable deployments across tenants:
# Connect to Security & Compliance PowerShell
Connect-IPPSSession
# Create a DLP policy scoped to Teams
New-DlpCompliancePolicy -Name "Teams - Block PII Sharing" `
-TeamsLocation All `
-Mode TestWithNotifications `
-Comment "Blocks SSN, passport, and credit card data in Teams messages"
# Create the detection rule
New-DlpComplianceRule -Name "Teams PII Detection Rule" `
-Policy "Teams - Block PII Sharing" `
-ContentContainsSensitiveInformation @(
@{Name="U.S. Social Security Number (SSN)"; minCount="1"},
@{Name="EU Passport Number"; minCount="1"},
@{Name="Credit Card Number"; minCount="1"}
) `
-BlockAccess $true `
-BlockAccessScope All `
-NotifyUser Owner `
-NotifyPolicyTipCustomText "This message was blocked because it contains sensitive personal data. Remove the data and resend." `
-GenerateAlert SiteAdminTestWithNotifications mode first. This simulates enforcement and generates alerts without actually blocking messages, giving you time to review matches and tune sensitivity thresholds before going live.Exchange DLP policies inspect both email body and attachments (including Office documents and PDFs) for sensitive content. Best practice is to create tiered rules: audit low-volume matches, warn on moderate matches, and hard-block high-volume or high-severity matches. This reduces user friction while still catching high-risk exfiltration.
Deploy the tiered Exchange DLP policy via PowerShell:
# Create Exchange DLP policy
New-DlpCompliancePolicy -Name "Exchange - Financial Data Protection" `
-ExchangeLocation All `
-Mode Enable `
-Comment "Tiered enforcement for credit card and financial data in email"
# Rule 1: Hard block - 5+ credit card numbers to external recipients
New-DlpComplianceRule -Name "Exchange Block High Volume CC" `
-Policy "Exchange - Financial Data Protection" `
-ContentContainsSensitiveInformation @{Name="Credit Card Number"; minCount="5"} `
-ExceptIfRecipientDomainIs @("contoso.com") `
-BlockAccess $true `
-BlockAccessScope NotInOrganization `
-GenerateIncidentReport SiteAdmin `
-IncidentReportContent All `
-NotifyUser Owner
# Rule 2: Warn with override - 1-4 credit card numbers externally
New-DlpComplianceRule -Name "Exchange Warn Low Volume CC" `
-Policy "Exchange - Financial Data Protection" `
-ContentContainsSensitiveInformation @{Name="Credit Card Number"; minCount="1"; maxCount="4"} `
-ExceptIfRecipientDomainIs @("contoso.com") `
-NotifyUser Owner `
-NotifyPolicyTipCustomText "This email may contain credit card numbers. Verify before sending externally." `
-SetHeader "X-DLP-Matched" "CreditCard-LowVolume"
# Rule 3: Audit only - internal email with any sensitive data
New-DlpComplianceRule -Name "Exchange Audit Internal Sensitive" `
-Policy "Exchange - Financial Data Protection" `
-ContentContainsSensitiveInformation @{Name="Credit Card Number"; minCount="1"} `
-ReportSeverityLevel Low `
-GenerateIncidentReport SiteAdmin-ExceptIfRecipientDomainIs parameter to exclude your own organisation's domain from external-only rules. This prevents internal communications from being blocked while still catching external exfiltration attempts.Policy tips are inline notifications displayed to users in Outlook and Teams when their message or email matches a DLP rule. Effective policy tips transform DLP from a blocking tool into a coaching mechanism - they explain what was detected, why it matters, and what alternatives the user has. Users can override with a business justification when appropriate.
Configure custom policy tip text and user notification settings on your DLP rules:
# Update an existing rule with custom policy tip and override
Set-DlpComplianceRule -Identity "Exchange Warn Low Volume CC" `
-NotifyUser Owner `
-NotifyPolicyTipCustomText @"
This email contains data that appears to include credit card numbers.
If this is a legitimate business need:
- Click 'Override' and provide a justification
- Consider encrypting the email using the 'Encrypt' button
If this was unintentional:
- Remove the sensitive data before resending
- Contact the Data Protection team for guidance
"@ `
-NotifyOverride WithJustification `
-NotifyEmailCustomText "A DLP policy was triggered on an email you sent. Review the policy tip for details."
# Configure a Teams rule with user notification
Set-DlpComplianceRule -Identity "Teams PII Detection Rule" `
-NotifyUser Owner `
-NotifyPolicyTipCustomText "This message was blocked - it contains personal data (SSN, passport, or credit card). Remove the sensitive content and resend. Use a secure sharing method instead." `
-NotifyOverride WithJustificationTeams shared channels allow cross-organisation collaboration using Azure AD B2B direct connect. DLP policies that apply to "Teams chat and channel messages" automatically cover shared channels - but you should consider stricter rules for external-facing channels. Messages in shared channels with external participants carry higher risk because data leaves your tenant boundary.
In the Purview portal, verify that your DLP policies cover shared channels by navigating to DLP > Policies, selecting your Teams policy, and confirming Teams chat and channel messages is listed as a location. Shared channels are included automatically when TeamsLocation is set to All. For more granular control, use adaptive scopes to target specific departments or user groups that participate in external shared channels.
Built-in sensitive information types cover common patterns like credit cards and SSNs, but every organisation has unique data formats - internal project codes, customer account numbers, employee IDs, or proprietary identifiers. Custom SITs let you define regex-based patterns with optional keyword proximity checks and confidence levels, then use them in any DLP policy alongside built-in types.
Create a custom sensitive information type using PowerShell - in this example, an internal project code format like PROJ-2024-00001:
# Connect to Security & Compliance PowerShell
Connect-IPPSSession
# Define the regex pattern and keyword list
$pattern = @{
"Pattern" = "PROJ-\d{4}-\d{5}"
"Name" = "Contoso Project Code Pattern"
}
$keywords = @{
"Keywords" = @("project", "internal", "confidential", "proprietary")
"Name" = "Project Code Keywords"
}
# Create the custom sensitive information type
New-DlpSensitiveInformationType -Name "Contoso Project Code" `
-Description "Matches internal project codes in format PROJ-YYYY-NNNNN" `
-SensitiveInformationTypeRulePackage @{
"Rules" = @(
@{
"Name" = "Contoso Project Code Rule"
"MatchPatterns" = @($pattern)
"SupportingKeywords" = @($keywords)
"Confidence" = 85
"ProximityWindow" = 300
}
)
}
# Verify the custom SIT was created
Get-DlpSensitiveInformationType -Identity "Contoso Project Code" | Format-List Name, Description, Id
# Test against sample content
Test-DlpSensitiveInformationType -TextToMatch "Please review PROJ-2024-00142 - this is a confidential internal project." `
-SensitiveInformationType "Contoso Project Code"Test-DlpSensitiveInformationType cmdlet to validate your regex against sample data before deploying it in a policy. Set the confidence level appropriately - high confidence (85+) for precise patterns with supporting keywords, medium (75) for patterns alone. Use the proximity window to require keywords within N characters of the pattern match.Teams meetings generate multiple data surfaces that DLP must cover: the meeting chat (before, during, and after the meeting), files shared in the meeting chat, meeting recordings stored in OneDrive/SharePoint, and meeting transcripts. Your Teams DLP policy automatically covers the meeting chat because it is treated as a group chat. Files and recordings require separate SharePoint/OneDrive DLP policies.
Meeting recordings are stored in the organiser's OneDrive (for non-channel meetings) or in the SharePoint site (for channel meetings). Apply sensitivity labels to recordings automatically by configuring auto-labelling policies in Purview Information Protection. For transcripts, consider using a DLP policy with content inspection on .vtt and .docx transcript files in OneDrive.
DLP alerts surface in both the Purview compliance portal and the Defender XDR portal. Defender XDR provides richer investigation capabilities by correlating DLP alerts with email, identity, and endpoint signals. For Teams DLP, you can see the exact message content that was blocked. For Exchange DLP, you can review the email, attachments, and delivery status.
Use KQL in Advanced Hunting to query DLP-related email events and identify patterns:
// Find emails that triggered DLP rules in the last 7 days
EmailEvents
| where Timestamp > ago(7d)
| where DeliveryAction in ("Blocked", "Replaced")
| where isnotempty(DlpMatchInfo)
| extend DlpRules = parse_json(DlpMatchInfo)
| mv-expand DlpRule = DlpRules
| extend RuleName = tostring(DlpRule.RuleName),
PolicyName = tostring(DlpRule.PolicyName),
Actions = tostring(DlpRule.Actions),
SITMatched = tostring(DlpRule.SensitiveInformationTypeName)
| project Timestamp, SenderFromAddress, RecipientEmailAddress,
Subject, DeliveryAction, PolicyName, RuleName,
SITMatched, Actions
| sort by Timestamp desc
// Identify repeat offenders
EmailEvents
| where Timestamp > ago(30d)
| where isnotempty(DlpMatchInfo)
| summarize MatchCount = count(),
UniqueRecipients = dcount(RecipientEmailAddress),
Policies = make_set(tostring(parse_json(DlpMatchInfo)[0].PolicyName))
by SenderFromAddress
| where MatchCount > 5
| sort by MatchCount descExchange transport rules (mail flow rules) complement DLP policies by providing additional actions that DLP rules alone cannot perform - such as adding disclaimers, BCC'ing compliance mailboxes, applying encryption, or modifying headers. You can create transport rules that trigger when a DLP policy match is detected, adding a second layer of protection and auditability.
Create a transport rule that applies encryption and BCC's compliance when a DLP policy match is found:
# Connect to Exchange Online
Connect-ExchangeOnline
# Transport rule: Encrypt emails matched by DLP and BCC compliance
New-TransportRule -Name "DLP Match - Encrypt and BCC Compliance" `
-MessageContainsDataClassifications @(
@{Name="Credit Card Number"; minCount="1"},
@{Name="U.S. Social Security Number (SSN)"; minCount="1"}
) `
-SentToScope NotInOrganization `
-ApplyRightsProtectionTemplate "Encrypt" `
-BlindCopyTo "dlp-review@contoso.com" `
-SetHeaderName "X-DLP-Transport-Action" `
-SetHeaderValue "Encrypted-and-BCC" `
-Priority 0 `
-Comments "Encrypts and copies to compliance when DLP-sensitive content is sent externally"
# Transport rule: Add disclaimer to DLP-matched emails
New-TransportRule -Name "DLP Match - Add Disclaimer" `
-MessageContainsDataClassifications @(
@{Name="Credit Card Number"; minCount="1"}
) `
-ApplyHtmlDisclaimerLocation Prepend `
-ApplyHtmlDisclaimerText "<p style='color:red;font-weight:bold'>โ ๏ธ This email has been flagged by DLP. It may contain sensitive financial data. Handle accordingly.</p>" `
-ApplyHtmlDisclaimerFallbackAction Wrap-MessageContainsDataClassifications condition to match the same SITs used in your DLP policy.An effective DLP programme requires automated incident workflows so high-severity alerts are never missed. Use Power Automate or Logic Apps to monitor the DLP alert webhook, enrich the alert with user and device context, notify the response team, and create a tracking ticket. This reduces mean time to respond (MTTR) from hours to minutes.
Configure an alert-routing webhook for high-severity DLP events using PowerShell to send to a Logic App or Power Automate HTTP endpoint:
# PowerShell function to forward DLP alerts to a Logic App / Power Automate endpoint
$webhookUri = "https://prod-01.australiaeast.logic.azure.com:443/workflows/YOUR-WORKFLOW-ID/triggers/manual/paths/invoke"
function Send-DlpAlertToWorkflow {
param(
[string]$AlertId,
[string]$PolicyName,
[string]$UserPrincipalName,
[string]$Severity,
[string]$MatchedContent,
[string]$Workload
)
$body = @{
alertId = $AlertId
policyName = $PolicyName
user = $UserPrincipalName
severity = $Severity
matchedContent = $MatchedContent
workload = $Workload
timestamp = (Get-Date -Format "o")
action = "Pending Review"
} | ConvertTo-Json
Invoke-RestMethod -Uri $webhookUri -Method POST `
-ContentType "application/json" -Body $body
}
# Example: Route a high-severity DLP alert
Send-DlpAlertToWorkflow `
-AlertId "DLP-2024-00847" `
-PolicyName "Exchange - Financial Data Protection" `
-UserPrincipalName "j.smith@contoso.com" `
-Severity "High" `
-MatchedContent "5 credit card numbers detected in attachment" `
-Workload "Exchange"Compliance reporting demonstrates the value of your DLP programme and provides evidence for auditors and regulators. Use Activity Explorer in Purview for interactive exploration, and Advanced Hunting in Defender XDR for custom KQL-based dashboards. Key metrics include: total matches by workload, matches by sensitive information type, top offending users, override usage, and trend analysis showing declining violation rates over time.
Use KQL queries in Advanced Hunting to build DLP reporting dashboards:
// DLP matches by workload - last 30 days
EmailEvents
| where Timestamp > ago(30d)
| where isnotempty(DlpMatchInfo)
| extend Workload = "Exchange"
| union (
CloudAppEvents
| where Timestamp > ago(30d)
| where ActionType has "Dlp"
| extend Workload = "Teams"
)
| summarize MatchCount = count() by Workload
| render piechart
// Top 10 users by DLP violations - last 30 days
EmailEvents
| where Timestamp > ago(30d)
| where isnotempty(DlpMatchInfo)
| summarize ViolationCount = count(),
SITs = make_set(tostring(parse_json(DlpMatchInfo)[0].SensitiveInformationTypeName)),
LastViolation = max(Timestamp)
by SenderFromAddress
| top 10 by ViolationCount desc
// Weekly DLP trend - declining violations indicate user learning
EmailEvents
| where Timestamp > ago(90d)
| where isnotempty(DlpMatchInfo)
| summarize WeeklyCount = count() by Week = startofweek(Timestamp)
| sort by Week asc
| render timechart with (title="DLP Violation Trend - Email")| Resource | Description |
|---|---|
| DLP for Teams Overview | Learn about DLP for Teams chat and channel messages, including shared channels |
| DLP for Exchange Online | Configure DLP policies for email body, attachments, and transport rules |
| Create a DLP Policy | Complete guide to creating and deploying DLP policies across workloads |
| DLP Policy Tips Reference | Configure policy tips for Outlook, Teams, and other Microsoft 365 apps |
| Custom Sensitive Info Types | Create custom SITs with regex patterns, keyword lists, and confidence levels |
| DLP PowerShell Cmdlets | PowerShell reference for New-DlpCompliancePolicy, New-DlpComplianceRule, and related cmdlets |
| DLP Alerts in Defender XDR | Investigate DLP alerts in the unified Defender XDR portal |
| Advanced Hunting for DLP | KQL queries for hunting DLP events in EmailEvents and CloudAppEvents tables |