Skip to content

caseHoldRules

Case Hold Rules. Query rules scoping what a case-hold policy preserves. The caseHoldRules entity set lives under /exchange/v1.0/caseHoldRules in the eDiscovery & audit category.

Fact Value
Path /exchange/v1.0/caseHoldRules
Category eDiscovery & audit
Tier Tier 5, Compliance
Read role Compliance.IPPS.Read.All (Community)
Write role none (read-only)
Backing cmdlets Get-CaseHoldRule, Set-CaseHoldRule, New-CaseHoldRule, Remove-CaseHoldRule
Method Path Synopsis Role Plan
GET /exchange/v1.0/caseHoldRules List caseHoldRules entries. Compliance.IPPS.Read Community
POST /exchange/v1.0/caseHoldRules Create a new caseHoldRules entry. Body keys map 1:1 to New-CaseHoldRule parameter names (camelCased). Required: name + policy (parent case-hold policy Name or GUID). Returns 201 + Location + the freshly-fetched rule. Compliance.IPPS.ReadWrite Enterprise
GET /exchange/v1.0/caseHoldRules/{key} Get a single caseHoldRules entry by Identity. Compliance.IPPS.Read Community
PATCH /exchange/v1.0/caseHoldRules/{key} Partial update of the caseHoldRules at /caseHoldRules/{key}. Body keys map 1:1 to Set-CaseHoldRule parameters. Returns 200 + the post-Set rule. Compliance.IPPS.ReadWrite Enterprise
DELETE /exchange/v1.0/caseHoldRules/{key} Remove the caseHoldRules at /caseHoldRules/{key}. Returns 204 with no body. Compliance.IPPS.ReadWrite Enterprise

List caseHoldRules entries.

Backing cmdlet: Get-CaseHoldRule. Role: Compliance.IPPS.Read (Community).

Parameter In Type Required Description
policy query string Scope to rules under a specific case-hold policy (policy Name or GUID).

Lists per-case hold rules via Get-CaseHoldRule on the IPPS pool. Each rule scopes a content query and date range under its parent caseHoldPolicy (the Policy field is the GUID back-pointer). Optional ?policy=<name|guid> narrows to one policy’s rules. Unlike caseHoldPolicies, list-all is allowed.

GET /exchange/v1.0/caseHoldRules HTTP/1.1
Authorization: Bearer {token}
HTTP/1.1 200 OK
{
"@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules(Id,Name,Mode,Disabled,Policy,Workload)",
"value": [
{
"Id": "contoso.com/Configuration/Q1 2026 Hold Policy",
"Name": "Q1 2026 Hold Policy",
"Policy": "policy-q1-2026-guid",
"Disabled": false,
"Mode": "Enforce",
"Workload": "Exchange, SharePoint"
},
{
"Id": "contoso.com/Configuration/Litigation Houston Hold",
"Name": "Litigation Houston Hold",
"Policy": "policy-litigation-houston",
"Disabled": false,
"Mode": "Enforce",
"Workload": "Exchange, SharePoint"
}
]
}

Related: GET /exchange/v1.0/caseHoldPolicies/{key}, GET /exchange/v1.0/caseHoldRules/{key}

Create a new caseHoldRules entry. Body keys map 1:1 to New-CaseHoldRule parameter names (camelCased). Required: name + policy (parent case-hold policy Name or GUID). Returns 201 + Location + the freshly-fetched rule.

Creates a rule scoped to a parent caseHoldPolicies entry, identified by the required policy field. The contentMatchQuery (KQL) narrows the hold to matching content; omit it to hold ALL content in the policy’s locations. Note: the rule-state toggle is disabled (Boolean), not enabled, the opposite of the parent policy. disabled: false means the rule is active.IPPS-side - controller passes omitConfirm: true. Pass ?dryRun=true to map to -WhatIf.

Backing cmdlet: New-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).

Parameter In Type Required Description
name body yes
policy body yes
comment body
contentMatchQuery body
disabled body
dryRun query bool (switch)

Create a content-match rule for a case hold policy

Section titled “Create a content-match rule for a case hold policy”

Create a new case hold rule via New-CaseHoldRule on the IPPS pool. Required: name + policy (parent caseHoldPolicies Name or GUID). Optional contentMatchQuery (KQL) narrows the hold to matching content; omit it to hold ALL content in the policy’s locations. Note: the rule-state toggle is disabled (Boolean), not enabled like the parent policy. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.

POST /exchange/v1.0/caseHoldRules HTTP/1.1
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "Q1-2026-Project-Apollo-Filter",
"policy": "Q1-2026-Litigation-Hold",
"comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.",
"contentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01",
"disabled": false
}
HTTP/1.1 201 Created
Location: /exchange/v1.0/caseHoldRules/Q1-2026-Project-Apollo-Filter
{
"@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity",
"Id": "rule-apollo-guid",
"Name": "Q1-2026-Project-Apollo-Filter",
"Identity": "rule-apollo-guid",
"Policy": "hold-q1-2026-litigation",
"Disabled": false,
"Mode": "Enforce",
"ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01",
"Comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.",
"Workload": "Exchange, SharePoint",
"Priority": 0,
"WhenCreated": "2026-05-25T10:15:00Z",
"WhenChanged": "2026-05-25T10:15:00Z"
}

Related: GET /exchange/v1.0/caseHoldRules?policy={policyId}, GET /exchange/v1.0/caseHoldRules/{key}, PATCH /exchange/v1.0/caseHoldRules/{key}, DELETE /exchange/v1.0/caseHoldRules/{key}, GET /exchange/v1.0/caseHoldPolicies/{policy}

Get a single caseHoldRules entry by Identity.

Backing cmdlet: Get-CaseHoldRule. Role: Compliance.IPPS.Read (Community).

Get a single case hold rule by Identity (Name or GUID). Backed by Get-CaseHoldRule on the IPPS pool. Use GET /caseHoldRules?policy={policyId} to discover rules under a specific parent caseHoldPolicies entry.

GET /exchange/v1.0/caseHoldRules/{key} HTTP/1.1
Authorization: Bearer {token}
HTTP/1.1 200 OK
{
"@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity",
"Id": "rule-apollo-guid",
"Name": "Q1-2026-Project-Apollo-Filter",
"Identity": "rule-apollo-guid",
"Policy": "hold-q1-2026-litigation",
"Disabled": false,
"Mode": "Enforce",
"ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01",
"Comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.",
"HoldContent": "All",
"Workload": "Exchange, SharePoint",
"Priority": 0,
"CreatedBy": "John Woods",
"LastModifiedBy": "John Woods",
"WhenCreated": "2026-05-25T10:15:00Z",
"WhenChanged": "2026-05-25T10:15:00Z",
"WhenCreatedUTC": "2026-05-25T10:15:00Z",
"WhenChangedUTC": "2026-05-25T10:15:00Z"
}

Related: GET /exchange/v1.0/caseHoldRules?policy={policyId}, PATCH /exchange/v1.0/caseHoldRules/{key}, DELETE /exchange/v1.0/caseHoldRules/{key}, GET /exchange/v1.0/caseHoldPolicies/{policy}

Partial update of the caseHoldRules at /caseHoldRules/{key}. Body keys map 1:1 to Set-CaseHoldRule parameters. Returns 200 + the post-Set rule.

Use this endpoint to tune a rule post-creation - narrow / widen the KQL filter via contentMatchQuery, toggle the rule on/off via disabled, or amend the comment. The parent policy link is immutable after creation; to move a rule between policies, DELETE + re-POST. IPPS-side - controller passes omitConfirm: true.

Backing cmdlet: Set-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).

Parameter In Type Required Description
comment body
contentMatchQuery body
disabled body
dryRun query bool (switch)

Partial update of the case hold rule at /caseHoldRules/{key} via Set-CaseHoldRule on the IPPS pool. Tune the rule post-creation: narrow or widen the KQL filter via contentMatchQuery, toggle the rule on/off via disabled (Boolean - disabled:false means active), or amend the comment. The parent policy link is immutable; to move a rule between policies, DELETE + re-POST. Returns 200 + the post-Set rule. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.

PATCH /exchange/v1.0/caseHoldRules/{key} HTTP/1.1
Authorization: Bearer {token}
Content-Type: application/json
{
"comment": "Updated by exonaut-sample automation: broadened scope to all Project Apollo correspondence.",
"contentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-01-01",
"disabled": false
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity",
"Id": "exonaut-sample-caseHoldRules",
"Name": "exonaut-sample-caseHoldRules",
"Identity": "exonaut-sample-caseHoldRules",
"Policy": "exonaut-sample-caseHoldPolicy",
"Disabled": false,
"Mode": "Enforce",
"ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-01-01",
"Comment": "Updated by exonaut-sample automation: broadened scope to all Project Apollo correspondence.",
"Workload": "Exchange, SharePoint",
"Priority": 0,
"WhenCreated": "2026-05-29T10:15:00Z",
"WhenChanged": "2026-05-29T11:42:00Z"
}

Notes: Doc-derived from Wiki + write-param allowlist; not live-captured. Body fields are Wiki-valid; values are illustrative.

Related: GET /exchange/v1.0/caseHoldRules

Remove the caseHoldRules at /caseHoldRules/{key}. Returns 204 with no body.

Rules don’t have their own distribution-pending state (only the parent caseHoldPolicies entry does), so no pre-DELETE guard is needed here. However, if the parent policy is currently in distributionStatus: “Pending”, the cmdlet may surface a related tenant-side error. Wait for the parent policy to settle, or retry distribution via PATCH on the parent policy.IPPS-side - omitConfirm: true. Note: this cmdlet uses -ForceDeletion (not the usual -Force); we don’t expose it in the surface - the standard DELETE flow covers the practical case.

Backing cmdlet: Remove-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).

Parameter In Type Required Description
dryRun query bool (switch)

Remove the case hold rule at /caseHoldRules/{key} via Remove-CaseHoldRule on the IPPS pool. Returns 204 with no body. Rules have no own distribution-pending state, but if the parent caseHoldPolicies entry is in distributionStatus ‘Pending’ the cmdlet may surface a related tenant-side error - wait for the parent policy to settle or retry distribution via PATCH on the parent policy. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.

DELETE /exchange/v1.0/caseHoldRules/{key} HTTP/1.1
Authorization: Bearer {token}
Content-Type: application/json
HTTP/1.1 204 No Content

Notes: Doc-derived from Wiki + write-param allowlist; not live-captured. Body fields are Wiki-valid; values are illustrative.

Related: GET /exchange/v1.0/caseHoldRules

?dryRun=true previews of any write stay on Community.