profilecleaner.ps1

🧩 Syntax:
# 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)
johnkonkemclaren

johnkonkemclaren

Member