FocusedWolf

Windows 10+11?; Installer Cleaner.bat

Jul 19th, 2026 (edited)
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 6.79 KB | None | 0 0
  1. :: WARNING: This script deletes files to the recycle bin. You are responsible for reviewing the script,
  2. ::          understanding its function, and ensuring that important data is backed up before execution.
  3. ::          The author accepts no responsibility for data loss, system instability, or any other damages resulting from its use.
  4. ::
  5. :: WARNING: AI says i'm dumb for using this script, so probably not safe to use! (i use it though :D)
  6. ::          AI: "Windows Installer is complicated.
  7. ::               Microsoft does not guarantee that every file in C:\Windows\Installer is represented by a LocalPackage registry value.
  8. ::
  9. ::               Examples include:
  10. ::                   superseded patches
  11. ::                   rollback data
  12. ::                   servicing information
  13. ::                   repair scenarios
  14. ::                   vendor-specific installer behavior
  15. ::
  16. ::               Modern Windows servicing has become considerably more complex since this script was originally conceived.
  17. ::               Because of that, Microsoft's guidance has long been:
  18. ::               Don't manually clean the Windows Installer cache.
  19. ::               That's also why Microsoft never released an official 'clean orphaned installers' tool."
  20.  
  21. @echo off
  22. REM Version 14
  23. title Installer Cleaner
  24. color 05
  25.  
  26. :CheckPermissions
  27.     fltmc >nul 2>&1 || (
  28.         echo Requesting administrative privileges . . .
  29.         powershell -NoProfile -Command "$p=@{FilePath='%~f0';Verb='RunAs'};if('%*'){$p.ArgumentList='%*'};Start-Process @p" 2>nul
  30.         exit /b 0
  31.     )
  32.  
  33. REM SOURCE: https://ourrick.wordpress.com/2015/04/04/find-orphaned-installer-files-in-cwindowsinstaller-folder/    <-- NOTE: There is some major bugs in that script!
  34. REM Where i first learned of the script: https://sourceforge.net/p/patchcleaner/discussion/general/thread/73e4f56a/?limit=25
  35.  
  36. REM http://www.codeproject.com/Tips/119828/Running-a-bat-file-as-administrator-Correcting-cur
  37. setlocal enableextensions enabledelayedexpansion
  38. cd /d "%~dp0"
  39.  
  40. if /i "%~1" == "nopause" (
  41.     set "NOPAUSE=1"
  42. ) else (
  43.     set "NOPAUSE=0"
  44. )
  45.  
  46. if /i "%~2" == "purge" (
  47.     set "PURGE=Y"
  48. ) else (
  49.     set "PURGE=N"
  50. )
  51.  
  52. set "LOG_DIRECTORY=%~dp0Logs\"
  53.  
  54. set "FAILURE_TO_DELETE=0"
  55. set "MISSING_INSTALLER=0"
  56.  
  57. :Choice
  58.     if /i "%PURGE%" equ "Y" goto :Work
  59.     :PROMPT_ONE
  60.         cls
  61.         set "PURGE=N"
  62.         set /p PURGE=Delete orphaned installer files to Recycle Bin or just search for orphans? [y/N]:
  63.         if /i "%PURGE%" equ "Y" goto :Work
  64.         if /i "%PURGE%" equ "N" goto :Work
  65.         goto :PROMPT_ONE
  66.  
  67. :Work
  68.    REM Create intermediate directories for log directory if necessary.
  69.     if not exist "!LOG_DIRECTORY!" (
  70.         mkdir "!LOG_DIRECTORY!" 2>nul
  71.         if not exist "!LOG_DIRECTORY!" (
  72.             echo Directory could not be created: "!LOG_DIRECTORY!"
  73.             exit /b 1
  74.         )
  75.     )
  76.  
  77.     set TRACKED="!LOG_DIRECTORY!INSTALLER CLEANER - Tracked.log"
  78.     if exist %TRACKED% del %TRACKED%
  79.  
  80.     set MISSING="!LOG_DIRECTORY!INSTALLER CLEANER - Missing.log"
  81.     if exist %MISSING% del %MISSING%
  82.  
  83.     set ORPHANED="!LOG_DIRECTORY!INSTALLER CLEANER - Orphaned.log"
  84.     if exist %ORPHANED% del %ORPHANED%
  85.  
  86.     set INSTALLERS="!LOG_DIRECTORY!INSTALLER CLEANER - Installers.log"
  87.     if exist %INSTALLERS% del %INSTALLERS%
  88.  
  89.     echo Caching installer references...
  90.  
  91.     REM This will find both .msi and .msp entries.
  92.     set "KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData"
  93.     set "VALUE_NAME=LocalPackage"
  94.     for /f "usebackq tokens=1-2*" %%a in (`reg query "%KEY_NAME%" /s /v "%VALUE_NAME%" 2^>nul ^| findstr /i "%VALUE_NAME%"`) do (
  95.        REM Append installer path to file.
  96.         echo %%c>>%INSTALLERS%
  97.     )
  98.  
  99.     if not exist %INSTALLERS% (
  100.         echo.
  101.         echo ERROR: No LocalPackage entries were found under:
  102.         echo   %KEY_NAME%
  103.         echo This is almost certainly a failed registry read rather than a
  104.         echo genuinely empty installer cache. Aborting without touching
  105.         echo any files under %WINDIR%\Installer.
  106.         echo.
  107.         pause
  108.         goto :eof
  109.     )
  110.  
  111.     if /i "%PURGE%" equ "N" (
  112.         echo Looking for orphaned installers...
  113.     ) else (
  114.         echo Looking for orphaned installers to delete...
  115.     )
  116.  
  117.     for /f "delims=" %%a in ('dir /b /s %WINDIR%\Installer\*.msi %WINDIR%\Installer\*.msp') do (
  118.        REM Added /I flag (Specifies that the search is not to be case-sensitive) to fix issue where M$ inconsistently lists installer paths in: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData
  119.        REM The LocalPackage key can contain upper and lower-case variations, e.g.
  120.        REM     c:\Windows\Installer\177be02.msp
  121.        REM     C:\Windows\Installer\32dc90.msi
  122.        REM Its bad because a file can be incorrectly classified as orphaned because findstr is case-sensitive by default.
  123.         findstr /i /c:"%%a" %INSTALLERS% >nul
  124.  
  125.         if !errorlevel! equ 1 (
  126.             echo "%%a" ORPHANED>>%ORPHANED%
  127.             echo "%%a" ORPHANED
  128.  
  129.             if /i "%PURGE%" equ "Y" (
  130.                REM del "%%a"
  131.                REM
  132.                REM Send orphaned installer files to the Recycle Bin instead of permanently deleting them.
  133.                 powershell.exe -NoProfile -Command "Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('%%a', [Microsoft.VisualBasic.FileIO.UIOption]::OnlyErrorDialogs, [Microsoft.VisualBasic.FileIO.RecycleOption]::SendToRecycleBin)"
  134.  
  135.                 if exist "%%a" (
  136.                     echo FAILED to recycle - %%a
  137.                     set FAILURE_TO_DELETE=1
  138.                 ) else (
  139.                     echo Deleted orphaned installer - %%a
  140.                 )
  141.             )
  142.         ) else (
  143.             echo "%%a" TRACKED>>%TRACKED%
  144.         )
  145.     )
  146.  
  147.     echo Looking for missing installers...
  148.  
  149.     for /f "delims=" %%a in ('type %INSTALLERS%') do (
  150.         if not exist "%%a" (
  151.             echo "%%a" MISSING>>%MISSING%
  152.             echo "%%a" MISSING
  153.             set MISSING_INSTALLER=1
  154.         )
  155.     )
  156.  
  157. :End
  158.     if %FAILURE_TO_DELETE% equ 1 pause
  159.     if %MISSING_INSTALLER% equ 1 (
  160.         echo -----
  161.         echo Search this registry key with the installer path to determine its DisplayName:
  162.         echo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData
  163.         echo Find an installer online with that name and download it.
  164.         echo Your looking for installers that offer a Repair option the first time you run them.
  165.         echo Click Repair, click Browse to find the vc_red.msi file, and click Ok to reinstall.
  166.         echo -----
  167.         pause
  168.     )
  169.  
  170.     if %NOPAUSE% equ 0 (
  171.         pause
  172.     ) else (
  173.         timeout /t 7 /nobreak
  174.     )
  175.     goto :eof
Advertisement
Add Comment
Please, Sign In to add comment