# List of users that should not be deleted for inactivity $excludedUsers = @( "hzun74", "mcsj35", "wtaub", "BAY.Cerner724", "Imprivata_CMI_801", "Imprivata_MMG_bay", "Imprivata_MMG_CMI" ) Function Get-FolderSize { param ( [Parameter(Mandatory=$true)] [string]$profilePath ) $size = (Get-ChildItem -LiteralPath "\\$computerName\$($profilePath.Replace(':', '$'))" -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB return [math]::Round($size, 2) } function Get-ADName($username) { try { $adUser = Get-ADUser -Identity $username -ErrorAction SilentlyContinue if ($adUser) { return $adUser.GivenName + " " + $adUser.Surname } else { return $null } } catch { return $null } } function ConvertTo-ReadableSize ($bytes) { $unit = "B" if ($bytes -gt 1GB) { $bytes /= 1GB $unit = "GB" } elseif ($bytes -gt 1MB) { $bytes /= 1MB $unit = "MB" } elseif ($bytes -gt 1KB) { $bytes /= 1KB $unit = "KB" } return "{0:N2} {1}" -f $bytes, $unit } function TimeSinceLastUseInMonths($lastUseTime) { $timeSpan = [DateTime]::Now - $lastUseTime return "{0:N2}" -f ($timeSpan.Days / 30.44) # Using average days in a month for calculation } function Remove-SelectedProfiles($selectedProfiles) { Write-Host "`nProfiles to be removed:" -ForegroundColor Red foreach ($profile in $selectedProfiles) { $adFullName = Get-ADName -username $profile.LocalPath.Split('\')[-1] Write-Host ("`t" + $profile.LocalPath.Split('\')[-1] + " ($adFullName)") -ForegroundColor Yellow } $confirm = Read-Host "`nAre you sure you want to remove these profiles? (yes/no)" if ($confirm -eq "yes") { foreach ($profile in $selectedProfiles) { $profile | Remove-CimInstance Write-Host "Removed profile for $($profile.LocalPath)" } } } $previousComputerName = $null do { # Clear screen for fresh view and add horizontal rule Clear-Host Write-Host ('-' * 50) -ForegroundColor Cyan if (-not $previousComputerName) { $computerName = Read-Host "Enter the computer name" } else { $computerName = $previousComputerName } $remoteComputer = $computerName # Test PS Remoting try { $result = Invoke-Command -ComputerName $remoteComputer -ScriptBlock { $true } -ErrorAction Stop } catch { $result = $false } if ($result) { Write-Output "PS Remoting is already enabled on $remoteComputer." } else { Write-Output "PS Remoting is not enabled on $remoteComputer. Trying to enable it using PSexec..." # Use PSexec to enable PS Remoting on the remote computer psexec.exe \\$remoteComputer powershell -Command "Enable-PSRemoting -Force -SkipNetworkProfileCheck" # Check if PS Remoting is now enabled try { $resultAfter = Invoke-Command -ComputerName $remoteComputer -ScriptBlock { $true } -ErrorAction Stop } catch { $resultAfter = $false } if ($resultAfter) { Write-Output "Successfully enabled PS Remoting on $remoteComputer." } else { Write-Output "Failed to enable PS Remoting on $remoteComputer." } } $choice = Read-Host "Choose an action: (1) List profiles, (2) Remove profiles not accessed in X months, (3) Manage profiles by folder size" $profiles = Get-CimInstance -Class Win32_UserProfile -ComputerName $computerName | Where-Object { $_.Special -eq $false -and $_.LocalPath -notmatch '\\(Public|Administrator|Default)$' } | Sort-Object { $shortcutFolder = "\\$computerName\c$\users\" + $_.LocalPath.Split('\')[-1] + "\Desktop\shortcuts" if (Test-Path $shortcutFolder) { (Get-Item $shortcutFolder).LastWriteTime } else { [datetime]::MinValue } } -Descending if ($choice -eq "1") { $i = 0 foreach ($profile in $profiles) { $adFullName = Get-ADName -username $profile.LocalPath.Split('\')[-1] $size = ConvertTo-ReadableSize -bytes ((Get-ChildItem -Recurse ("\\$computerName\c$\users\" + $profile.LocalPath.Split('\')[-1])).Length | Measure-Object -Sum).Sum $shortcutFolder = "\\$computerName\c$\users\" + $profile.LocalPath.Split('\')[-1] + "\Desktop\shortcuts" $lastModified = if (Test-Path $shortcutFolder) { (Get-Item $shortcutFolder).LastWriteTime } else { "shortcuts folder not found within Desktop" } # Display user details in formatted and colored output Write-Host "`n[$i]" -ForegroundColor Yellow Write-Host ("Name: $($profile.LocalPath.Split('\')[-1]) ($adFullName)") -ForegroundColor Green Write-Host "Size: $size" -ForegroundColor Green Write-Host "Last Modified: $lastModified" -ForegroundColor Green $i++ } $selectedIndices = (Read-Host "`nSelect users to remove by index (space-delimited)").Split() $selectedProfiles = $profiles | Where-Object { $selectedIndices -contains $profiles.IndexOf($_).ToString() } Remove-SelectedProfiles -selectedProfiles $selectedProfiles } if ($choice -eq "2") { Write-Host "`nProfiles and their inactivity duration:" -ForegroundColor Cyan foreach ($profile in $profiles) { $shortcutFolder = "\\$computerName\c$\users\" + $profile.LocalPath.Split('\')[-1] + "\Desktop\shortcuts" if (Test-Path $shortcutFolder) { $lastModified = (Get-Item $shortcutFolder).LastWriteTime $monthsInactive = TimeSinceLastUseInMonths -lastUseTime $lastModified Write-Host ("`t" + $profile.LocalPath.Split('\')[-1] + ": " + $monthsInactive + " months") -ForegroundColor Green } else { Write-Host ("`t" + $profile.LocalPath.Split('\')[-1] + ": shortcuts folder not found within Desktop") -ForegroundColor Red } } $months = Read-Host "`nEnter the number of months of inactivity for profile removal" $cutoffDate = (Get-Date).AddMonths(-$months) $profilesToBeRemoved = $profiles | Where-Object { $shortcutFolder = "\\$computerName\c$\users\" + $_.LocalPath.Split('\')[-1] + "\Desktop\shortcuts" if ($excludedUsers -contains $_.LocalPath.Split('\')[-1]) { return $false } if (Test-Path $shortcutFolder) { (Get-Item $shortcutFolder).LastWriteTime -lt $cutoffDate } else { $false } } Remove-SelectedProfiles -selectedProfiles $profilesToBeRemoved } if ($choice -eq '3') { $profiles = Get-CimInstance -ComputerName $computerName -ClassName Win32_UserProfile | Where-Object { !$_.Special } $profiles | Select-Object LocalPath, @{Name='Size (MB)';Expression={Get-FolderSize $_.LocalPath}} $sizeCriterion = Read-Host "Enter the folder size criterion (in MB)" $comparison = Read-Host "Enter 'G' to delete profiles with size greater than the criterion, or 'L' to delete profiles with size lesser than the criterion" $sizeCriterionBytes = $sizeCriterion/1000000 if ($comparison -eq 'G') { $profilesToRemove = $profiles | Where-Object {(Get-FolderSize $_.LocalPath) -gt $sizeCriterionBytes} } elseif ($comparison -eq 'L') { $profilesToRemove = $profiles | Where-Object {(Get-FolderSize $_.LocalPath) -lt $sizeCriterionBytes} } # Confirm and delete profiles $confirm = Read-Host "Enter 'Y' to confirm removal of the listed profiles or 'N' to cancel" if ($confirm -eq 'Y') { $profilesToRemove | ForEach-Object { Remove-CimInstance -CimInstance $_ } } } $action = Read-Host "`nChoose an action: (1) Search again on the same PC, (2) Search another PC, (3) Exit" if ($action -eq "3") { break } elseif ($action -eq "2") { $previousComputerName = $null continue } else { $previousComputerName = $computerName } } while ($true)