Sensitivity labels are architecture, not a 40-row spreadsheet called “Confidential | HR | Pay band | South site | Draft-v12”. If people need a decision tree to click, you did not build a classification system. Microsoft: at most five parents, five children. Four parents cover almost every tenant: Public, General, Confidential, Highly Confidential. Sublabels = who you collaborate with (Organisatie / Keten), not the data type. Purview detects PII with SITs; that does not go in the label name. Bulk CSV for New-Label: sensitivity labels in bulk. DLP on this schema: phased DLP.

Two systems, not one

  • File/email labels — encryption, watermark, header, auto-label, DLP condition. Travel with the file (metadata in the file header, not in a SharePoint column that strips on download).
  • Container labels (Groups and sites) — team privacy, guests, external sharing, unmanaged devices. Files inside that site do not inherit this. Containers first (oversharing), then files (content). EnableMIPLabels in Entra, then publish.
  • Retention labels are a third system (File Plan). Sensitivity says “who may see this”; retention says “how long we keep it”. Do not mix them in one name.

What you do not put in the name

No “PII label”, “FOI label”, “client-file label”. A published decision can be Public; a draft opinion from the same lawyer is Highly Confidential. Users must not decide a legal threshold — Purview detects national-id/IBAN/card with SITs in the background. Labels stay readable: Public, General, Confidential / Organisatie, Confidential / Keten, Highly Confidential / Juridisch. The moment one document contains two data types, a data-type model collapses.

Parent first (here, yes)

Nested sensitivity: parent first, child second (New-Label -ParentId). Opposite of record daisy-chain. Users see the parent; the child carries encryption. Set DefaultSubLabelId on the parent if “Confidential” should really mean “Organisatie”. Microsoft is moving to label groups as the successor of parent/child — until that migration: parent/child as here. Test in a pilot group, not on the whole tenant at once.

PowerShell
Connect-IPPSSession -UserPrincipalName [email protected]
# PARENT FIRST (opposite of record daisy-chain).
$conf = New-Label -Name "Confidential" `
  -DisplayName "Confidential" `
  -Tooltip "Restricted. Pick Organisatie or Keten." `
  -Comment "Parent. Protection lives on the children."
New-Label -Name "Confidential/Organisatie" `
  -DisplayName "Organisatie" `
  -ParentId $conf.Guid `
  -Tooltip "Organisation only. No encryption in phase 2."
New-Label -Name "Confidential/Keten" `
  -DisplayName "Keten" `
  -ParentId $conf.Guid `
  -Tooltip "Named partners. Encryption."
# Users who pick the parent should land on Organisatie, not on a hollow parent.
Set-Label -Identity $conf.Guid -AdvancedSettings @{
    DefaultSubLabelId = (Get-Label | Where-Object { $_.DisplayName -eq "Organisatie" }).Guid
}

Turn container labels on

Without EnableMIPLabels = True on the Entra directory setting, Groups-and-sites options do not appear, or they do nothing. At least one Entra ID P1. Then: privacy (Public / Private / Let users decide), guest access, external sharing, unmanaged devices (often Conditional Access). Retro-label existing teams with PnP — otherwise the old sharing sprawl stays.

PowerShell
# Container labels need EnableMIPLabels on the Entra directory setting.
# Entra ID P1 (at least one licence). Graph beta.
Connect-MgGraph -Scopes "Directory.ReadWrite.All"
$setting = Get-MgBetaDirectorySetting | Where-Object {
    $_.Values.Name -eq "EnableMIPLabels"
}
if (-not $setting) { throw "Unified Group directory setting not found. Create it from the Group.Unified template first." }
Update-MgBetaDirectorySetting -DirectorySettingId $setting.Id -BodyParameter @{
    Values = @(@{ Name = "EnableMIPLabels"; Value = "True" })
}
(Get-MgBetaDirectorySetting -DirectorySettingId $setting.Id).Values
PowerShell
# After the GroupsAndSites labels exist:
Set-Label -Identity "Team afgeschermd" -AdvancedSettings @{
    DefaultSharingScope        = "SpecificPeople"
    DefaultShareLinkPermission = "View"
    MembersCanShare            = "MemberShareNone"
}
# Files inside that site do NOT inherit this label. Publish a file label separately.

Six phases

  1. Phase 0 — whiteboard. Policy on one page: who may share what. Four parents, no data types in names. CISO + legal + IM sign off. Fill the CSV below; do not build in Purview yet. If you cannot point at the policy line a label represents, that label does not belong.
  2. Phase 1 — containers. Team intern / Team keten / Team afgeschermd on Teams and sites. No encryption. Retro-label existing teams. This stops guest sprawl from the sharing workflow — a bigger leak than one unlabelled Word file.
  3. Phase 2 — files, recommended. Publish Public/General/Confidential. Default = General. No mandatory, no encryption. Header/footer is fine. Measure: what % picks General vs nothing. Without help almost everyone lands on default or dismisses the prompt.
  4. Phase 3 — auto-label simulation. SITs (national id, IBAN, credit card) in simulation. Manual labelling covers a few percent; auto-label is how you reach real coverage without asking the whole organisation to reclassify history. Turn auto-label on only when simulation shows no surprises. Turn it off if access breaks for a reason that is not an education gap.
  5. Phase 4 — encryption on a small set. Highly Confidential / Juridisch, named users, watermark. Not on all Confidential Organisatie — that breaks sharing. Encryption exposes gaps (no revoke, no named partners) and then the label gets blamed. Pilot one department.
  6. Phase 5 — mandatory on files, recommended on mail. Never mandate on email/meetings — that is the primary channel, that is how you lose the organisation. On files, mandatory is fine, with recommended/auto. Then DLP on this schema — phased DLP.

Planning CSV

One row per label (parent or child). Never mix scope Files+Email and GroupsAndSites on the same row — those are two publications. DLPHook is the later DLP phase, not a Purview column. Phase is your rollout, not a Microsoft field. Fill this in the workshop; only build once the CSV is signed.

CSV
Phase,Parent,SubLabel,Scope,Default,Encryption,Watermark,ContainerPrivacy,GuestAccess,ExternalSharing,DLPHook,AutoLabel,Pilot,Notes
0,Public,,Files+Email,No,No,No,n/a,n/a,n/a,None,No,CISO workshop,Approved for the open web. No restrictions.
0,General,,Files+Email,Yes,No,No,n/a,n/a,n/a,None,No,Whole org,Day-to-day work. Default. Users should almost always land here.
0,Confidential,Organisatie,Files+Email,No,No,No,n/a,n/a,n/a,Audit,Simulation later,IM+Legal,Inside the organisation. No encryption yet (phase 3).
0,Confidential,Keten,Files+Email,No,Yes,No,n/a,n/a,n/a,Tip,No,Legal,Named supply-chain partners. Encryption + named users.
0,Highly Confidential,Juridisch,Files+Email,No,Yes,Yes,n/a,n/a,n/a,Block,No,Legal office,Small population. Encryption from day 1 of this phase.
1,Team intern,,GroupsAndSites,No,n/a,n/a,Private,Off,ExistingUsers,None,No,IT,Container. Does NOT encrypt files inside.
1,Team keten,,GroupsAndSites,No,n/a,n/a,Private,On,NewAndExistingGuests,None,No,IT,Guest access on. Still no file encryption.
1,Team afgeschermd,,GroupsAndSites,No,n/a,n/a,Private,Off,Disabled,None,No,IT,No guests, no sharing. Pair with Highly Confidential files.

AI / Copilot

Highly Confidential must be able to DLP-block Copilot from processing the file. A private search index (Azure AI Search, RAG) reads text; encryption on the source file is not decryption in that index. The label GUID must sit in the index before ingest, or query-time Purview cannot enforce anything. Build labels as if an index will honour them — even if you do not have that index yet. Personal Copilot accounts on work documents (multiple identities in one client) are possible by default; that is an explicit block, not a default.

Sources

Frequent errors and how to fix them

These are the messages people type into search when the module will not start. The exact wording is here so this page can be found.

ComplianceTagForNextStage / replacement label not found
Daisy-chain: create the last label first, then the one that points at it. Nested sensitivity is the opposite (parent first).
A parameter cannot be found that matches parameter name 'TargetLabelId'
Get-ReviewItems wants ImmutableId, not the name. Get-ComplianceTag | Select ImmutableId. Mailbox Import Export role is often missing.
Flow not listed on the retention label
Flow is not in the Default environment, or the premium connector has no licence. Attach with Set-ComplianceTag -FlowId.
ReviewerEmail / invalid recipient
Disposition review needs a mail-enabled security group, not a Microsoft 365 Group and not a guest. Max 200 reviewers per tenant.
EnableMIPLabels is False / Groups and sites options missing
Container labels: set EnableMIPLabels to True via Microsoft Graph (directory setting) before you publish Groups and sites.
ParentId / label not found (New-Label nested)
Sensitivity: parent first, child second. Retention daisy-chain is the opposite (last first).

Questions about this, or need help setting it up? We are happy to think along.

Message on LinkedIn →