windowsweep 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-INTEGRATION-GUIDE.md +203 -0
- package/CHANGELOG.md +124 -0
- package/LICENSE +21 -21
- package/README.md +88 -49
- package/VERSION +1 -1
- package/lib/actions.ps1 +212 -209
- package/lib/config.ps1 +108 -99
- package/lib/constants.ps1 +103 -89
- package/lib/fs.ps1 +189 -180
- package/lib/log.ps1 +140 -140
- package/lib/safety.ps1 +541 -493
- package/lib/scan.ps1 +109 -94
- package/lib/ui.ps1 +275 -235
- package/modules/android_avd.ps1 +36 -36
- package/modules/app_caches.ps1 +58 -58
- package/modules/browsers.ps1 +33 -33
- package/modules/build_tools.ps1 +35 -35
- package/modules/crash_trap.ps1 +89 -89
- package/modules/disk_usage.ps1 +49 -49
- package/modules/docker.ps1 +93 -93
- package/modules/editors.ps1 +150 -150
- package/modules/globals_audit.ps1 +236 -0
- package/modules/health.ps1 +101 -101
- package/modules/installed_programs.ps1 +118 -0
- package/modules/menu.ps1 +63 -61
- package/modules/notify.ps1 +60 -0
- package/modules/orphaned_appdata.ps1 +189 -0
- package/modules/personal.ps1 +126 -124
- package/modules/pkg_managers.ps1 +73 -69
- package/modules/projects.ps1 +160 -143
- package/modules/release_helpers.ps1 +438 -434
- package/modules/reports.ps1 +212 -212
- package/modules/runner.ps1 +242 -190
- package/modules/self_test_extra.ps1 +537 -86
- package/modules/startup_audit.ps1 +126 -0
- package/modules/system_admin.ps1 +220 -220
- package/modules/test_runners.ps1 +24 -24
- package/modules/walkthrough.ps1 +80 -79
- package/modules/windows_user.ps1 +118 -112
- package/package.json +4 -3
- package/windowsweep.ps1 +322 -296
package/modules/app_caches.ps1
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# app_caches.ps1 - section 8: desktop-app caches (Electron / Chromium-based apps) and superseded Squirrel versions.
|
|
2
|
-
|
|
3
|
-
function Get-Targets08 {
|
|
4
|
-
$P = $Script:P
|
|
5
|
-
return @(
|
|
6
|
-
(New-Target 8 'Discord' "$($P.A)\discord" -Kind electron -Guard @('Discord'))
|
|
7
|
-
(New-Target 8 'Discord Canary' "$($P.A)\discordcanary" -Kind electron -Guard @('DiscordCanary'))
|
|
8
|
-
(New-Target 8 'Discord PTB' "$($P.A)\discordptb" -Kind electron -Guard @('DiscordPTB'))
|
|
9
|
-
(New-Target 8 'Slack' "$($P.A)\Slack" -Kind electron -Guard @('slack'))
|
|
10
|
-
(New-Target 8 'Slack (Store)' "$($P.L)\Packages\*slack*\LocalCache\Roaming\Slack" -Kind electron -Guard @('slack'))
|
|
11
|
-
(New-Target 8 'Microsoft Teams (classic)' "$($P.A)\Microsoft\Teams" -Kind electron -Guard @('Teams'))
|
|
12
|
-
(New-Target 8 'Microsoft Teams (new)' "$($P.L)\Packages\MSTeams_*\LocalCache\Microsoft\MSTeams\EBWebView\*" -Kind chromium -Guard @('ms-teams'))
|
|
13
|
-
(New-Target 8 'Zoom logs' "$($P.A)\Zoom\logs" -Mode clear-old -Days 30 -Guard @('Zoom'))
|
|
14
|
-
(New-Target 8 'Spotify streaming cache' "$($P.L)\Spotify\Storage" -Mode clear -Guard @('Spotify'))
|
|
15
|
-
(New-Target 8 'Spotify (Store) streaming cache' "$($P.L)\Packages\SpotifyAB.SpotifyMusic_*\LocalCache\Spotify\Storage" -Kind glob -Mode clear -Guard @('Spotify'))
|
|
16
|
-
(New-Target 8 'Postman' "$($P.A)\Postman" -Kind electron -Guard @('Postman'))
|
|
17
|
-
(New-Target 8 'Figma' "$($P.A)\Figma" -Kind electron -Guard @('Figma'))
|
|
18
|
-
(New-Target 8 'Notion' "$($P.A)\Notion" -Kind electron -Guard @('Notion'))
|
|
19
|
-
(New-Target 8 'Signal' "$($P.A)\Signal" -Kind electron -Guard @('Signal'))
|
|
20
|
-
(New-Target 8 'Skype' "$($P.A)\Microsoft\Skype for Desktop" -Kind electron -Guard @('Skype'))
|
|
21
|
-
(New-Target 8 'GitHub Desktop' "$($P.A)\GitHub Desktop" -Kind electron -Guard @('GitHubDesktop'))
|
|
22
|
-
(New-Target 8 'Obsidian' "$($P.A)\obsidian" -Kind electron -Guard @('Obsidian'))
|
|
23
|
-
(New-Target 8 'Claude desktop app' "$($P.A)\Claude" -Kind electron -Guard @('Claude'))
|
|
24
|
-
(New-Target 8 'Linear' "$($P.A)\Linear" -Kind electron -Guard @('Linear'))
|
|
25
|
-
(New-Target 8 'Granola' "$($P.A)\Granola" -Kind electron -Guard @('Granola'))
|
|
26
|
-
(New-Target 8 'Insomnia' "$($P.A)\Insomnia" -Kind electron -Guard @('Insomnia'))
|
|
27
|
-
(New-Target 8 'Steam web cache' "$($P.L)\Steam\htmlcache" -Mode clear -Guard @('steam'))
|
|
28
|
-
(New-Target 8 'Epic Games Launcher web cache' "$($P.L)\EpicGamesLauncher\Saved\webcache*" -Kind glob -Mode clear -Guard @('EpicGamesLauncher'))
|
|
29
|
-
(New-Target 8 'Epic Games Launcher logs' "$($P.L)\EpicGamesLauncher\Saved\Logs" -Mode clear-old -Days 30)
|
|
30
|
-
(New-Target 8 'Adobe media cache files' "$($P.A)\Adobe\Common\Media Cache Files" -Mode prune -Guard @('Adobe Premiere Pro', 'AfterFX', 'Adobe Audition') -Note 'Premiere / After Effects rebuild them on open')
|
|
31
|
-
(New-Target 8 'Adobe media cache database' "$($P.A)\Adobe\Common\Media Cache" -Mode prune -Guard @('Adobe Premiere Pro', 'AfterFX', 'Adobe Audition'))
|
|
32
|
-
(New-Target 8 'OBS Studio logs' "$($P.A)\obs-studio\logs" -Mode clear-old -Days 30)
|
|
33
|
-
(New-Target 8 'OBS Studio crash reports' "$($P.A)\obs-studio\crashes" -Mode clear-old -Days 30)
|
|
34
|
-
(New-Target 8 'Squirrel installer temp' "$($P.L)\SquirrelTemp" -Mode clear)
|
|
35
|
-
(New-Target 8 'Electron updater downloads' "$($P.L)\@*-updater" -Kind glob -Mode clear-old -Days 7 -Note 'pending update installers older than a week')
|
|
36
|
-
(New-Target 8 'Discord superseded versions' "$($P.L)\Discord" -Kind cmd -Guard @('Discord') -Note 'app-x.y.z folders other than the newest')
|
|
37
|
-
(New-Target 8 'Postman superseded versions' "$($P.L)\Postman" -Kind cmd -Guard @('Postman'))
|
|
38
|
-
(New-Target 8 'Figma superseded versions' "$($P.L)\Figma" -Kind cmd -Guard @('Figma'))
|
|
39
|
-
(New-Target 8 'GitHub Desktop superseded versions' "$($P.L)\GitHubDesktop" -Kind cmd -Guard @('GitHubDesktop'))
|
|
40
|
-
(New-Target 8 'Slack superseded versions' "$($P.L)\slack" -Kind cmd -Guard @('slack'))
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function Invoke-Section08 {
|
|
45
|
-
Write-SectionIntro @(
|
|
46
|
-
'Chat, design and API apps are browsers in disguise: their Cache, Code Cache and GPU caches rebuild on the next',
|
|
47
|
-
'start, and installers that keep old app-x.y.z versions beside the current one waste space. Accounts, chat',
|
|
48
|
-
'databases and settings are never touched; a running app is skipped.'
|
|
49
|
-
)
|
|
50
|
-
$targets = Get-Targets08
|
|
51
|
-
$null = Show-TargetSizes @($targets | Where-Object { $_.Kind -ne 'cmd' })
|
|
52
|
-
if (-not (Confirm-Section 'Clean desktop-app caches now?')) { Write-Info 'skipped'; return }
|
|
53
|
-
$null = Invoke-TargetList @($targets | Where-Object { $_.Kind -ne 'cmd' })
|
|
54
|
-
foreach ($t in @($targets | Where-Object { $_.Kind -eq 'cmd' })) {
|
|
55
|
-
if (-not (Test-DirPresent $t.Path)) { continue }
|
|
56
|
-
$null = Remove-SupersededVersions -Root $t.Path -Guard $t.Guard -Label $t.Label
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
# app_caches.ps1 - section 8: desktop-app caches (Electron / Chromium-based apps) and superseded Squirrel versions.
|
|
2
|
+
|
|
3
|
+
function Get-Targets08 {
|
|
4
|
+
$P = $Script:P
|
|
5
|
+
return @(
|
|
6
|
+
(New-Target 8 'Discord' "$($P.A)\discord" -Kind electron -Guard @('Discord'))
|
|
7
|
+
(New-Target 8 'Discord Canary' "$($P.A)\discordcanary" -Kind electron -Guard @('DiscordCanary'))
|
|
8
|
+
(New-Target 8 'Discord PTB' "$($P.A)\discordptb" -Kind electron -Guard @('DiscordPTB'))
|
|
9
|
+
(New-Target 8 'Slack' "$($P.A)\Slack" -Kind electron -Guard @('slack'))
|
|
10
|
+
(New-Target 8 'Slack (Store)' "$($P.L)\Packages\*slack*\LocalCache\Roaming\Slack" -Kind electron -Guard @('slack'))
|
|
11
|
+
(New-Target 8 'Microsoft Teams (classic)' "$($P.A)\Microsoft\Teams" -Kind electron -Guard @('Teams'))
|
|
12
|
+
(New-Target 8 'Microsoft Teams (new)' "$($P.L)\Packages\MSTeams_*\LocalCache\Microsoft\MSTeams\EBWebView\*" -Kind chromium -Guard @('ms-teams'))
|
|
13
|
+
(New-Target 8 'Zoom logs' "$($P.A)\Zoom\logs" -Mode clear-old -Days 30 -Guard @('Zoom'))
|
|
14
|
+
(New-Target 8 'Spotify streaming cache' "$($P.L)\Spotify\Storage" -Mode clear -Guard @('Spotify'))
|
|
15
|
+
(New-Target 8 'Spotify (Store) streaming cache' "$($P.L)\Packages\SpotifyAB.SpotifyMusic_*\LocalCache\Spotify\Storage" -Kind glob -Mode clear -Guard @('Spotify'))
|
|
16
|
+
(New-Target 8 'Postman' "$($P.A)\Postman" -Kind electron -Guard @('Postman'))
|
|
17
|
+
(New-Target 8 'Figma' "$($P.A)\Figma" -Kind electron -Guard @('Figma'))
|
|
18
|
+
(New-Target 8 'Notion' "$($P.A)\Notion" -Kind electron -Guard @('Notion'))
|
|
19
|
+
(New-Target 8 'Signal' "$($P.A)\Signal" -Kind electron -Guard @('Signal'))
|
|
20
|
+
(New-Target 8 'Skype' "$($P.A)\Microsoft\Skype for Desktop" -Kind electron -Guard @('Skype'))
|
|
21
|
+
(New-Target 8 'GitHub Desktop' "$($P.A)\GitHub Desktop" -Kind electron -Guard @('GitHubDesktop'))
|
|
22
|
+
(New-Target 8 'Obsidian' "$($P.A)\obsidian" -Kind electron -Guard @('Obsidian'))
|
|
23
|
+
(New-Target 8 'Claude desktop app' "$($P.A)\Claude" -Kind electron -Guard @('Claude'))
|
|
24
|
+
(New-Target 8 'Linear' "$($P.A)\Linear" -Kind electron -Guard @('Linear'))
|
|
25
|
+
(New-Target 8 'Granola' "$($P.A)\Granola" -Kind electron -Guard @('Granola'))
|
|
26
|
+
(New-Target 8 'Insomnia' "$($P.A)\Insomnia" -Kind electron -Guard @('Insomnia'))
|
|
27
|
+
(New-Target 8 'Steam web cache' "$($P.L)\Steam\htmlcache" -Mode clear -Guard @('steam'))
|
|
28
|
+
(New-Target 8 'Epic Games Launcher web cache' "$($P.L)\EpicGamesLauncher\Saved\webcache*" -Kind glob -Mode clear -Guard @('EpicGamesLauncher'))
|
|
29
|
+
(New-Target 8 'Epic Games Launcher logs' "$($P.L)\EpicGamesLauncher\Saved\Logs" -Mode clear-old -Days 30)
|
|
30
|
+
(New-Target 8 'Adobe media cache files' "$($P.A)\Adobe\Common\Media Cache Files" -Mode prune -Guard @('Adobe Premiere Pro', 'AfterFX', 'Adobe Audition') -Note 'Premiere / After Effects rebuild them on open')
|
|
31
|
+
(New-Target 8 'Adobe media cache database' "$($P.A)\Adobe\Common\Media Cache" -Mode prune -Guard @('Adobe Premiere Pro', 'AfterFX', 'Adobe Audition'))
|
|
32
|
+
(New-Target 8 'OBS Studio logs' "$($P.A)\obs-studio\logs" -Mode clear-old -Days 30)
|
|
33
|
+
(New-Target 8 'OBS Studio crash reports' "$($P.A)\obs-studio\crashes" -Mode clear-old -Days 30)
|
|
34
|
+
(New-Target 8 'Squirrel installer temp' "$($P.L)\SquirrelTemp" -Mode clear)
|
|
35
|
+
(New-Target 8 'Electron updater downloads' "$($P.L)\@*-updater" -Kind glob -Mode clear-old -Days 7 -Note 'pending update installers older than a week')
|
|
36
|
+
(New-Target 8 'Discord superseded versions' "$($P.L)\Discord" -Kind cmd -Guard @('Discord') -Note 'app-x.y.z folders other than the newest')
|
|
37
|
+
(New-Target 8 'Postman superseded versions' "$($P.L)\Postman" -Kind cmd -Guard @('Postman'))
|
|
38
|
+
(New-Target 8 'Figma superseded versions' "$($P.L)\Figma" -Kind cmd -Guard @('Figma'))
|
|
39
|
+
(New-Target 8 'GitHub Desktop superseded versions' "$($P.L)\GitHubDesktop" -Kind cmd -Guard @('GitHubDesktop'))
|
|
40
|
+
(New-Target 8 'Slack superseded versions' "$($P.L)\slack" -Kind cmd -Guard @('slack'))
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function Invoke-Section08 {
|
|
45
|
+
Write-SectionIntro @(
|
|
46
|
+
'Chat, design and API apps are browsers in disguise: their Cache, Code Cache and GPU caches rebuild on the next',
|
|
47
|
+
'start, and installers that keep old app-x.y.z versions beside the current one waste space. Accounts, chat',
|
|
48
|
+
'databases and settings are never touched; a running app is skipped.'
|
|
49
|
+
)
|
|
50
|
+
$targets = Get-Targets08
|
|
51
|
+
$null = Show-TargetSizes @($targets | Where-Object { $_.Kind -ne 'cmd' })
|
|
52
|
+
if (-not (Confirm-Section 'Clean desktop-app caches now?')) { Write-Info 'skipped'; return }
|
|
53
|
+
$null = Invoke-TargetList @($targets | Where-Object { $_.Kind -ne 'cmd' })
|
|
54
|
+
foreach ($t in @($targets | Where-Object { $_.Kind -eq 'cmd' })) {
|
|
55
|
+
if (-not (Test-DirPresent $t.Path)) { continue }
|
|
56
|
+
$null = Remove-SupersededVersions -Root $t.Path -Guard $t.Guard -Label $t.Label
|
|
57
|
+
}
|
|
58
|
+
}
|
package/modules/browsers.ps1
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
# browsers.ps1 - section 7: browser caches for every profile. Profile data is never touched.
|
|
2
|
-
|
|
3
|
-
function Get-Targets07 {
|
|
4
|
-
$P = $Script:P
|
|
5
|
-
return @(
|
|
6
|
-
(New-Target 7 'Google Chrome' "$($P.L)\Google\Chrome\User Data" -Kind chromium -Guard @('chrome') -Note 'cache folders of every profile')
|
|
7
|
-
(New-Target 7 'Google Chrome Beta' "$($P.L)\Google\Chrome Beta\User Data" -Kind chromium -Guard @('chrome'))
|
|
8
|
-
(New-Target 7 'Google Chrome Dev' "$($P.L)\Google\Chrome Dev\User Data" -Kind chromium -Guard @('chrome'))
|
|
9
|
-
(New-Target 7 'Google Chrome Canary' "$($P.L)\Google\Chrome SxS\User Data" -Kind chromium -Guard @('chrome'))
|
|
10
|
-
(New-Target 7 'Microsoft Edge' "$($P.L)\Microsoft\Edge\User Data" -Kind chromium -Guard @('msedge'))
|
|
11
|
-
(New-Target 7 'Brave' "$($P.L)\BraveSoftware\Brave-Browser\User Data" -Kind chromium -Guard @('brave'))
|
|
12
|
-
(New-Target 7 'Vivaldi' "$($P.L)\Vivaldi\User Data" -Kind chromium -Guard @('vivaldi'))
|
|
13
|
-
(New-Target 7 'Opera' "$($P.A)\Opera Software\Opera Stable" -Kind chromium -Guard @('opera'))
|
|
14
|
-
(New-Target 7 'Opera GX' "$($P.A)\Opera Software\Opera GX Stable" -Kind chromium -Guard @('opera'))
|
|
15
|
-
(New-Target 7 'Chromium' "$($P.L)\Chromium\User Data" -Kind chromium -Guard @('chrome', 'chromium'))
|
|
16
|
-
(New-Target 7 'Arc' "$($P.L)\Packages\TheBrowserCompany.Arc_*\LocalCache\Local\Arc\User Data" -Kind chromium -Guard @('Arc'))
|
|
17
|
-
(New-Target 7 'Firefox' "$($P.L)\Mozilla\Firefox\Profiles" -Kind firefox -Guard @('firefox') -Note 'cache2, startupCache, thumbnails, jumpListCache')
|
|
18
|
-
(New-Target 7 'LibreWolf' "$($P.L)\LibreWolf\Profiles" -Kind firefox -Guard @('librewolf'))
|
|
19
|
-
(New-Target 7 'Waterfox' "$($P.L)\Waterfox\Profiles" -Kind firefox -Guard @('waterfox'))
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function Invoke-Section07 {
|
|
24
|
-
Write-SectionIntro @(
|
|
25
|
-
'Browser caches rebuild as you browse; the first page loads afterwards are a little slower. Cookies, logins,',
|
|
26
|
-
'history, bookmarks, extensions, Local Storage, IndexedDB and PWA CacheStorage are never touched.',
|
|
27
|
-
'A browser that is open right now is skipped - close it and run this section again.'
|
|
28
|
-
)
|
|
29
|
-
$targets = Get-Targets07
|
|
30
|
-
$null = Show-TargetSizes $targets
|
|
31
|
-
if (-not (Confirm-Section 'Clear browser caches now?')) { Write-Info 'skipped'; return }
|
|
32
|
-
$null = Invoke-TargetList $targets
|
|
33
|
-
}
|
|
1
|
+
# browsers.ps1 - section 7: browser caches for every profile. Profile data is never touched.
|
|
2
|
+
|
|
3
|
+
function Get-Targets07 {
|
|
4
|
+
$P = $Script:P
|
|
5
|
+
return @(
|
|
6
|
+
(New-Target 7 'Google Chrome' "$($P.L)\Google\Chrome\User Data" -Kind chromium -Guard @('chrome') -Note 'cache folders of every profile')
|
|
7
|
+
(New-Target 7 'Google Chrome Beta' "$($P.L)\Google\Chrome Beta\User Data" -Kind chromium -Guard @('chrome'))
|
|
8
|
+
(New-Target 7 'Google Chrome Dev' "$($P.L)\Google\Chrome Dev\User Data" -Kind chromium -Guard @('chrome'))
|
|
9
|
+
(New-Target 7 'Google Chrome Canary' "$($P.L)\Google\Chrome SxS\User Data" -Kind chromium -Guard @('chrome'))
|
|
10
|
+
(New-Target 7 'Microsoft Edge' "$($P.L)\Microsoft\Edge\User Data" -Kind chromium -Guard @('msedge'))
|
|
11
|
+
(New-Target 7 'Brave' "$($P.L)\BraveSoftware\Brave-Browser\User Data" -Kind chromium -Guard @('brave'))
|
|
12
|
+
(New-Target 7 'Vivaldi' "$($P.L)\Vivaldi\User Data" -Kind chromium -Guard @('vivaldi'))
|
|
13
|
+
(New-Target 7 'Opera' "$($P.A)\Opera Software\Opera Stable" -Kind chromium -Guard @('opera'))
|
|
14
|
+
(New-Target 7 'Opera GX' "$($P.A)\Opera Software\Opera GX Stable" -Kind chromium -Guard @('opera'))
|
|
15
|
+
(New-Target 7 'Chromium' "$($P.L)\Chromium\User Data" -Kind chromium -Guard @('chrome', 'chromium'))
|
|
16
|
+
(New-Target 7 'Arc' "$($P.L)\Packages\TheBrowserCompany.Arc_*\LocalCache\Local\Arc\User Data" -Kind chromium -Guard @('Arc'))
|
|
17
|
+
(New-Target 7 'Firefox' "$($P.L)\Mozilla\Firefox\Profiles" -Kind firefox -Guard @('firefox') -Note 'cache2, startupCache, thumbnails, jumpListCache')
|
|
18
|
+
(New-Target 7 'LibreWolf' "$($P.L)\LibreWolf\Profiles" -Kind firefox -Guard @('librewolf'))
|
|
19
|
+
(New-Target 7 'Waterfox' "$($P.L)\Waterfox\Profiles" -Kind firefox -Guard @('waterfox'))
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function Invoke-Section07 {
|
|
24
|
+
Write-SectionIntro @(
|
|
25
|
+
'Browser caches rebuild as you browse; the first page loads afterwards are a little slower. Cookies, logins,',
|
|
26
|
+
'history, bookmarks, extensions, Local Storage, IndexedDB and PWA CacheStorage are never touched.',
|
|
27
|
+
'A browser that is open right now is skipped - close it and run this section again.'
|
|
28
|
+
)
|
|
29
|
+
$targets = Get-Targets07
|
|
30
|
+
$null = Show-TargetSizes $targets
|
|
31
|
+
if (-not (Confirm-Section 'Clear browser caches now?')) { Write-Info 'skipped'; return }
|
|
32
|
+
$null = Invoke-TargetList $targets
|
|
33
|
+
}
|
package/modules/build_tools.ps1
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
# build_tools.ps1 - section 2: build-tool caches (Gradle, Maven, Android, Unity, JetBrains).
|
|
2
|
-
|
|
3
|
-
function Get-Targets02 {
|
|
4
|
-
$P = $Script:P
|
|
5
|
-
return @(
|
|
6
|
-
(New-Target 2 'Gradle caches' "$($P.U)\.gradle\caches" -Mode prune -Dev $true -Note 'Gradle re-downloads what a build needs')
|
|
7
|
-
(New-Target 2 'Gradle wrapper distributions' "$($P.U)\.gradle\wrapper\dists" -Mode units -Dev $true -KeepNewest $true -Note 'the newest distribution is always kept')
|
|
8
|
-
(New-Target 2 'Gradle daemon logs' "$($P.U)\.gradle\daemon" -Mode prune -Days 7)
|
|
9
|
-
(New-Target 2 'Gradle temp' "$($P.U)\.gradle\.tmp" -Mode clear)
|
|
10
|
-
(New-Target 2 'Maven local repository' "$($P.U)\.m2\repository" -Mode prune -Dev $true -Note 'restored by the next mvn build')
|
|
11
|
-
(New-Target 2 'Android SDK manager cache' "$($P.U)\.android\cache" -Mode clear)
|
|
12
|
-
(New-Target 2 'Android build cache' "$($P.U)\.android\build-cache" -Mode prune -Dev $true)
|
|
13
|
-
(New-Target 2 'Android SDK temp' "$($P.L)\Android\Sdk\.temp" -Mode clear)
|
|
14
|
-
(New-Target 2 'Android SDK download leftovers' "$($P.L)\Android\Sdk\.downloadIntermediates" -Mode clear)
|
|
15
|
-
(New-Target 2 'Unity cache' "$($P.L)\Unity\cache" -Mode prune -Dev $true)
|
|
16
|
-
(New-Target 2 'JetBrains IDE caches (idle IDE versions)' "$($P.L)\JetBrains" -Mode units -Dev $true -ExcludeNames @('Toolbox') -Note 'a whole IDE version idle N+ days; the Toolbox itself is protected')
|
|
17
|
-
(New-Target 2 '.NET telemetry storage' "$($P.U)\.dotnet\TelemetryStorageService" -Mode clear)
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function Invoke-Section02 {
|
|
22
|
-
Write-SectionIntro @(
|
|
23
|
-
'Build caches are re-created by the next build. In developer mode only idle files go, so a project you',
|
|
24
|
-
'compiled last week keeps its warm cache. JetBrains caches are removed per IDE version, only when that whole',
|
|
25
|
-
'version has been idle for the window (an IDE you no longer run).'
|
|
26
|
-
) -Dev $true
|
|
27
|
-
$targets = Get-Targets02
|
|
28
|
-
$null = Show-TargetSizes $targets
|
|
29
|
-
if (-not (Confirm-Section 'Prune build-tool caches now?')) { Write-Info 'skipped'; return }
|
|
30
|
-
if ((Test-CommandPresent 'gradle') -and -not $Script:WS.DryRun) {
|
|
31
|
-
$null = Invoke-External -FilePath 'gradle' -ArgumentList @('--stop') -Quiet -Label 'gradle --stop'
|
|
32
|
-
Write-Note 'stopped idle Gradle daemons so their caches are not locked'
|
|
33
|
-
}
|
|
34
|
-
$null = Invoke-TargetList $targets
|
|
35
|
-
}
|
|
1
|
+
# build_tools.ps1 - section 2: build-tool caches (Gradle, Maven, Android, Unity, JetBrains).
|
|
2
|
+
|
|
3
|
+
function Get-Targets02 {
|
|
4
|
+
$P = $Script:P
|
|
5
|
+
return @(
|
|
6
|
+
(New-Target 2 'Gradle caches' "$($P.U)\.gradle\caches" -Mode prune -Dev $true -Note 'Gradle re-downloads what a build needs')
|
|
7
|
+
(New-Target 2 'Gradle wrapper distributions' "$($P.U)\.gradle\wrapper\dists" -Mode units -Dev $true -KeepNewest $true -Note 'the newest distribution is always kept')
|
|
8
|
+
(New-Target 2 'Gradle daemon logs' "$($P.U)\.gradle\daemon" -Mode prune -Days 7)
|
|
9
|
+
(New-Target 2 'Gradle temp' "$($P.U)\.gradle\.tmp" -Mode clear)
|
|
10
|
+
(New-Target 2 'Maven local repository' "$($P.U)\.m2\repository" -Mode prune -Dev $true -Note 'restored by the next mvn build')
|
|
11
|
+
(New-Target 2 'Android SDK manager cache' "$($P.U)\.android\cache" -Mode clear)
|
|
12
|
+
(New-Target 2 'Android build cache' "$($P.U)\.android\build-cache" -Mode prune -Dev $true)
|
|
13
|
+
(New-Target 2 'Android SDK temp' "$($P.L)\Android\Sdk\.temp" -Mode clear)
|
|
14
|
+
(New-Target 2 'Android SDK download leftovers' "$($P.L)\Android\Sdk\.downloadIntermediates" -Mode clear)
|
|
15
|
+
(New-Target 2 'Unity cache' "$($P.L)\Unity\cache" -Mode prune -Dev $true)
|
|
16
|
+
(New-Target 2 'JetBrains IDE caches (idle IDE versions)' "$($P.L)\JetBrains" -Mode units -Dev $true -ExcludeNames @('Toolbox') -Note 'a whole IDE version idle N+ days; the Toolbox itself is protected')
|
|
17
|
+
(New-Target 2 '.NET telemetry storage' "$($P.U)\.dotnet\TelemetryStorageService" -Mode clear)
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function Invoke-Section02 {
|
|
22
|
+
Write-SectionIntro @(
|
|
23
|
+
'Build caches are re-created by the next build. In developer mode only idle files go, so a project you',
|
|
24
|
+
'compiled last week keeps its warm cache. JetBrains caches are removed per IDE version, only when that whole',
|
|
25
|
+
'version has been idle for the window (an IDE you no longer run).'
|
|
26
|
+
) -Dev $true
|
|
27
|
+
$targets = Get-Targets02
|
|
28
|
+
$null = Show-TargetSizes $targets
|
|
29
|
+
if (-not (Confirm-Section 'Prune build-tool caches now?')) { Write-Info 'skipped'; return }
|
|
30
|
+
if ((Test-CommandPresent 'gradle') -and -not $Script:WS.DryRun) {
|
|
31
|
+
$null = Invoke-External -FilePath 'gradle' -ArgumentList @('--stop') -Quiet -Label 'gradle --stop'
|
|
32
|
+
Write-Note 'stopped idle Gradle daemons so their caches are not locked'
|
|
33
|
+
}
|
|
34
|
+
$null = Invoke-TargetList $targets
|
|
35
|
+
}
|
package/modules/crash_trap.ps1
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
# crash_trap.ps1 - on an unexpected error, bundle the log + latest report + a manifest into a local zip.
|
|
2
|
-
# Nothing is ever sent anywhere; the user decides whether to attach it to a bug report.
|
|
3
|
-
|
|
4
|
-
function Initialize-CrashTrap {
|
|
5
|
-
$Script:WS.CrashArmed = $true
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function Get-FeedbackDir {
|
|
9
|
-
$d = $Script:WS.FeedbackDir
|
|
10
|
-
if (-not (Test-Path -LiteralPath $d)) { New-Item -ItemType Directory -Force -Path $d | Out-Null }
|
|
11
|
-
return $d
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function Get-LatestReportPath {
|
|
15
|
-
$dir = $Script:WS.ReportsDir
|
|
16
|
-
if (-not (Test-Path -LiteralPath $dir)) { return $null }
|
|
17
|
-
$f = Get-ChildItem -LiteralPath $dir -Filter 'report-*.json' -File -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
18
|
-
if ($f) { return $f.FullName }
|
|
19
|
-
return $null
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function New-SystemManifest {
|
|
23
|
-
<# .SYNOPSIS Non-sensitive environment facts for a bug report. #>
|
|
24
|
-
param([string] $Kind, [string] $Extra = '')
|
|
25
|
-
$ws = $Script:WS
|
|
26
|
-
$lines = @(
|
|
27
|
-
"$Script:WS_NAME v$(Get-ToolVersion) - $Kind"
|
|
28
|
-
"Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')"
|
|
29
|
-
''
|
|
30
|
-
'=== System info ==='
|
|
31
|
-
"OS: $($ws.OsCaption) ($([Environment]::OSVersion.Version))"
|
|
32
|
-
"PowerShell: $($PSVersionTable.PSVersion) ($($PSVersionTable.PSEdition))"
|
|
33
|
-
"Elevated: $($ws.IsAdmin)"
|
|
34
|
-
"Launcher: $($ws.Launcher) npx: $($ws.Npx)"
|
|
35
|
-
"Mode: $($ws.Mode) dry-run: $($ws.DryRun) developer: $($ws.Developer)"
|
|
36
|
-
"Node: $(try { (& node --version 2>$null) } catch { 'not installed' })"
|
|
37
|
-
)
|
|
38
|
-
if ($Extra) { $lines += ''; $lines += $Extra }
|
|
39
|
-
$lines += ''
|
|
40
|
-
$lines += '=== Privacy note ==='
|
|
41
|
-
$lines += 'This bundle was generated locally and was NOT sent anywhere. Review every file before sharing;'
|
|
42
|
-
$lines += 'logs and reports contain paths from your machine and a snapshot of cache sizes.'
|
|
43
|
-
$lines += "Report bugs at: $Script:WS_ISSUES (or email $Script:WS_EMAIL)"
|
|
44
|
-
return $lines
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function New-BundleZip {
|
|
48
|
-
<# .SYNOPSIS Zip the current log, the latest report and a manifest. Returns the zip path or $null. #>
|
|
49
|
-
param([string] $Prefix, [string[]] $Manifest)
|
|
50
|
-
$ws = $Script:WS
|
|
51
|
-
$stamp = Get-Date -Format 'yyyy-MM-dd_HHmmss'
|
|
52
|
-
$tmp = Join-Path $env:TEMP ("$Script:WS_NAME-bundle-" + [guid]::NewGuid().ToString('N'))
|
|
53
|
-
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
|
|
54
|
-
try {
|
|
55
|
-
[IO.File]::WriteAllLines((Join-Path $tmp 'MANIFEST.txt'), $Manifest)
|
|
56
|
-
if ($ws.LogFile -and (Test-Path -LiteralPath $ws.LogFile)) { Copy-Item -LiteralPath $ws.LogFile -Destination $tmp -ErrorAction SilentlyContinue }
|
|
57
|
-
$rep = Get-LatestReportPath
|
|
58
|
-
if ($rep) { Copy-Item -LiteralPath $rep -Destination $tmp -ErrorAction SilentlyContinue }
|
|
59
|
-
$out = Join-Path (Get-FeedbackDir) ("$Prefix-$stamp.zip")
|
|
60
|
-
Compress-Archive -Path (Join-Path $tmp '*') -DestinationPath $out -Force -ErrorAction Stop
|
|
61
|
-
return $out
|
|
62
|
-
} catch {
|
|
63
|
-
Write-Warn "could not create bundle: $($_.Exception.Message)"
|
|
64
|
-
return $null
|
|
65
|
-
} finally {
|
|
66
|
-
try { Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue } catch { $null = $_ }
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function Invoke-CrashBundle {
|
|
71
|
-
<# .SYNOPSIS Called by the entry script when Invoke-Main throws. #>
|
|
72
|
-
param([System.Management.Automation.ErrorRecord] $ErrorRecord)
|
|
73
|
-
$ws = $Script:WS
|
|
74
|
-
$msg = $ErrorRecord.Exception.Message
|
|
75
|
-
$where = $ErrorRecord.InvocationInfo.PositionMessage
|
|
76
|
-
Write-LogLine "CRASH: $msg"
|
|
77
|
-
Write-LogLine $ErrorRecord.ScriptStackTrace
|
|
78
|
-
$extra = @("=== Error ===", $msg, $where, '', '=== Stack ===', $ErrorRecord.ScriptStackTrace) -join "`r`n"
|
|
79
|
-
$zip = New-BundleZip -Prefix 'crash' -Manifest (New-SystemManifest -Kind 'CRASH REPORT' -Extra $extra)
|
|
80
|
-
Write-UiLine '' 'Gray'
|
|
81
|
-
Write-Err "$Script:WS_NAME exited unexpectedly: $msg"
|
|
82
|
-
Write-Note $where
|
|
83
|
-
if ($zip) {
|
|
84
|
-
Write-Info "crash bundle: $zip"
|
|
85
|
-
Write-Note 'Review it (it contains paths from your machine), then attach it to an issue:'
|
|
86
|
-
Write-Note "$Script:WS_ISSUES or run: windowsweep --report-issue"
|
|
87
|
-
}
|
|
88
|
-
Write-Note 'Nothing was sent. windowsweep makes no network calls.'
|
|
89
|
-
}
|
|
1
|
+
# crash_trap.ps1 - on an unexpected error, bundle the log + latest report + a manifest into a local zip.
|
|
2
|
+
# Nothing is ever sent anywhere; the user decides whether to attach it to a bug report.
|
|
3
|
+
|
|
4
|
+
function Initialize-CrashTrap {
|
|
5
|
+
$Script:WS.CrashArmed = $true
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function Get-FeedbackDir {
|
|
9
|
+
$d = $Script:WS.FeedbackDir
|
|
10
|
+
if (-not (Test-Path -LiteralPath $d)) { New-Item -ItemType Directory -Force -Path $d | Out-Null }
|
|
11
|
+
return $d
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function Get-LatestReportPath {
|
|
15
|
+
$dir = $Script:WS.ReportsDir
|
|
16
|
+
if (-not (Test-Path -LiteralPath $dir)) { return $null }
|
|
17
|
+
$f = Get-ChildItem -LiteralPath $dir -Filter 'report-*.json' -File -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
18
|
+
if ($f) { return $f.FullName }
|
|
19
|
+
return $null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function New-SystemManifest {
|
|
23
|
+
<# .SYNOPSIS Non-sensitive environment facts for a bug report. #>
|
|
24
|
+
param([string] $Kind, [string] $Extra = '')
|
|
25
|
+
$ws = $Script:WS
|
|
26
|
+
$lines = @(
|
|
27
|
+
"$Script:WS_NAME v$(Get-ToolVersion) - $Kind"
|
|
28
|
+
"Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')"
|
|
29
|
+
''
|
|
30
|
+
'=== System info ==='
|
|
31
|
+
"OS: $($ws.OsCaption) ($([Environment]::OSVersion.Version))"
|
|
32
|
+
"PowerShell: $($PSVersionTable.PSVersion) ($($PSVersionTable.PSEdition))"
|
|
33
|
+
"Elevated: $($ws.IsAdmin)"
|
|
34
|
+
"Launcher: $($ws.Launcher) npx: $($ws.Npx)"
|
|
35
|
+
"Mode: $($ws.Mode) dry-run: $($ws.DryRun) developer: $($ws.Developer)"
|
|
36
|
+
"Node: $(try { (& node --version 2>$null) } catch { 'not installed' })"
|
|
37
|
+
)
|
|
38
|
+
if ($Extra) { $lines += ''; $lines += $Extra }
|
|
39
|
+
$lines += ''
|
|
40
|
+
$lines += '=== Privacy note ==='
|
|
41
|
+
$lines += 'This bundle was generated locally and was NOT sent anywhere. Review every file before sharing;'
|
|
42
|
+
$lines += 'logs and reports contain paths from your machine and a snapshot of cache sizes.'
|
|
43
|
+
$lines += "Report bugs at: $Script:WS_ISSUES (or email $Script:WS_EMAIL)"
|
|
44
|
+
return $lines
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function New-BundleZip {
|
|
48
|
+
<# .SYNOPSIS Zip the current log, the latest report and a manifest. Returns the zip path or $null. #>
|
|
49
|
+
param([string] $Prefix, [string[]] $Manifest)
|
|
50
|
+
$ws = $Script:WS
|
|
51
|
+
$stamp = Get-Date -Format 'yyyy-MM-dd_HHmmss'
|
|
52
|
+
$tmp = Join-Path $env:TEMP ("$Script:WS_NAME-bundle-" + [guid]::NewGuid().ToString('N'))
|
|
53
|
+
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
|
|
54
|
+
try {
|
|
55
|
+
[IO.File]::WriteAllLines((Join-Path $tmp 'MANIFEST.txt'), $Manifest)
|
|
56
|
+
if ($ws.LogFile -and (Test-Path -LiteralPath $ws.LogFile)) { Copy-Item -LiteralPath $ws.LogFile -Destination $tmp -ErrorAction SilentlyContinue }
|
|
57
|
+
$rep = Get-LatestReportPath
|
|
58
|
+
if ($rep) { Copy-Item -LiteralPath $rep -Destination $tmp -ErrorAction SilentlyContinue }
|
|
59
|
+
$out = Join-Path (Get-FeedbackDir) ("$Prefix-$stamp.zip")
|
|
60
|
+
Compress-Archive -Path (Join-Path $tmp '*') -DestinationPath $out -Force -ErrorAction Stop
|
|
61
|
+
return $out
|
|
62
|
+
} catch {
|
|
63
|
+
Write-Warn "could not create bundle: $($_.Exception.Message)"
|
|
64
|
+
return $null
|
|
65
|
+
} finally {
|
|
66
|
+
try { Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue } catch { $null = $_ }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function Invoke-CrashBundle {
|
|
71
|
+
<# .SYNOPSIS Called by the entry script when Invoke-Main throws. #>
|
|
72
|
+
param([System.Management.Automation.ErrorRecord] $ErrorRecord)
|
|
73
|
+
$ws = $Script:WS
|
|
74
|
+
$msg = $ErrorRecord.Exception.Message
|
|
75
|
+
$where = $ErrorRecord.InvocationInfo.PositionMessage
|
|
76
|
+
Write-LogLine "CRASH: $msg"
|
|
77
|
+
Write-LogLine $ErrorRecord.ScriptStackTrace
|
|
78
|
+
$extra = @("=== Error ===", $msg, $where, '', '=== Stack ===', $ErrorRecord.ScriptStackTrace) -join "`r`n"
|
|
79
|
+
$zip = New-BundleZip -Prefix 'crash' -Manifest (New-SystemManifest -Kind 'CRASH REPORT' -Extra $extra)
|
|
80
|
+
Write-UiLine '' 'Gray'
|
|
81
|
+
Write-Err "$Script:WS_NAME exited unexpectedly: $msg"
|
|
82
|
+
Write-Note $where
|
|
83
|
+
if ($zip) {
|
|
84
|
+
Write-Info "crash bundle: $zip"
|
|
85
|
+
Write-Note 'Review it (it contains paths from your machine), then attach it to an issue:'
|
|
86
|
+
Write-Note "$Script:WS_ISSUES or run: windowsweep --report-issue"
|
|
87
|
+
}
|
|
88
|
+
Write-Note 'Nothing was sent. windowsweep makes no network calls.'
|
|
89
|
+
}
|
package/modules/disk_usage.ps1
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
# disk_usage.ps1 - section 21: read-only disk usage report (largest entries, disk images, drives).
|
|
2
|
-
|
|
3
|
-
function Get-Targets21 { return @() }
|
|
4
|
-
|
|
5
|
-
function Show-LargestEntries {
|
|
6
|
-
<# .SYNOPSIS Size every top-level entry of a folder and print the largest N. Returns the rows. #>
|
|
7
|
-
param([string] $Root, [int] $Top = 20, [string] $Title = '')
|
|
8
|
-
if (-not (Test-DirPresent $Root)) { return @() }
|
|
9
|
-
if (-not $Title) { $Title = $Root }
|
|
10
|
-
Write-Section "Largest entries in $Title"
|
|
11
|
-
Write-Note 'measuring...'
|
|
12
|
-
$rows = @()
|
|
13
|
-
foreach ($e in (Get-ChildEntries $Root)) {
|
|
14
|
-
$full = Remove-LongPrefix $e.FullName
|
|
15
|
-
$bytes = [long]0
|
|
16
|
-
if (Test-ReparsePoint $e) { continue }
|
|
17
|
-
if ($e -is [IO.DirectoryInfo]) { $bytes = Get-DirectoryBytes $full } else { $bytes = [long]$e.Length }
|
|
18
|
-
$rows += [pscustomobject]@{ Path = $full; Bytes = $bytes }
|
|
19
|
-
}
|
|
20
|
-
$rows = @($rows | Sort-Object Bytes -Descending | Select-Object -First $Top)
|
|
21
|
-
foreach ($r in $rows) {
|
|
22
|
-
$why = Get-ProtectionReason $r.Path
|
|
23
|
-
$tag = ''
|
|
24
|
-
if ($why) { $tag = ' [protected]' }
|
|
25
|
-
Write-UiLine (" {0,10} {1}{2}" -f (Format-Bytes $r.Bytes), $r.Path, $tag) 'Gray'
|
|
26
|
-
}
|
|
27
|
-
return $rows
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function Invoke-Section21 {
|
|
31
|
-
$ws = $Script:WS
|
|
32
|
-
$P = $Script:P
|
|
33
|
-
Write-SectionIntro @('Where the space went. Read-only; entries marked [protected] are ones this tool will never delete.')
|
|
34
|
-
$lines = @("windowsweep disk usage report - $(Get-Date -Format 'yyyy-MM-dd HH:mm')", '')
|
|
35
|
-
Show-DriveTable
|
|
36
|
-
foreach ($d in (Get-DriveSnapshot)) { $lines += ("{0} size {1} free {2}" -f $d.drive, (Format-Bytes $d.size_bytes), (Format-Bytes $d.free_bytes)) }
|
|
37
|
-
$h = Get-HiberfilInfo
|
|
38
|
-
if ($h.Bytes -gt 0) { Write-Kv 'hiberfil.sys:' (Format-Bytes $h.Bytes); $lines += "hiberfil.sys $(Format-Bytes $h.Bytes)" }
|
|
39
|
-
foreach ($img in (Get-DiskImageFiles)) { Write-Kv 'disk image:' ("{0} {1}" -f (Format-Bytes $img.Length), $img.FullName); $lines += "vhdx $(Format-Bytes $img.Length) $($img.FullName)" }
|
|
40
|
-
foreach ($pair in @(@($P.U, 'your profile'), @($P.L, 'AppData\Local'), @($P.A, 'AppData\Roaming'), @("$($P.SD)\", "drive $($P.SD)"))) {
|
|
41
|
-
$rows = Show-LargestEntries -Root $pair[0] -Top 20 -Title $pair[1]
|
|
42
|
-
$lines += ''; $lines += "== $($pair[1]) =="
|
|
43
|
-
foreach ($r in $rows) { $lines += ("{0,10} {1}" -f (Format-Bytes $r.Bytes), $r.Path) }
|
|
44
|
-
}
|
|
45
|
-
if (-not $ws.NoReport) {
|
|
46
|
-
$out = Join-Path $ws.ReportsDir ('disk-usage-' + $ws.Stamp + '.txt')
|
|
47
|
-
try { [IO.File]::WriteAllLines($out, $lines); Write-Info "report written: $out" } catch { Write-Warn "could not write $out" }
|
|
48
|
-
}
|
|
49
|
-
}
|
|
1
|
+
# disk_usage.ps1 - section 21: read-only disk usage report (largest entries, disk images, drives).
|
|
2
|
+
|
|
3
|
+
function Get-Targets21 { return @() }
|
|
4
|
+
|
|
5
|
+
function Show-LargestEntries {
|
|
6
|
+
<# .SYNOPSIS Size every top-level entry of a folder and print the largest N. Returns the rows. #>
|
|
7
|
+
param([string] $Root, [int] $Top = 20, [string] $Title = '')
|
|
8
|
+
if (-not (Test-DirPresent $Root)) { return @() }
|
|
9
|
+
if (-not $Title) { $Title = $Root }
|
|
10
|
+
Write-Section "Largest entries in $Title"
|
|
11
|
+
Write-Note 'measuring...'
|
|
12
|
+
$rows = @()
|
|
13
|
+
foreach ($e in (Get-ChildEntries $Root)) {
|
|
14
|
+
$full = Remove-LongPrefix $e.FullName
|
|
15
|
+
$bytes = [long]0
|
|
16
|
+
if (Test-ReparsePoint $e) { continue }
|
|
17
|
+
if ($e -is [IO.DirectoryInfo]) { $bytes = Get-DirectoryBytes $full } else { $bytes = [long]$e.Length }
|
|
18
|
+
$rows += [pscustomobject]@{ Path = $full; Bytes = $bytes }
|
|
19
|
+
}
|
|
20
|
+
$rows = @($rows | Sort-Object Bytes -Descending | Select-Object -First $Top)
|
|
21
|
+
foreach ($r in $rows) {
|
|
22
|
+
$why = Get-ProtectionReason $r.Path
|
|
23
|
+
$tag = ''
|
|
24
|
+
if ($why) { $tag = ' [protected]' }
|
|
25
|
+
Write-UiLine (" {0,10} {1}{2}" -f (Format-Bytes $r.Bytes), $r.Path, $tag) 'Gray'
|
|
26
|
+
}
|
|
27
|
+
return $rows
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function Invoke-Section21 {
|
|
31
|
+
$ws = $Script:WS
|
|
32
|
+
$P = $Script:P
|
|
33
|
+
Write-SectionIntro @('Where the space went. Read-only; entries marked [protected] are ones this tool will never delete.')
|
|
34
|
+
$lines = @("windowsweep disk usage report - $(Get-Date -Format 'yyyy-MM-dd HH:mm')", '')
|
|
35
|
+
Show-DriveTable
|
|
36
|
+
foreach ($d in (Get-DriveSnapshot)) { $lines += ("{0} size {1} free {2}" -f $d.drive, (Format-Bytes $d.size_bytes), (Format-Bytes $d.free_bytes)) }
|
|
37
|
+
$h = Get-HiberfilInfo
|
|
38
|
+
if ($h.Bytes -gt 0) { Write-Kv 'hiberfil.sys:' (Format-Bytes $h.Bytes); $lines += "hiberfil.sys $(Format-Bytes $h.Bytes)" }
|
|
39
|
+
foreach ($img in (Get-DiskImageFiles)) { Write-Kv 'disk image:' ("{0} {1}" -f (Format-Bytes $img.Length), $img.FullName); $lines += "vhdx $(Format-Bytes $img.Length) $($img.FullName)" }
|
|
40
|
+
foreach ($pair in @(@($P.U, 'your profile'), @($P.L, 'AppData\Local'), @($P.A, 'AppData\Roaming'), @("$($P.SD)\", "drive $($P.SD)"))) {
|
|
41
|
+
$rows = Show-LargestEntries -Root $pair[0] -Top 20 -Title $pair[1]
|
|
42
|
+
$lines += ''; $lines += "== $($pair[1]) =="
|
|
43
|
+
foreach ($r in $rows) { $lines += ("{0,10} {1}" -f (Format-Bytes $r.Bytes), $r.Path) }
|
|
44
|
+
}
|
|
45
|
+
if (-not $ws.NoReport) {
|
|
46
|
+
$out = Join-Path $ws.ReportsDir ('disk-usage-' + $ws.Stamp + '.txt')
|
|
47
|
+
try { [IO.File]::WriteAllLines($out, $lines); Write-Info "report written: $out" } catch { Write-Warn "could not write $out" }
|
|
48
|
+
}
|
|
49
|
+
}
|