functions/Get-XdrXspmChokePoint.ps1

function Get-XdrXspmChokePoint {
    <#
    .SYNOPSIS
        Retrieves choke point data from Microsoft Defender XDR XSPM.

    .DESCRIPTION
        Gets choke point information from the XSPM (Extended Security Posture Management) attack surface API.
        Choke points are critical nodes in the network that appear in multiple attack paths, making them
        high-value targets for security hardening and monitoring.
        The results are ordered by risk level (Critical, High, Medium, Low) and attack path count.
        Supports pagination and can retrieve all available choke points when using the -All parameter.
        This function includes caching support with a 30-minute TTL to reduce API calls.

    .PARAMETER Top
        The maximum number of choke points to return per page. Default is 100.
        Ignored when -All is specified.

    .PARAMETER Skip
        The number of choke points to skip for pagination. Default is 0.
        Ignored when -All is specified.

    .PARAMETER All
        When specified, retrieves all available choke points by handling pagination automatically.

    .PARAMETER Force
        Bypasses the cache and forces a fresh retrieval from the API.

    .EXAMPLE
        Get-XdrXspmChokePoint
        Retrieves the first 100 choke points, ordered by risk level and attack path count.

    .EXAMPLE
        Get-XdrXspmChokePoint -Top 50
        Retrieves the first 50 choke points.

    .EXAMPLE
        Get-XdrXspmChokePoint -Top 100 -Skip 100
        Retrieves choke points 101-200 (pagination).

    .EXAMPLE
        Get-XdrXspmChokePoint -All
        Retrieves all available choke points by automatically handling pagination.

    .EXAMPLE
        Get-XdrXspmChokePoint -All -Force
        Retrieves all choke points, bypassing the cache.

    .OUTPUTS
        Array
        Returns an array of choke point objects containing node information, attack path counts, and risk levels.
    #>

    [OutputType([System.Object[]])]
    [CmdletBinding()]
    param (
        [Parameter()]
        [int]$Top = 100,

        [Parameter()]
        [int]$Skip = 0,

        [Parameter()]
        [switch]$All,

        [Parameter()]
        [switch]$Force
    )

    begin {
        Update-XdrConnectionSettings
    }

    process {
        # Define the choke point query
        $query = @"
AttackPathDiscovery
| where AttackPathsCount > 1
| extend RiskOrder=case(MaxRiskLevel == 'Critical', 0,
    MaxRiskLevel == 'High', 1,
    MaxRiskLevel == 'Medium', 2,
    MaxRiskLevel == 'Low', 3, 4)
| order by RiskOrder asc, AttackPathsCount desc
"@


        if ($All) {
            Write-Verbose "Retrieving all choke points with automatic pagination"

            $allChokePoints = @()
            $currentSkip = 0
            $pageSize = 100

            do {
                Write-Verbose "Fetching page starting at record $currentSkip"

                try {
                    $queryResult = Invoke-XdrXspmHuntingQuery -Query $query -ScenarioName "ChokePoints_get_choke_point_types_filter" -Top $pageSize -Skip $currentSkip -Force:$Force

                    if ($queryResult.data -and $queryResult.data.Count -gt 0) {
                        $allChokePoints += $queryResult.data
                        Write-Verbose "Retrieved $($queryResult.data.Count) choke points (Total so far: $($allChokePoints.Count))"

                        # Check if we've retrieved all records
                        if ($queryResult.totalRecords -le ($currentSkip + $queryResult.data.Count)) {
                            Write-Verbose "All choke points retrieved. Total: $($allChokePoints.Count)"
                            break
                        }

                        $currentSkip += $pageSize
                    } else {
                        Write-Verbose "No more choke points to retrieve"
                        break
                    }
                } catch {
                    Write-Error "Failed to retrieve choke points at skip position $currentSkip : $_"
                    throw
                }
            } while ($true)

            return $allChokePoints
        } else {
            # Single page retrieval
            Write-Verbose "Retrieving choke points (Top: $Top, Skip: $Skip)"

            try {
                $queryResult = Invoke-XdrXspmHuntingQuery -Query $query -ScenarioName "ChokePoints_get_choke_point_types_filter" -Top $Top -Skip $Skip -Force:$Force

                if ($queryResult.data) {
                    Write-Verbose "Retrieved $($queryResult.data.Count) of $($queryResult.totalRecords) total choke points"
                    return $queryResult.data
                } else {
                    Write-Verbose "No choke points found"
                    return @()
                }
            } catch {
                Write-Error "Failed to retrieve choke points: $_"
                throw
            }
        }
    }

    end {

    }
}