Purview sensitivity labels in bulk: Excel columns and nested labels

Sensitivity labels in Microsoft Purview can be created one by one in the UI, or in bulk via Excel/CSV and Security & Compliance PowerShell (New-Label). This is not the same as retention labels / file plan — those have a different CSV. Do not mix them.

Order for nested labels

A sublabel points at its immediate parent. That parent must already exist. So create the top first (empty Parent), then the next layer, then the deepest. The last (deepest) label cannot go first: New-Label fails with parent not found.

Example: Confidential → Confidential / HR → Confidential / HR / Payroll. Row 1: Confidential (Parent empty). Row 2: HR (Parent = Confidential). Row 3: Payroll (Parent = HR). If Excel is deepest-first, sort before import.

Delete or unpublish is the reverse: deepest child first, then the parent. A parent that still has sublabels will not delete.

Excel columns

First row = headers, these names exactly. Optional cells may be empty. Name is internal and painful to rename later; DisplayName is what users see.

Column Required Meaning
Name yes Internal id (no spaces if you can avoid them).
DisplayName yes Name in Office / SharePoint / Outlook.
Tooltip yes Hover text in the sensitivity bar.
Comment no Admin description, not shown to users.
Parent no Name or DisplayName of the immediate parent. Empty = top-level.
Priority no Order in the list. Unique integers; keep a gap (0, 10, 20) so you can insert later.
Color no Hex, e.g. #C23B22.
HeaderEnabled / HeaderText no Content marking header. Same pattern for Footer* and Watermark*.
EncryptionEnabled no TRUE/FALSE. Rights definitions belong in a second pass (Set-Label), not in the first create.
SiteAndGroupProtectionEnabled no Container label for SharePoint / Teams. Do not mix file encryption and container settings on the same nested child unless you mean it.

Sample CSV

CSV
Name,DisplayName,Tooltip,Comment,Parent,Priority,Color,HeaderEnabled,HeaderText,EncryptionEnabled
Confidential,Confidential,Company confidential,Root label,,0,#C23B22,TRUE,CONFIDENTIAL,TRUE
Confidential-HR,HR,HR only,Child of Confidential,Confidential,1,#C23B22,TRUE,HR CONFIDENTIAL,TRUE
Confidential-HR-Payroll,Payroll,Payroll only,Child of HR,Confidential-HR,2,#8B1E1E,TRUE,PAYROLL,TRUE
Internal,Internal,Internal use,Root label,,3,#2E75B6,FALSE,,FALSE

PowerShell

Compliance PowerShell, not Exchange Online. Role: Compliance Administrator or higher. App-only is possible, but the cmdlets live in the IPS session.

PowerShell
Connect-IPPSSession
# Security & Compliance PowerShell (not Exchange, not Graph)

$rows = Import-Csv .\labels.csv
# Parent must already exist: empty Parent first, then one level down, then the next.
$ordered = $rows | Sort-Object @{ Expression = {
    if (-not $_.Parent) { 0 } else { 1 + ($_.Parent -split '[\\/]').Count }
} }

foreach ($r in $ordered) {
    $p = @{
        Name        = $r.Name
        DisplayName = $r.DisplayName
        Tooltip     = $r.Tooltip
        Comment     = $r.Comment
    }
    if ($r.Parent) {
        $parent = Get-Label | Where-Object { $_.Name -eq $r.Parent -or $_.DisplayName -eq $r.Parent }
        if (-not $parent) { throw "Parent not found: $($r.Parent). Create the parent row first." }
        $p.ParentId = $parent.Guid
    }
    if ($r.Priority) { $p.Priority = [int]$r.Priority }
    New-Label @p
    if ($r.HeaderEnabled -eq 'TRUE') {
        Set-Label -Identity $r.Name -ApplyContentMarkingHeaderEnabled $true -ApplyContentMarkingHeaderText $r.HeaderText
    }
}

Publish

A label that is not in a label policy is invisible. Publishing the parent does not auto-publish the children — include every layer in the policy, or use separate policies per layer. Auto-labeling policies point at existing labels; those labels must already be published.

Frequent errors

Parent label not found — the parent row is not imported yet, or Parent does not match Name/DisplayName (spaces, casing). Cannot delete label that has sublabels — remove the deepest first. The term New-Label is not recognized — you are in Exchange or Graph, not in Connect-IPPSSession.

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 →