functions/Move-XdrAlertToIncident.ps1

function Move-XdrAlertToIncident {
    <#
    .SYNOPSIS
        Moves alerts to a specific incident or creates a new one.

    .DESCRIPTION
        Moves one or more alerts to a target incident. If TargetIncidentId is not specified,
        a new incident is created containing the alerts.
        Validates that the TargetIncidentId and AlertIds exist before attempting the move.

    .PARAMETER AlertIds
        A list of alert IDs to move.

    .PARAMETER TargetIncidentId
        The ID of the incident to move the alerts to. If null or omitted, a new incident is created.

    .PARAMETER Comment
        Optional comment for the operation. Default is "Moved via XDRInternals".
    
    .PARAMETER Confirm
        Prompts for confirmation before executing the move operation.
    
    .PARAMETER WhatIf
        Shows what would happen if the cmdlet runs.

    .EXAMPLE
        Move-XdrAlertToIncident -AlertIds "ed638962183442188554_-691007355" -TargetIncidentId 2822
        Moves the specified alert to incident 2822.

    .EXAMPLE
        Move-XdrAlertToIncident -AlertIds "ed638962183442188554_-691007355"
        Moves the specified alert to a new incident.
    #>

    [OutputType([PSCustomObject])]
    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]]$AlertIds,

        [Parameter()]
        [long]$TargetIncidentId,

        [Parameter()]
        [string]$Comment = "Moved via XDRInternals"
    )

    begin {
        Update-XdrConnectionSettings
    }

    process {
        # Validate TargetIncidentId if provided
        $incidentIdValue = $null
        if ($PSBoundParameters.ContainsKey('TargetIncidentId') -and $TargetIncidentId -gt 0) {
            Write-Verbose "Validating TargetIncidentId: $TargetIncidentId"
            $incidentSearch = Get-XdrIncidentSearch -Term "$TargetIncidentId"
            
            # Check if we found an exact match
            $incidentMatch = $incidentSearch | Where-Object { $_.incidentId -eq $TargetIncidentId }
            
            if (-not $incidentMatch) {
                Write-Error "Target Incident ID '$TargetIncidentId' not found."
                return
            }
            $incidentIdValue = $TargetIncidentId
        }

        # Validate AlertIds
        $validAlertIds = @()
        foreach ($alertId in $AlertIds) {
            Write-Verbose "Validating AlertId: $alertId"
            $alertSearch = Get-XdrAlertSearch -SearchTerm $alertId
            
            # Check if we found an exact match
            $alertMatch = $alertSearch | Where-Object { $_.id -eq $alertId }

            if ($alertMatch) {
                $validAlertIds += $alertId
            } else {
                Write-Error "Alert ID '$alertId' not found."
                return
            }
        }

        if ($validAlertIds.Count -eq 0) {
            return
        }

        if ($PSCmdlet.ShouldProcess("Alerts: $($validAlertIds -join ', ')", "Move to Incident: $(if ($incidentIdValue) { $incidentIdValue } else { 'New Incident' })")) {
            
            $body = @{
                AlertIds                               = $validAlertIds
                IncidentId                             = $incidentIdValue
                Comment                                = $Comment
                ReturnOkIfAlertAlreadyLinkedToIncident = $true
                FeedbackContent                        = @{
                    ClientFalseCorrelationEntities  = @()
                    ClientFalseCorrelationLinkTypes = @()
                    ClientNewLinkReasons            = @()
                }
            }

            $Uri = "https://security.microsoft.com/apiproxy/mtp/alertsLinks/alerts/incidentLinks?newApi=true"
            
            try {
                $response = Invoke-XdrRestMethod -Uri $Uri -Method POST -Body ($body | ConvertTo-Json -Depth 10) -ErrorAction Stop
                return $response
            } catch {
                Write-Error "Failed to move alerts: $_"
            }
        }
    }
}