# Remove-DotNetCore31.ps1 # Removes unsupported Microsoft .NET Core / ASP.NET Core / Windows Desktop Runtime / SDK 3.1.x components $ErrorActionPreference = "Continue" Write-Output "Starting .NET Core 3.1 remediation..." $registryPaths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $targetApps = foreach ($path in $registryPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { ( $_.DisplayName -match "Microsoft \.NET.*3\.1\." -or $_.DisplayName -match "Microsoft ASP\.NET Core.*3\.1\." -or $_.DisplayName -match "Microsoft Windows Desktop Runtime.*3\.1\." ) -and $_.UninstallString } } if (-not $targetApps) { Write-Output "No .NET Core 3.1 components found. Nothing to remove." exit 0 } foreach ($app in $targetApps) { Write-Output "Found: $($app.DisplayName) $($app.DisplayVersion)" } foreach ($app in $targetApps) { Write-Output "Attempting to remove: $($app.DisplayName) $($app.DisplayVersion)" $uninstallString = $app.UninstallString if ($uninstallString -match "\{[A-Fa-f0-9\-]{36}\}") { $productCode = $Matches[0] Write-Output "Using MSI product code: $productCode" Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $productCode /qn /norestart" -Wait } else { Write-Output "No MSI product code found for $($app.DisplayName). Skipping." } } Write-Output "Verifying remaining .NET Core 3.1 components..." $remainingApps = foreach ($path in $registryPaths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | Where-Object { ( $_.DisplayName -match "Microsoft \.NET.*3\.1\." -or $_.DisplayName -match "Microsoft ASP\.NET Core.*3\.1\." -or $_.DisplayName -match "Microsoft Windows Desktop Runtime.*3\.1\." ) -and $_.UninstallString } } if ($remainingApps) { Write-Output "Some .NET Core 3.1 components may still remain:" $remainingApps | ForEach-Object { Write-Output "$($_.DisplayName) $($_.DisplayVersion)" } exit 1 } else { Write-Output ".NET Core 3.1 components removed successfully." exit 0 }