Created
July 1, 2025 15:21
-
-
Save guibranco/6471f6ce03cf9ba5f76c37c35d185bf8 to your computer and use it in GitHub Desktop.
PowerShell cleanup script to remove temporary/packages/modules files from a developer machine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| param ( | |
| [switch]$DryRun, | |
| [switch]$Verbose | |
| ) | |
| # π Track start time | |
| $StartTime = Get-Date | |
| $LogEntries = @() | |
| # π‘οΈ Admin check | |
| if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` | |
| [Security.Principal.WindowsBuiltInRole]::Administrator)) { | |
| Write-Warning "This script requires administrator privileges. Please run it as an administrator." | |
| exit 1 | |
| } | |
| # π Log file paths | |
| $PlainLog = "cleanup_log.txt" | |
| $HtmlLog = "cleanup_log.html" | |
| function Log { | |
| param ( | |
| [string]$Message, | |
| [string]$Type = "INFO" # INFO | WARN | ERROR | ACTION | |
| ) | |
| $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" | |
| $entry = [PSCustomObject]@{ | |
| Time = $Timestamp | |
| Type = $Type | |
| Message = $Message | |
| } | |
| $LogEntries += $entry | |
| if ($Verbose) { | |
| $prefix = if ($Type -eq "ERROR") { "[X]" } elseif ($Type -eq "WARN") { "[!]" } elseif ($Type -eq "ACTION") { "[>]" } else { "[Β·]" } | |
| Write-Host "$prefix $Timestamp - $Message" | |
| } | |
| "$Timestamp [$Type] $Message" | Out-File -Append -FilePath $PlainLog | |
| } | |
| # π Relative folder names to delete recursively | |
| $DirList = @( | |
| "bin", "obj", "node_modules", "target\debug", "target\tmp", | |
| ".angular", ".terraform", | |
| "visuals\traces", "visuals\videos", "visuals\screenshots", "visuals\information" | |
| ) | |
| # π Full path folders to delete directly | |
| $AdditionalDirList = @( | |
| $env:TEMP, | |
| "C:\Windows\Temp", | |
| "$env:USERPROFILE\AppData\Local\Temp", | |
| "C:\ProgramData\Microsoft\Windows\WER\ReportQueue", | |
| "C:\Windows\SoftwareDistribution\Download" | |
| ) | |
| $VsCodeDirs = @( | |
| "$env:APPDATA\Code\Cache", | |
| "$env:APPDATA\Code\Cookies", | |
| "$env:APPDATA\Code\LocalStorage", | |
| "$env:APPDATA\Code\User\workspaceStorage" | |
| ) | |
| $CacheDirs = @( | |
| "$env:APPDATA\Local\pip\cache", | |
| "$env:GOPATH\pkg\mod", | |
| "$env:USERPROFILE\.cargo", | |
| "$env:APPDATA\npm-cache", | |
| "$env:USERPROFILE\AppData\Local\Microsoft\VisualStudio" | |
| ) | |
| function Remove-Directory { | |
| param ( | |
| [string]$Path, | |
| [string]$Reason = "Deleting directory", | |
| [switch]$DryRun | |
| ) | |
| if (Test-Path $Path) { | |
| if ($DryRun) { | |
| Log "${Reason}: ${Path} - WOULD DELETE (dry run)" "ACTION" | |
| } else { | |
| try { | |
| Remove-Item -Path $Path -Recurse -Force -ErrorAction Stop | |
| Log "${Reason}: ${Path} - SUCCESS" "ACTION" | |
| } catch { | |
| Log "${Reason}: ${Path} - ERROR: $_" "ERROR" | |
| } | |
| } | |
| } else { | |
| Log "${Reason}: ${Path} - DOES NOT EXIST" "WARN" | |
| } | |
| } | |
| Log "Cleanup started. DryRun=${DryRun}, Verbose=${Verbose}" "INFO" | |
| # π Recursively find and remove relative folders | |
| foreach ($dir in $DirList) { | |
| Log "Searching for '${dir}' folders recursively..." "INFO" | |
| Get-ChildItem -Directory -Recurse -Filter $dir -ErrorAction SilentlyContinue | ForEach-Object { | |
| Remove-Directory -Path $_.FullName -Reason "Recursive match" -DryRun:$DryRun | |
| } | |
| } | |
| # β Remove full path folders | |
| foreach ($path in $AdditionalDirList + $VsCodeDirs + $CacheDirs) { | |
| Remove-Directory -Path $path -Reason "Fixed path" -DryRun:$DryRun | |
| } | |
| # π§Ό NuGet cache | |
| Log "Clearing NuGet cache..." "INFO" | |
| if ($DryRun) { | |
| Log "NuGet cache: WOULD RUN 'nuget locals all -clear'" "ACTION" | |
| } else { | |
| try { | |
| nuget locals all -clear | Out-Null | |
| Log "NuGet cache cleared." "ACTION" | |
| } catch { | |
| Log "NuGet cache clear failed: $_" "ERROR" | |
| } | |
| } | |
| # π³ Docker cache | |
| Log "Cleaning Docker cache..." "INFO" | |
| if ($DryRun) { | |
| Log "Docker: WOULD RUN 'docker system prune -af'" "ACTION" | |
| } else { | |
| try { | |
| docker system prune -af | Out-Null | |
| Log "Docker cache cleaned." "ACTION" | |
| } catch { | |
| Log "Docker prune failed: $_" "ERROR" | |
| } | |
| } | |
| # π¦ npm cache | |
| Log "Cleaning npm cache..." "INFO" | |
| if ($DryRun) { | |
| Log "npm: WOULD RUN 'npm cache clean --force'" "ACTION" | |
| } else { | |
| try { | |
| npm cache clean --force | Out-Null | |
| Log "npm cache cleaned." "ACTION" | |
| } catch { | |
| Log "npm cache clean failed: $_" "ERROR" | |
| } | |
| } | |
| # β Execution time summary | |
| $EndTime = Get-Date | |
| $Duration = $EndTime - $StartTime | |
| Log "Cleanup completed in $(${Duration}.TotalSeconds) seconds." "INFO" | |
| # π₯οΈ HTML log generation | |
| $htmlContent = @" | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Cleanup Report</title> | |
| <style> | |
| body { font-family: Consolas, monospace; padding: 20px; background: #f9f9f9; } | |
| table { border-collapse: collapse; width: 100%; } | |
| th, td { padding: 8px 12px; border: 1px solid #ccc; } | |
| th { background-color: #f0f0f0; } | |
| .INFO { color: #333; } | |
| .WARN { color: orange; } | |
| .ERROR { color: red; font-weight: bold; } | |
| .ACTION { color: #2a7ae2; } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>π§Ή Cleanup Report</h2> | |
| <p><strong>Start Time:</strong> ${StartTime}<br> | |
| <strong>End Time:</strong> ${EndTime}<br> | |
| <strong>Duration:</strong> $([math]::Round(${Duration}.TotalSeconds, 2)) seconds<br> | |
| <strong>Dry Run:</strong> ${DryRun}<br> | |
| <strong>Verbose:</strong> ${Verbose}</p> | |
| <table> | |
| <tr><th>Time</th><th>Type</th><th>Message</th></tr> | |
| "@ | |
| foreach ($entry in $LogEntries) { | |
| $htmlContent += "<tr><td>$($entry.Time)</td><td class='$($entry.Type)'>$($entry.Type)</td><td>$($entry.Message)</td></tr>`n" | |
| } | |
| $htmlContent += @" | |
| </table> | |
| </body> | |
| </html> | |
| "@ | |
| $htmlContent | Out-File -Encoding UTF8 -FilePath $HtmlLog | |
| Log "HTML report written to ${HtmlLog}" "INFO" |
Author
guibranco
commented
Jul 1, 2025
| Command | Description |
|---|---|
| .\cleanup.ps1 | Run silent cleanup |
| .\cleanup.ps1 -Verbose | Cleanup with console output |
| .\cleanup.ps1 -DryRun -Verbose | Simulate cleanup (no deletions) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment