Introduction
Managing user profiles on Windows systems is crucial for maintaining system health and storage efficiency. This PowerShell script provides an automated solution for identifying and removing outdated user profiles while protecting system-critical profiles. The script includes interactive confirmation and detailed logging with color-coded outputs for better visibility.
The Script
<#
.SYNOPSIS
Automated cleanup of unused Windows user profiles.
.DESCRIPTION
This script identifies and removes user profiles that haven't been accessed
for a specified number of days, with built-in protection for system profiles.
.PARAMETER numOfDays
Number of days of inactivity before a profile is considered unused. Default is 60.
#>
# Set default days if no argument provided
$numOfDays = if ($args[0]) { $args[0] } else { 60 }
# Interactive confirmation function
function Get-UserConfirmation {
$caption = "Profile Deletion Confirmation"
$message = "Do you want to proceed with deleting the unused user profiles?"
$choices = [System.Management.Automation.Host.ChoiceDescription[]]@("&Yes", "&No")
$defaultChoice = 1 # Default to No for safety
$decision = $host.UI.PromptForChoice($caption, $message, $choices, $defaultChoice)
return $decision -eq 0
}
# Protected system profiles
function Test-ProtectedProfile {
param([string]$ProfileName)
$protectedProfiles = @(
"All Users", "Default User", "Default", "LocalService",
"NetworkService", "Administrator", "Public", "AppData",
"Classic .NET AppPool"
)
return $profileName -in $protectedProfiles
}
# Determine user profile path
$userProfilePath = if (Test-Path "C:\Users") {
"C:\Users"
} else {
"C:\Documents and Settings"
}
Write-Host "`nScanning for unused profiles older than $numOfDays days..." -ForegroundColor Cyan
# Collect eligible profiles
$unusedProfiles = Get-ChildItem -Path $userProfilePath | Where-Object {
$lastAccess = $_.LastAccessTime
$age = (New-TimeSpan $lastAccess (Get-Date)).Days
-not (Test-ProtectedProfile $_.Name) -and ($age -gt $numOfDays)
} | Select-Object @{
Name = 'Profile'
Expression = { $_.FullName }
}, @{
Name = 'LastAccess'
Expression = { $_.LastAccessTime }
}, @{
Name = 'DaysInactive'
Expression = { (New-TimeSpan $_.LastAccessTime (Get-Date)).Days }
}
if ($unusedProfiles) {
Write-Host "`nFound unused profiles:" -ForegroundColor Yellow
$unusedProfiles | ForEach-Object {
Write-Host "Profile: " -NoNewline -ForegroundColor Green
Write-Host $_.Profile
Write-Host "Last Access: " -NoNewline -ForegroundColor Green
Write-Host $_.LastAccess
Write-Host "Days Inactive: " -NoNewline -ForegroundColor Green
Write-Host "$($_.DaysInactive)`n"
}
if (Get-UserConfirmation) {
Write-Host "`nRemoving profiles..." -ForegroundColor Cyan
foreach ($profile in $unusedProfiles) {
$path = $profile.Profile
try {
Write-Host "Removing profile: $path" -ForegroundColor Yellow
Remove-Item -Path $path -Force -Recurse -ErrorAction Stop
Write-Host "Successfully removed profile: $path" -ForegroundColor Green
}
catch {
Write-Host "Failed to remove profile: $path" -ForegroundColor Red
Write-Host "Error: $_" -ForegroundColor Red
}
}
Write-Host "`nProfile cleanup completed!" -ForegroundColor Cyan
}
else {
Write-Host "`nOperation cancelled by user." -ForegroundColor Yellow
}
}
else {
Write-Host "`nNo unused profiles found meeting the $numOfDays day threshold." -ForegroundColor Green
}
How It Works
The enhanced script provides several improvements over the original version:
- Improved Error Handling: Robust try-catch blocks for safer execution
- Color-Coded Output: Visual feedback using different colors for various message types
- Enhanced Reporting: Detailed information about each profile before deletion
- Safer Defaults: No parameter defaults to protecting profiles
- Simplified Logic: Streamlined profile detection and removal process
- Better Documentation: Includes detailed comments and help information
Conclusion
This improved script provides a safer, more user-friendly approach to managing user profiles on Windows systems. The color-coded output makes it easier to track the script’s progress and identify any issues that arise during execution. It’s an essential tool for system administrators managing multiple workstations or servers requiring regular profile maintenance.