Free your system of garbage. With this customziable script you can cleanup your system and remove large files, duplicates, old and used files, remove empty folders and even find duplicates of archives.
This script is provided "as is", without warranty of any kind. Use at your own risk. The author assumes no responsibility or liability for any loss, damage, or other problems that may arise from the use, misuse, or inability to use this script. Always review and test the script in a safe environment before running it on important data.
It is strongly recommended to perform regular backups of your data to prevent any dataloss.
- Define the directory which you want to clean. You may also specify a maximum recursion depth, if you would like to avoid subfolders or to decrease the amount of data.
- Specify a maximum file age or size. Any files larger / older than specified will be removed.
- Specify a maximum folder size. If specified, the size of each folder is calculated and if larger than the threshold removed.
- Check for empty folders. If an empty folder is found, it will be removed.
- Check for duplicate files. For more details see -CheckForDuplicates.
- Check for duplicate archives. Fore more details see -CheckForDuplicateArchives.
- Option to make the script resumable. Fore more details see -Resumable.
Start-LitterPicking.ps1
-LitterOrigin <DirectoryInfo>
[[-Depth] <short>]
[[-MaximumFileSize] <ulong>]
[[-MaximumFolderSize] <ulong>]
[[-MaximumFileWriteTime] <timespan>]
[-RemoveEmptyFolders]
[-CheckForDuplicates]
[-CheckForDuplicateArchives]
[-Resumable]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
Folder to clean up. Can also be a string which will be automatically cast to the expected DirectoryInfo type.
| Type: | DirectoryInfo |
|---|---|
| Default value: | None |
| Required: | True |
| Accept pipeline input: | True |
| Accept wildcard characters: | False |
Recursion depth. -1 means unlimited depth. Only accepts values equal or greater than -1.
Cann be specified to avoid subfolders or to decrease the amount of data that will be checked.
| Type: | Int16 |
|---|---|
| Default value: | -1 |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Maximum file size in bytes. Use PowerShell's suffixes to specify the size (e.g. 1MB, 10GB).
Any files larger than specified will be removed.
| Type: | UInt64 |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Maximum folder size in bytes. Use PowerShell's suffixes to specify the size (e.g. 1MB, 10GB).
The size of each folder is calculated and if larger than the threshold removed.
| Type: | UInt64 |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Maximum file write time specified as a TimeSpan. The timespan can either be created using the command New-TimeSpan or PowerShell is also able to create a timespan from a string, e.g. "30:0:0:0".
"30:0:0:0"
^ ^ ^ ^
| | | Seconds
| | Minutes
| Hours
Days
| Type: | TimeSpan |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Remove empty folders.
| Type: | SwitchParameter |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Check for duplicate files.
A SHA256 file hash is calculated of every file encountered. At the end a prompt is shown for each duplicate which allows for examining / keeping / removing the file. This will only find exact matches.
| Type: | SwitchParameter |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Check for duplicate archives.
If an archive (.zip, .rar, .7z, .tar or .gz) is found, the contents of the archive are listed and compared to data in the same directory and the first level of subdirectories of the archive itself.
The check only compares the path of a file in the archive to the path relative to the archive. If any matches are found, the user is prompted to choose an action for the possible matches / the archive. Again, it will only check the path, it will not compare the contents of the matches.
| Type: | SwitchParameter |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
Resumable mode.
If the execution fails for any reason or you want to continue at a later time (depending on the options, the script can run for a very long time), the script will remember all files and paths it has already checked once and will not recheck them. If you resume the script and have changed files or the contents of folders the script has already delt with, they will not be rechecked.
The location of the file used as "memory" is %TEMP%\UnvoluntaryLitterPicking_Resumable.txt.
| Type: | SwitchParameter |
|---|---|
| Default value: | None |
| Required: | False |
| Accept pipeline input: | False |
| Accept wildcard characters: | False |
- Add terminal bell if user interaction is required ([Console]::Beep(), check in PowerShell. VS Code seems to surpress the sound)
- Archive match removal: Option to specify regex for matching. For example if its obvious all files are in a subfolder, specify that folder to be deleted and avoid any similar files that might be in other subdirectories
- Archive matching: Option to compare file content.
- Option to use recycling bin
- Add blocklist to skip specific paths (could leverage resumable functionality)
- Investigate "End of Central Directory record could not be found" error when removing archives
- Multi-Threading. Execution order is important. When offloading tasks / running them in the background, the script can no longer ensure correct checks. For example the empty folder check might fail if the user is prompted for the deletion of a singular file in a folder but while waiting for the users interaction the script already continues onto the empty folder check which, at that moment, would not be empty.