Public/Remove-LocalRepositoryPackage.ps1

function Remove-LocalRepositoryPackage {
    <#
    .SYNOPSIS
        Remove packages from a local repository.
 
    .DESCRIPTION
        Removes specific packages or versions from a local repository directory.
        Can remove specific versions, all versions of a package, or old versions only.
 
    .PARAMETER Path
        Path to the local repository. Defaults to C:\LocalNuGetRepo.
 
    .PARAMETER PackageName
        Name of the package to remove.
 
    .PARAMETER Version
        Specific version to remove. If not specified, removes all versions.
 
    .PARAMETER KeepLatest
        When removing all versions, keep the latest version.
 
    .PARAMETER OlderThan
        Remove versions older than the specified number of days.
 
    .PARAMETER Force
        Force removal without confirmation prompts.
 
    .EXAMPLE
        Remove-LocalRepositoryPackage -PackageName "MyModule"
         
        Removes all versions of MyModule package.
 
    .EXAMPLE
        Remove-LocalRepositoryPackage -PackageName "MyModule" -Version "1.0.9"
         
        Removes specific version 1.0.9 of MyModule.
 
    .EXAMPLE
        Remove-LocalRepositoryPackage -PackageName "MyModule" -KeepLatest
         
        Removes all versions of MyModule except the latest.
 
    .EXAMPLE
        Remove-LocalRepositoryPackage -OlderThan 30 -Force
         
        Removes all package versions older than 30 days without confirmation.
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
    param(
        [Parameter(Position = 0)]
        [ValidateScript({
            if (-not (Test-Path -Path $_ -PathType Container)) {
                throw "Path '$_' does not exist or is not a directory."
            }
            $true
        })]
        [string]$Path = $script:DefaultRepositoryPath,
        
        [Parameter(Position = 1)]
        [string]$PackageName,
        
        [Parameter()]
        [string]$Version,
        
        [Parameter()]
        [switch]$KeepLatest,
        
        [Parameter()]
        [int]$OlderThan,
        
        [Parameter()]
        [switch]$Force
    )

    try {
        Write-Host "Scanning repository for packages to remove: $Path" -ForegroundColor Cyan
        
        # Find all .nupkg files
        $nupkgFiles = Get-ChildItem -Path $Path -Filter "*.nupkg" -File
        
        if (-not $nupkgFiles) {
            Write-Host "No packages found in repository: $Path" -ForegroundColor Yellow
            return
        }
        
        # Parse package information
        $allPackages = @()
        foreach ($file in $nupkgFiles) {
            $pkgInfo = Get-NuPkgInfo -FilePath $file.FullName
            if ($pkgInfo) {
                $allPackages += [PSCustomObject]@{
                    Name = $pkgInfo.Name
                    Version = $pkgInfo.Version
                    VersionString = $pkgInfo.VersionString
                    FileName = $pkgInfo.FileName
                    FilePath = $pkgInfo.FilePath
                    LastModified = $pkgInfo.LastModified
                    Size = $pkgInfo.Size
                }
            }
        }
        
        if ($allPackages.Count -eq 0) {
            Write-Host "No valid packages found in repository" -ForegroundColor Yellow
            return
        }
        
        # Filter packages to remove
        $packagesToRemove = @()
        
        if ($PackageName) {
            # Filter by package name
            $packageMatches = $allPackages | Where-Object { $_.Name -eq $PackageName }
            
            if (-not $packageMatches) {
                Write-Error "Package '$PackageName' not found in repository"
                return
            }
            
            if ($Version) {
                # Specific version
                $packagesToRemove = $packageMatches | Where-Object { $_.VersionString -eq $Version }
                if (-not $packagesToRemove) {
                    Write-Error "Version '$Version' of package '$PackageName' not found"
                    return
                }
            } elseif ($KeepLatest) {
                # All versions except latest
                $latest = $packageMatches | Sort-Object Version -Descending | Select-Object -First 1
                $packagesToRemove = $packageMatches | Where-Object { $_.VersionString -ne $latest.VersionString }
            } else {
                # All versions
                $packagesToRemove = $packageMatches
            }
        } elseif ($OlderThan) {
            # Filter by age
            $cutoffDate = (Get-Date).AddDays(-$OlderThan)
            $packagesToRemove = $allPackages | Where-Object { $_.LastModified -lt $cutoffDate }
        } else {
            Write-Error "Must specify either -PackageName or -OlderThan parameter"
            return
        }
        
        if ($packagesToRemove.Count -eq 0) {
            Write-Host "No packages match the removal criteria" -ForegroundColor Yellow
            return
        }
        
        # Show packages to be removed
        Write-Host "`nPackages to remove:" -ForegroundColor Yellow
        Write-Host "==================" -ForegroundColor Yellow
        
        $totalSize = 0
        foreach ($pkg in $packagesToRemove) {
            Write-Host " - $($pkg.Name) v$($pkg.VersionString) ($($pkg.Size) MB)" -ForegroundColor Red
            $totalSize += $pkg.Size
        }
        
        Write-Host "`nTotal: $($packagesToRemove.Count) package(s), $([math]::Round($totalSize, 2)) MB" -ForegroundColor Gray
        
        # Confirm removal unless Force is specified
        if (-not $Force) {
            $confirmation = Read-Host "`nAre you sure you want to remove these packages? (y/N)"
            if ($confirmation -notin @('y', 'Y', 'yes', 'Yes', 'YES')) {
                Write-Host "Package removal cancelled" -ForegroundColor Yellow
                return
            }
        }
        
        # Remove packages
        $removedCount = 0
        $failedCount = 0
        
        foreach ($pkg in $packagesToRemove) {
            if ($PSCmdlet.ShouldProcess($pkg.FileName, "Remove package file")) {
                try {
                    Remove-Item -Path $pkg.FilePath -Force
                    Write-Host " [OK] Removed: $($pkg.FileName)" -ForegroundColor Green
                    $removedCount++
                } catch {
                    Write-Warning "Failed to remove $($pkg.FileName): $($_.Exception.Message)"
                    $failedCount++
                }
            }
        }
        
        # Show summary
        Write-Host "`n[SUMMARY] Package removal completed" -ForegroundColor Green
        Write-Host " Removed: $removedCount package(s)" -ForegroundColor White
        if ($failedCount -gt 0) {
            Write-Host " Failed: $failedCount package(s)" -ForegroundColor Red
        }
        
        # Show remaining packages
        $remainingPackages = Get-ChildItem -Path $Path -Filter "*.nupkg" -File
        Write-Host " Remaining: $($remainingPackages.Count) package(s)" -ForegroundColor Gray
        
    } catch {
        Write-Error "Failed to remove packages: $($_.Exception.Message)"
    }
}