src/Public/SharePoint/Clear-SP365List.ps1

function Clear-SP365List {
    <#
    .SYNOPSIS
        Deletes or recycles every item in a SharePoint list.
 
    .DESCRIPTION
        Retrieves items from the specified SharePoint list in batches and removes
        them until the list is empty. Items are permanently deleted by default.
        Use Recycle to send items to the SharePoint recycle bin instead.
 
        The command requires an active SharePoint connection and prompts for
        confirmation before making changes. Enter an uppercase Y to continue.
 
    .PARAMETER ListName
        The name or identity of the SharePoint list to clear.
 
    .PARAMETER Recycle
        Sends removed items to the SharePoint recycle bin. Without this switch,
        the items are permanently deleted.
 
    .EXAMPLE
        Clear-SP365List -ListName 'Import Queue'
 
        Prompts for confirmation and permanently deletes every item in the list.
 
    .EXAMPLE
        Clear-SP365List -ListName 'Import Queue' -Recycle
 
        Prompts for confirmation and sends every item in the list to the recycle bin.
 
    .INPUTS
        None.
 
    .OUTPUTS
        None.
 
    .NOTES
        This command is destructive. Confirm the current site and selected list
        before entering Y.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        $ListName,
        [Parameter(Mandatory = $false)]
        [switch]$Recycle = $false
    )
    try {

        $privatePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath "private"
        @(Get-ChildItem -Path $privatePath -Recurse -Filter "*.ps1") | ForEach-Object {
            try {
                . $_.FullName
            }
            catch {
                exit
            }
        }

        Test-ForModuleUpdate

        $list = Get-PnPList -Identity $listName
        if (-not $list) {
            Write-Error "List '$listName' not found."
            return
        }
        if ($Recycle) {
            Write-Host -ForegroundColor Yellow "WARNING: This will Recycle all $($list.ItemCount) items in the list '$listName'."
        }
        else {
            Write-Host -ForegroundColor Yellow "WARNING: This will permanently delete all $($list.ItemCount) items in the list '$listName'."
        }
        $input = Read-Host "Are you sure you want to continue? Type 'Y' to confirm"
        if ($input -ne "Y") {
            Write-Host -ForegroundColor Yellow "Operation cancelled."
            return
        }

        $deletedCounter = 0
        $itemTotal = (Get-PnPList -Identity $listName).ItemCount
        do {
            Write-Host -NoNewline "Retrieving items from list '$listName' (Total Items: $itemTotal)"
            $items = Get-PnPListItem -List $listName -PageSize 1000 
            Write-Host -ForegroundColor Green " .....Done!"
            Write-Host -NoNewline "Processing items for $($Recycle ? 'Recycling' : 'Deleting')"
            
            $items | ForEach-Object {
                $percent = "{0:n1}" -f (($deletedCounter / $itemTotal) * 100)
                Write-Progress -Activity "$($Recycle ? 'Recycling' : 'Deleting') SharePoint List Items: $listName (Items: $itemTotal)" -Status "$percent% Complete:" -PercentComplete $percent
                if ($Recycle) {
                    Remove-PnPListItem -List $listName -Identity $_.Id -Recycle -Force | Out-Null
                }
                else {
                    Remove-PnPListItem -List $listName -Identity $_.Id -Force | Out-Null
                }
                $deletedCounter++
            }
        } until ((Get-PnPList -Identity $listName).ItemCount -eq 0)
        Write-Host -ForegroundColor Green " .....Done!"
    }
    catch {
        if ($_.Exception.Message -eq "The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument to connect.") {
            Write-Error "The current connection holds no SharePoint context. Please use one of the Connect-SP365 commands which uses the -Url argument to connect."
        }
        else {
            Write-Error $_.Exception.Message
        }
    }
}
Export-ModuleMember -Function *
# SIG # Begin signature block
# MIIHMAYJKoZIhvcNAQcCoIIHITCCBx0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDxYx+u91wVPsPo
# ypsJyi3qJuj5wf7a8/XXvrWk4l3PHKCCBBwwggQYMIICgKADAgECAhBH6tQY1Crt
# r02dueiKibmNMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNVBAMMGU0zNjUuVG9vbGtp
# dCBDb2RlIFNpZ25pbmcwHhcNMjYwNzE2MTY1NjE0WhcNMjcwNzE2MTcwNjEzWjAk
# MSIwIAYDVQQDDBlNMzY1LlRvb2xraXQgQ29kZSBTaWduaW5nMIIBojANBgkqhkiG
# 9w0BAQEFAAOCAY8AMIIBigKCAYEAxQCBRWJ923yIy73AwGWtFvfBL/dZHvwCBO05
# dJopbkHGcCqifl9R21PXr5OIjcEFv16ObYL23cPwZaNKCiejuiU32MHwidYHU1k5
# AzFpjwW2uwjeA7Hip3cURwoeOH/LzNa/xNTBRiO70M7gunZCm+FixDcPKf66Tvb1
# iM6pbOFmJvzbGjFqKM6mQRofaCPU89SHW5y43HyZNdiWsJTN4TsWj96Rps4fKhh2
# gToexqi0GhLHhLtVQ8ZxMic6w0C9sCWhYBl3kw1OJdaa/MVBdVAXDOIL0HIG8jOa
# l1x67U1LihXEw1hdc3YabhvSYZ5ZXPV1AZ2z6+Qa0EL9XlJWqBkn0rO6sZB1IkOo
# gfeTxVuI6SjhqpW6QrAFFJzb81qd0dDWmmuVka1yoWEic7naZpDfuh3JZPOUilE1
# Wv3qhBDYN5qg1qXeh0RMosR8rMfKjE8CFvsB7LTibom+22in1x16vmIiv9ep5HNc
# eS0hRa/84+vmXQ8R6hN8x+oWbG8NAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDAT
# BgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUu9RWiOCtUYtlrLgwzVDsor7P
# p88wDQYJKoZIhvcNAQELBQADggGBAKJksJX6tgjdng//9wRM2ztQn8breDnY/Zki
# 8iXrC94sqCYoYg1lT0pVHZq1ZHpdUNh/xQnjP9asbIqgUt0YiCIASCONV2nM2wyK
# VjrvxaC08xefuHiO/R6Uc9sDW38mID+gDoAmswmB9JV5qm+j8b4hw3vcwuUe3nla
# 5bn3YoKXLY4/YJjHNA62TmhYNfs7iwdk2vyH/dCvD35LdBhP/y2ChmOxzI1aSp4L
# c65zCFVDPzw1IED/5q9NM48QUVDgVAX6VNuocjXZpWd7fHf7KFLRJSExXtaYQCdk
# hBSITzd5WBT2opKF02TrTyc5h1zCTr6HU+1Eqr92fvEGfqk4yYSt4plyqbm6Unnq
# gEgwDqlgm9ZNA8hzorcoxSetVVZ8z+50KB55JRTENZ/5kOJWzPtoIA+PdmFvg3wU
# jQHhO6C32rdVUk+j1hI1zL6sR8gYn5VmLPVjfs49yKf+2t3iDsaYVRNawOqHrMZj
# g59c2M2hT5D6krLsI8r3F/t3YfHbKjGCAmowggJmAgEBMDgwJDEiMCAGA1UEAwwZ
# TTM2NS5Ub29sa2l0IENvZGUgU2lnbmluZwIQR+rUGNQq7a9Nnbnoiom5jTANBglg
# hkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV
# MC8GCSqGSIb3DQEJBDEiBCAX3dsXFO+9mla0OLBVvv7gZcaSipgxSJHdcXYMuVd2
# vzANBgkqhkiG9w0BAQEFAASCAYBqDcHV+8S4YKzZ7krm0heqbWbDouzxD9ZpIt5l
# tb2R4a+qrS6s5LX/9HzpNB5j0y5JvSOzAOXcgw2nTDsbu4gGJVv41PeJth5sYNOv
# CaBNY3YxzX0e0WVR8LfsmODUPeHpvOlwHFxXMBWpiReQ96ppi1Eb8C2UlcCxSkiS
# T7JrUpw7ECz+j3tVbcGflBN0a9zOQeTtS44zgYb1KbAw6xmZY5oDmK01tR1Q9uvh
# 2itqYSsb0An75sgtvAHjNA98uyDWSZC5mBgvvjqoBWoSwiAG6+s3J+CLw7zukehd
# CMl+aiUZtU7Rokua6ZyzJOOZzNqpTxsTq3G9UthYCTyQpav92htbGUODvJpQ5Pez
# fTKf2pODhA/AttbXI4aMfC5RPZTkXCgsL/y6ezGZeJT0rcCglk8XmCvQA/8qN+Oe
# 29SFLGyuV3GhIsrvEzt53LnXkagsUdSHSI5HLi5mn/xOY65v8fT1kpy4d3jpEAth
# tB4tAgWL42eQ5GTCHXtmsC0VQEw=
# SIG # End signature block