The script attempts to delete all folders older than the current folder in C:\Program Files\dotnet\shared... where older code is left behind when updated code is installed.
Please test this with -WhatIf as a parameter and ensure it's safe and working for you before deploying this (or any script). For other Microsoft .NET versions, you will need to edit the 8.x.x to 9.x.x, for example.
# Requires: PowerShell 5+ | Run as admin (self-elevates if needed)
# Purpose: In C:\Program Files\dotnet\shared\{Microsoft.NETCore.App, Microsoft.WindowsDesktop.App}
# keep the latest 8.0.x folder and delete any other 8.0.x folders.
param(
[switch]$WhatIf # Use -WhatIf for a dry run
)
# --- Elevation check (self-relaunch as admin if needed) ---
$currId = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currId)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
Write-Host "Re-launching with administrative privileges..."
$psi = @{
FilePath = (Get-Process -Id $PID).Path
ArgumentList = @('-NoProfile','-ExecutionPolicy','Bypass','-File',"`"$PSCommandPath`"") + ($PSBoundParameters.Keys | ForEach-Object { if ($PSBoundParameters[$_]) { "-$_" } })
Verb = 'RunAs'
}
Start-Process @psi
exit
}
$base = 'C:\Program Files\dotnet\shared' # (spelled correctly: Program Files)
$targets = @('Microsoft.NETCore.App','Microsoft.WindowsDesktop.App')
foreach ($t in $targets) {
$path = Join-Path $base $t
if (-not (Test-Path $path)) {
Write-Host "Skipping: $path (not found)"
continue
}
# Get only 8.0.* directories and associate them with parsed [version] objects
$entries = @()
foreach ($d in Get-ChildItem -Path $path -Directory -ErrorAction SilentlyContinue) {
if ($d.Name -like '8.0.*') {
try {
$ver = [version]$d.Name
$entries += [pscustomobject]@{ Dir = $d; Ver = $ver }
} catch {
# Ignore folders that don't parse to a version
}
}
}
if (-not $entries) {
Write-Host "No 8.0.x folders found in $path"
continue
}
$latest = $entries | Sort-Object Ver -Descending | Select-Object -First 1
$toDelete = $entries | Where-Object { $_.Ver -ne $latest.Ver }
Write-Host "Folder: $path"
Write-Host " Keeping latest 8.0.x: $($latest.Dir.Name)"
if ($toDelete) {
$toDeleteNames = $toDelete.Dir.Name -join ', '
Write-Host " Deleting older 8.0.x: $toDeleteNames"
foreach ($e in $toDelete) {
Remove-Item -LiteralPath $e.Dir.FullName -Recurse -Force -Confirm:$false -ErrorAction Continue -WhatIf:$WhatIf
}
} else {
Write-Host " Nothing else to delete."
}
}
Write-Host "Done. $(if($WhatIf){'This was a DRY RUN (-WhatIf). No changes were made.'})"