Public/Remove-NSPM365InboxRule.ps1

function Remove-NSPM365InboxRule {
    <#
    .SYNOPSIS
        Removes (or with -Disable, disables) inbox rules and clears mailbox forwarding found by Get-NSPM365InboxRuleReport, confirming each and returning what was there first.
    .DESCRIPTION
        Takes Get-NSPM365InboxRuleReport rows from the pipeline, or rule identities. Needs an
        Exchange Online session (Connect-ExchangeOnline) with rights to change mailboxes.
 
          InboxRule rows Remove-InboxRule, or Disable-InboxRule with -Disable
          MailboxForwarding rows Set-Mailbox -ForwardingSmtpAddress $null -ForwardingAddress $null
                                  -DeliverToMailboxAndForward $false (also with -Disable: there is
                                  no disabled state for forwarding)
 
        Each change is confirmed (ConfirmImpact High); -WhatIf shows them all without changing
        anything. Before each change the rule is read again (Get-InboxRule) and returned in
        Before as JSON, so the evidence survives the removal: pipe the results to Export-Csv.
 
        -Disable is the reversible choice while the investigation is open: the rule stops
        running but keeps its settings for the report.
 
        Exchange warns that changing rules outside Outlook deletes rules that were turned off in
        Outlook desktop; that prompt is answered yes (-AlwaysDeleteOutlookRulesBlob), or the
        command would stop for input. Those client-side rules are lost - the same as when the
        user edits a rule in Outlook on the web.
 
        Audit rows (Get-NSPM365InboxRuleAudit) don't carry the rule identity: find the live rule
        with Get-NSPM365InboxRuleReport first.
    .PARAMETER InputObject
        Rows from Get-NSPM365InboxRuleReport.
    .PARAMETER Identity
        Rule identities ('jdoe@contoso.com\1234567890', the report's RuleIdentity).
    .PARAMETER Disable
        Disable rules instead of removing them.
    .EXAMPLE
        Get-NSPM365InboxRuleReport -Mailbox jdoe@contoso.com -SuspiciousOnly | Remove-NSPM365InboxRule -WhatIf
    .EXAMPLE
        Get-NSPM365InboxRuleReport -SuspiciousOnly | Remove-NSPM365InboxRule -Disable | Export-Csv .\rules-disabled.csv -NoTypeInformation
    .EXAMPLE
        Remove-NSPM365InboxRule -Identity 'jdoe@contoso.com\1234567890' -Confirm:$false
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'Report')]
    param(
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Report')]
        [psobject[]]$InputObject,
        [Parameter(Mandatory, ParameterSetName = 'Identity')]
        [string[]]$Identity,
        [switch]$Disable
    )

    begin {
        $disableRules = [bool]$Disable
        if (-not (Get-Command Remove-InboxRule -ErrorAction SilentlyContinue)) {
            throw 'Remove-InboxRule is not available: run Connect-ExchangeOnline (ExchangeOnlineManagement module) first.'
        }
        $result = {
            param($Row, $Action, $Outcome, $Before)
            [pscustomobject]@{
                Mailbox      = [string]$Row.Mailbox
                Kind         = [string]$Row.Kind
                RuleName     = [string]$Row.RuleName
                RuleIdentity = [string]$Row.RuleIdentity
                Action       = $Action
                Result       = $Outcome
                Flags        = [string]$Row.Flags
                Before       = if ($null -ne $Before) { ConvertTo-Json -InputObject $Before -Depth 4 -Compress } else { '' }
            }
        }
        $handle = {
            param($Row)
            if ($Row.Kind -eq 'MailboxForwarding') {
                $before = Get-Mailbox -Identity $Row.Mailbox -ErrorAction Stop | Select-Object PrimarySmtpAddress, ForwardingSmtpAddress, ForwardingAddress, DeliverToMailboxAndForward
                if (-not $PSCmdlet.ShouldProcess("$($Row.Mailbox) (forwarding to $($Row.ForwardTo))", 'Clear mailbox forwarding')) {
                    return (& $result $Row 'ClearForwarding' 'Skipped' $before)
                }
                try {
                    Set-Mailbox -Identity $Row.Mailbox -ForwardingSmtpAddress $null -ForwardingAddress $null -DeliverToMailboxAndForward $false -Confirm:$false -ErrorAction Stop
                    & $result $Row 'ClearForwarding' 'Done' $before
                } catch { & $result $Row 'ClearForwarding' "Failed: $($_.Exception.Message)" $before }
                return
            }

            if (-not $Row.RuleIdentity) {
                Write-Error "No RuleIdentity on '$($Row.RuleName)' ($($Row.Mailbox)): pass rows from Get-NSPM365InboxRuleReport, or -Identity."
                return
            }
            $action = if ($disableRules) { 'Disable' } else { 'Remove' }
            try {
                $before = Get-InboxRule -Identity $Row.RuleIdentity -ErrorAction Stop | Select-Object *
            } catch {
                return (& $result $Row $action "Failed: rule not found ($($_.Exception.Message))" $null)
            }
            $name = if ($Row.RuleName) { $Row.RuleName } else { [string]$before.Name }
            $mailbox = if ($Row.Mailbox) { $Row.Mailbox } else { [string]$before.MailboxOwnerId }
            if (-not $PSCmdlet.ShouldProcess("'$name' ($($Row.RuleIdentity)) in $mailbox", "$action inbox rule")) {
                return (& $result $Row $action 'Skipped' $before)
            }
            try {
                if ($disableRules) {
                    Disable-InboxRule -Identity $Row.RuleIdentity -AlwaysDeleteOutlookRulesBlob -Force -Confirm:$false -ErrorAction Stop
                } else {
                    Remove-InboxRule -Identity $Row.RuleIdentity -AlwaysDeleteOutlookRulesBlob -Force -Confirm:$false -ErrorAction Stop
                }
                & $result $Row $action 'Done' $before
            } catch { & $result $Row $action "Failed: $($_.Exception.Message)" $before }
        }
    }
    process {
        $rows = if ($PSCmdlet.ParameterSetName -eq 'Identity') {
            @($Identity | ForEach-Object { [pscustomobject]@{ Mailbox = ''; Kind = 'InboxRule'; RuleName = ''; RuleIdentity = $_; Flags = '' } })
        } else { @($InputObject) }
        foreach ($row in $rows) { if ($null -ne $row) { & $handle $row } }
    }
}