src/Public/SharePoint/Restore-SP365ListItems.ps1

function Restore-SP365ListItems {
    <#
    .SYNOPSIS
        Restores a SharePoint list's items from the recycle bin.
 
    .DESCRIPTION
        Finds recycle-bin items whose directory matches the root folder of the
        specified SharePoint list and restores each item.
 
        The command requires an active SharePoint connection and prompts for
        confirmation before restoring items. Enter an uppercase Y to continue.
 
    .PARAMETER ListName
        The name or identity of the SharePoint list whose recycled items should
        be restored.
 
    .EXAMPLE
        Restore-SP365ListItems -ListName 'Import Queue'
 
        Prompts for confirmation and restores matching recycle-bin items to the
        Import Queue list.
 
    .INPUTS
        None.
 
    .OUTPUTS
        The command may emit output returned by Restore-PnPRecycleBinItem.
 
    .NOTES
        Only items currently available in the SharePoint recycle bin and
        associated with the list's root folder can be restored.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        $ListName
    )
    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
        }
        Write-Host "Looking for items in the Recycle Bin that belong to the list '$listName'..."

        $items = Get-PnPRecycleBinItem | Where-Object { $_.DirName -eq $list.RootFolder.ServerRelativeUrl.TrimStart('/') } 
        Write-Host -ForegroundColor Yellow "WARNING: This will Restore all $($items.Count) 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
        }

        $items | ForEach-Object {
            Write-Host -NoNewline "Restoring item: $($_.Title)"
            Restore-PnPRecycleBinItem -Identity $_.Id -Force
            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
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAOVzCrZ4x72Mik
# YqdbN5TmAr7/7t15YES0EtzHDijh36CCBBwwggQYMIICgKADAgECAhBH6tQY1Crt
# 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
# MC8GCSqGSIb3DQEJBDEiBCBhtDBx6BgiygAYIrUuAiA3xGQKc9ch51pq3oMH37QL
# fjANBgkqhkiG9w0BAQEFAASCAYBt4hQJrNDhLv14aQYCT1WDkxtRIzPby0xADwEW
# KxK4jCmPvEkTMfzt7H05anDkX2II6Fp8kKDILzM/hFAAI/EUESWpNHMA+QD1XoVF
# m2npZq2yr6RZLNZsSD3DehWyIkc57hUM5ocBNq3L7SCrTXW12er1ZiYiUFpcv2W8
# zY9CFVNNwvS1EFd4QFYSMh93db+4szgxqpsXND1PHQPu4fVvMfTGRPaeu6wH/HHE
# kzjL3U7HlNpg+2ucyBk8eQSzkKl3CeZgILmPySlBZdteE0I/OqP3gs5opPzOrjzj
# DhiRavSyUcgAnib4VQ1JHOpx11L52DV6KjrxUWeO5M6FaJUQdOBkOBk7r1q8Rgud
# rv7pgTwpMqmqrXmU4i2Vclzkzy1NcvhfKbL7/VypwyRn8pTAjtXplLTuv1ifK2JO
# vpT9FbcZ1R/yBYwIP8CVwYDa0CLRFxndOkMEJlekohS82xFO+JC+PfazB41MyRnT
# Egu2h3YigscP89U/H7Og2kqQBxM=
# SIG # End signature block