Most legal-hold write-ups stop at "run this command." Real requests don't cooperate: the custodian left the company, the mailbox is soft-deleted, the client says "litigation hold" but means a Purview case hold, or you're asked to release one matter and discover the mailbox is held by three. Get any of these wrong and the failure mode isn't a stack trace — it's permanent, unrecoverable data loss (spoliation), with legal consequences for the client and the provider.
This is the runbook I wish I'd had. Below is a scenario switcher: pick what you're actually facing and jump straight to its investigation, commands, verification, and cautions. First, three things that underpin all of it.
The terminology trap
When a client says "litigation hold," they usually mean "preserve this data" — not the specific Exchange mailbox Litigation Hold flag. Nine times out of ten the right mechanism is a Purview eDiscovery case hold, which is scoped to a named matter and auditable. Clarifying which one they need — and defaulting to the case hold — is half the job. The two are different mechanisms with different release procedures.
00Golden rules
Non-negotiable. Everything below assumes these.
Preserve first, act surgically, never release blind
Never remove a hold without written authorization from the owner of that specific matter — approval for Matter A never authorizes touching Matter B, even on the same mailboxes. Never delete a policy to release a subset of custodians (deleting a policy releases everyone). When the data is ambiguous, stop and escalate — inactive mailboxes and orphaned policies fail safe, so keep preserving. Document every read-only finding before any write.
01The four mailbox states
State determines what's possible — and where the danger lives.
Holds also stack — a mailbox can carry several at once, and LitigationHoldEnabled = False does not mean "not held," because a Purview case hold preserves independently of that flag. Hold GUIDs in InPlaceHolds carry a prefix: UniH… is a Purview/eDiscovery case hold, mbx… a legacy in-place hold, and a bare 32-hex value is usually org-wide retention.
02Pick your scenario
Twelve cases, grouped by what you're being asked to do. Click one.
Place a hold
Release a hold
Content search
Place a hold on an active mailbox routine
Preserve a current employee's data. Two mechanisms; prefer the case hold for anything that may become eDiscovery.
Option A — mailbox-level litigation hold (whole mailbox, simplest)Set-Mailbox -Identity "departed.user@contoso.com" ` -LitigationHoldEnabled $true ` -LitigationHoldDuration Unlimited ` -LitigationHoldOwner "Legal - Matter 12345"Option B — Purview case hold (preferred; tracked & scoped)
# 1. create the eDiscovery case (skip if it exists) New-ComplianceCase -Name "Matter 12345 - Contoso v. Example" ` -Description "Litigation hold for Matter 12345" # 2. create the hold policy, scope the custodian(s) New-CaseHoldPolicy -Name "Matter12345-ExchangeHold" ` -Case "Matter 12345 - Contoso v. Example" ` -ExchangeLocation "departed.user@contoso.com" # 3. create the rule. An empty rule (no query) holds EVERYTHING. New-CaseHoldRule -Name "Matter12345-Rule" -Policy "Matter12345-ExchangeHold"Verify
Get-Mailbox "departed.user@contoso.com" |
Select-Object LitigationHoldEnabled,
@{N='InPlaceHolds';E={$_.InPlaceHolds -join '; '}}
Place a hold on an inactive mailbox care
Preserve a departed employee whose mailbox is already inactive. Add it by DistinguishedName — the most reliable identifier for inactive mailboxes.
DiagnosisGet-Mailbox -InactiveMailboxOnly -Identity "departed.user@contoso.com" |
Select-Object DisplayName, IsInactiveMailbox, DistinguishedName, WhenSoftDeleted,
@{N='InPlaceHolds';E={$_.InPlaceHolds -join '; '}}
Action — add by DistinguishedName
$dn = (Get-Mailbox -InactiveMailboxOnly ` -Identity "departed.user@contoso.com").DistinguishedName Set-CaseHoldPolicy -Identity "Matter12345-ExchangeHold" -AddExchangeLocation $dn
Asked to hold a mailbox that is gone escalate
Nothing left to preserve. All three state checks return nothing.
Diagnosis — all three return nothing → it's goneGet-Mailbox "departed.user@contoso.com" -ErrorAction SilentlyContinue Get-Mailbox -InactiveMailboxOnly -Identity "departed.user@contoso.com" -ErrorAction SilentlyContinue Get-Mailbox -SoftDeletedMailbox -Identity "departed.user@contoso.com" -ErrorAction SilentlyContinue
Release a mailbox-level litigation hold care
A single-mechanism release — only after confirming no other matter needs this mailbox.
DiagnosisGet-Mailbox "departed.user@contoso.com" |
Select-Object LitigationHoldEnabled, ComplianceTagHoldApplied,
@{N='InPlaceHolds';E={$_.InPlaceHolds -join '; '}}
Action
Set-Mailbox -Identity "departed.user@contoso.com" -LitigationHoldEnabled $false
Release one custodian from a healthy case hold correct way
The surgical release — drop one or two custodians and preserve everyone else. Safe because the parent case still exists.
Diagnosis — confirm the parent case still exists$policy = Get-CaseHoldPolicy -Identity "<policy-guid>"
$policy | Format-List Name, CaseId, Enabled, Mode
# the parent case must resolve — if this returns the case, you're clear:
Get-ComplianceCase -Identity $policy.CaseId
Action — remove ONLY the custodian(s)
Set-CaseHoldPolicy -Identity "<policy-guid>" `
-RemoveExchangeLocation @("departed.user@contoso.com","second.user@contoso.com")
Mailbox held by a retention policy care
A governance hold, not a matter hold. Detected via ComplianceTagHoldApplied.
DiagnosisGet-Mailbox "departed.user@contoso.com" | Select-Object ComplianceTagHoldApplied
Get-RetentionCompliancePolicy | Format-Table Name, Enabled, Mode -AutoSize
# which mailboxes a given policy scopes:
Get-RetentionCompliancePolicy -Identity "<retention-policy-name>" -DistributionDetail |
Select-Object -ExpandProperty ExchangeLocation
Mailbox on holds from multiple matters high-risk
The most common real-world trap. List every hold GUID and resolve each to its matter before touching anything.
Diagnosis — resolve each GUID to its policy + case$holds = (Get-Mailbox "departed.user@contoso.com").InPlaceHolds
foreach ($h in $holds) {
$guid = $h -replace '^UniH','' # strip the UniH prefix
Get-CaseHoldPolicy -Identity $guid -ErrorAction SilentlyContinue |
Select-Object Name, CaseId, @{N='GUID';E={$_.Guid}}
}
Release where this is the last hold on an inactive mailbox max caution
Irreversible. Removing the only hold on an inactive mailbox authorizes its destruction.
Diagnosis — confirm this hold is the ONLY thing preserving itGet-Mailbox -InactiveMailboxOnly -Identity "departed.user@contoso.com" |
Select-Object IsInactiveMailbox, LitigationHoldEnabled, ComplianceTagHoldApplied,
RetentionHoldEnabled, DelayHoldApplied,
@{N='InPlaceHolds';E={$_.InPlaceHolds -join '; '}}
# one hold in InPlaceHolds + everything else False = this hold is the ONLY thing preserving it
Orphaned case hold — parent case deleted escalate
The policy is still Enabled/Enforce, but its parent case was deleted. Get- reads it; per-custodian Set- fails with "policy wasn't found." See the full worked example below.
Diagnosis — confirm the parent case is gone$policy = Get-CaseHoldPolicy -Identity "<policy-guid>" -DistributionDetail
$policy | Format-List Name, Guid, Enabled, Mode, CaseId, DistributionStatus
# nothing back = the case is deleted = ORPHANED
Get-ComplianceCase -Identity $policy.CaseId -ErrorAction SilentlyContinue
Content search on an active mailbox routine
Search reads — it does not preserve. If preservation is also needed, apply a hold first.
Action# 1. create the search with a KQL content query New-ComplianceSearch -Name "Matter12345-Search" ` -ExchangeLocation "departed.user@contoso.com" ` -ContentMatchQuery 'subject:"contract" AND received>=01/01/2025' # 2. run it Start-ComplianceSearch -Identity "Matter12345-Search" # 3. check results Get-ComplianceSearch -Identity "Matter12345-Search" | Select-Object Name, Status, Items, Size
Content search on an inactive mailbox care
Searchable while retained. Search before releasing — never the reverse.
Action — resolve the DistinguishedName first$im = Get-Mailbox -InactiveMailboxOnly -Identity "departed.user@contoso.com" New-ComplianceSearch -Name "Matter12345-InactiveSearch" ` -ExchangeLocation $im.DistinguishedName ` -AllowNotFoundExchangeLocationsEnabled $true Start-ComplianceSearch -Identity "Matter12345-InactiveSearch"
"Apply a hold AND run a content search" care
Preserve, then collect — the ordering matters.
Correct order1. Confirm the mailbox still exists (active or inactive). 2. Apply / confirm the hold so nothing is lost during collection (Scenario 01 / 02). 3. THEN run the content search (Scenario 10 / 11). 4. Export / collect via the eDiscovery case as authorized.
03Worked example — the orphaned hold
A real investigation, anonymized. The star scenario, end to end.
A paralegal (Legal, "Matter A") requests release of 46 mailboxes from the Matter A hold. She adds one line that becomes the whole story: "if any of these are on hold for another matter, tell me before releasing." Honor that instruction and it changes everything.
Step 1 — verify holds on every mailbox. 41 come back clean; 5 are STILL HELD by a GUID that doesn't belong to Matter A. That's the requester's "another matter" — exactly what she asked to be warned about.
Step 2 — resolve the mystery GUID. It's a live, enforced hold ("Matter B") scoping 72 custodians firm-wide; the 5 mailboxes are just members of it.
Step 3 — check the parent case. The CaseId no longer resolves — the case was deleted from Purview while the hold kept enforcing. Orphaned.
Step 4 — the surgical removal is blocked. Set-CaseHoldPolicy -RemoveExchangeLocation fails with "policy wasn't found," because the write path needs the missing case. The only command that would execute is full deletion of the policy.
Step 5 — why force-delete is not the answer. Of the 72 custodians, 14 are soft-deleted inactive mailboxes whose only hold is this orphaned policy — some preserved for years. Deleting the policy makes all 14 eligible for permanent, unrecoverable purge. Force-delete is off the table.
Step 6 — the resolution. Matter A: all 46 released, as requested — done. The 5: cleared of Matter A but left fully intact on the orphaned Matter B hold. Then the safe remediation for the orphan itself: create a new eDiscovery hold with a proper case scoped to the custodians who must stay held, wait for propagation, dual-verify it's binding on every mailbox, and only then force-delete the orphan. Because the new hold now preserves everyone, removing the orphan never leaves anyone unprotected — and the out-of-scope custodians stay held under a policy that's actually manageable. Nothing was force-removed without that safety net in place; the state reports went to the Matter B owner and Microsoft Support.
The distilled lessons
The requester's own "warn me if it's another matter" is the trigger that should stop a release — honor it. "Remove all holds" never authorizes touching a different matter. An orphaned policy blocks the safe tool and leaves only the dangerous one — that's a signal to escalate, not to force. And always check for inactive mailboxes before any policy-level action: they're the ones that get destroyed.
Further reading
- Create eDiscovery holds — Microsoft Learncase holds, policies, and rules
- Manage inactive mailboxes — Microsoft Learnthe preserve-after-deletion lifecycle
- Content search — Microsoft LearnNew-/Start-/Get-ComplianceSearch
- Get-Mailbox reference — Microsoft LearnInPlaceHolds, inactive and soft-deleted parameters
Comments
Questions or corrections welcome. Sign in with GitHub to join the thread.