Cómo eliminar perfiles de usuario antiguos en Windows
Los administradores deben eliminar de vez en cuando los perfiles de usuario antiguos (usuarios retirados o inactivos, etc.) de C:\Users en estaciones de trabajo y servidores de Windows. La tarea de limpieza del perfil de usuario de Windows se realiza con mayor frecuencia en servidores de terminal de Servicios de escritorio remoto (RDS).
El principal problema de los servidores RDS es el constante crecimiento del tamaño de los directorios de perfiles de usuario en el disco duro. Este problema se resuelve parcialmente mediante cuotas de tamaño de perfil de usuario mediante cuotas de FSRM o NTFS, mediante perfiles móviles como FSLogix o User Profile Disk, carpetas redirigidas, etc. Sin embargo, si tiene una gran cantidad de usuarios de RDS, con el tiempo la carpeta C:\Users contendrá una gran cantidad de directorios con perfiles de usuario antiguos (sin usar).
¿Cómo eliminar un perfil de usuario en Windows manualmente?
En Windows, puede eliminar un perfil manualmente desde el Panel de control:
Abra la Configuración avanzada del sistema (ejecute el comando
SystemPropertiesAdvanced) y vaya a Perfiles de usuario -> Configuración;
-
Esta ventana enumera todos los perfiles de usuario (cuentas locales, de dominio y de Microsoft) almacenados en esta computadora. El tamaño de cada perfil de usuario en el disco se muestra en la columna Tamaño;
Seleccione el usuario cuyo perfil desea eliminar y haga clic en el botón Eliminar.
En Windows 11/10 y Windows Server 2022/2019, puede eliminar perfiles de usuario del disco a través de la aplicación Configuración. Vaya a Cuentas -> Acceda al trabajo y la escuela (o ejecute el atajo de URI
ms-settings:otherusers). Seleccione un usuario y haga clic en Eliminar para eliminar los datos de su perfil de la computadora.
Cuando un perfil de usuario se elimina correctamente en Windows, se eliminan el directorio del perfil en C:\Users y la entrada del usuario en el registro.
Muchos administradores novatos intentan eliminar manualmente el directorio de perfil de usuario de la carpeta C:\Users. En este caso, deberá eliminar manualmente la referencia del perfil del registro de Windows:
Ejecute el Editor del Registro (
regedit.exe);
-
Vaya a la clave de registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList;
Para cada usuario que inició sesión localmente (este método de inicio de sesión debe estar permitido para el usuario mediante la opción Permitir inicio de sesión local GPO), se crea una subclave separada con el SID del usuario como nombre;
Puede encontrar la clave de registro correspondiente al usuario por su SID, o puede buscar manualmente el contenido de todas las subclaves hasta que encuentre una clave en la que el valor ProfileImagePath apunte al directorio con el perfil de usuario en el disco (por ejemplo,
C:\Users\j.smith);
Elimine esta clave de registro para completar la eliminación correcta del perfil.
También puede eliminar el perfil de un usuario específico usando PowerShell:
Get-CimInstance -Class Win32_UserProfile | Where-Object { $_.LocalPath.split(‘\’)[-1] -eq 'j.smith' } | Remove-CimInstanceEste comando elimina tanto el directorio del disco duro como el
j.smithreferencia de perfil de usuario en el registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList.
Este comando funciona tanto en Windows PowerShell como en las nuevas versiones de PowerShell Core 6.x, 7.x.
Puede quitar un perfil de usuario en una computadora remota usando PowerShell Remoting y el cmdlet Invoke-Command:
$compname="mun-wks92s3"
$user = "j.smith"
Invoke-Command -ComputerName $compname -ScriptBlock {
param($user)
Get-CimInstance -Class Win32_UserProfile | Where-Object { $_.LocalPath.split(‘\’)[-1] -eq $user } | Remove-CimInstance
} -ArgumentList $userGPO: eliminar perfiles de usuario anteriores a un número de días especificado
En Windows, hay una opción de directiva de grupo integrada para eliminar automáticamente los perfiles de usuario con más de xx días. Puede habilitar esta opción mediante el Editor de directivas de grupo local (
gpedit.msc) o con la consola de administración de GPO de dominio (
gpmc.msc). En este ejemplo, vamos a aplicar una política de limpieza automática de perfiles a los hosts en la granja RDS que se encuentran en un contenedor separado (unidad organizativa, OU) en Active Directory.
Antes de aplicar la política de perfiles de limpieza a todos los hosts, le recomendamos que la pruebe en un host de prueba. Ponga uno de los servidores RDSH en modo de mantenimiento (drenaje) y pruebe la política en él.
Localice la unidad organizativa que contiene las computadoras/servidores a los que desea aplicar la política de limpieza del perfil de usuario. Haga clic con el botón derecho en la unidad organizativa y seleccione Crear un GPO en este dominio y vincularlo aquí;
Especifique el nombre de la política y edite el GPO;
Vaya a Configuración de la computadora -> Plantillas administrativas -> Sistema -> Perfiles de usuario;
Abra la opción Eliminar perfiles de usuario anteriores a un número específico de días al reiniciar el sistema;
Habilite la política y especifique la cantidad de días que un perfil de usuario se considera activo. Cuando termine este período, el Servicio de perfiles de usuario de Windows eliminará automáticamente el perfil en el próximo reinicio. Se recomienda especificar aquí el período de 45-90 días;
Después de aplicar la nueva configuración de directiva de grupo, el servicio de perfiles de usuario en su servidor Windows eliminará automáticamente los perfiles de usuario antiguos. Los perfiles de usuario se eliminarán en el próximo reinicio del servidor.
Si utiliza esta política, debe asegurarse de que no haya problemas con la hora del sistema cuando el servidor se detiene/reinicia (consulte el artículo “Cambios de fecha y hora del sistema después del reinicio”). De lo contrario, los perfiles de usuario activos pueden eliminarse.
Otra desventaja es que no puedes evitar que se eliminen ciertos perfiles, como cuentas locales, administradores, etc.
Esta política no funcionaba correctamente en versiones anteriores a Windows 11/10 y Windows Server 2022/2019. Anteriormente, la inactividad del perfil de usuario estaba determinada por la fecha de modificación del archivo NTUSER.dat. Al instalar actualizaciones de Windows, el servicio Instalador de confianza puede cambiar la fecha de modificación del archivo NTUSER.dat en el perfil de cada usuario. Como resultado, el servicio Win32_UserProfile cree que el perfil se usó recientemente.
En las versiones modernas de Windows, esta opción de directiva de grupo comprueba la actividad del perfil de usuario con los valores de los parámetros LocalProfileUnloadTimeLow y LocalProfileUnloadTimeHigh en HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\
Puede usar la siguiente secuencia de comandos para obtener los valores de registro LocalProfileLoadTimeLow y LocalProfileUnloadTimeHigh en formato de hora normal:
$profilelist = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
foreach ($p in $profilelist) {
try {
$objUser = (New-Object System.Security.Principal.SecurityIdentifier($p.PSChildName)).Translate([System.Security.Principal.NTAccount]).value
} catch {
$objUser = "[UNKNOWN]"
}
Remove-Variable -Force LTH,LTL,UTH,UTL -ErrorAction SilentlyContinue
$LTH = '{0:X8}' -f (Get-ItemProperty -Path $p.PSPath -Name LocalProfileLoadTimeHigh -ErrorAction SilentlyContinue).LocalProfileLoadTimeHigh
$LTL = '{0:X8}' -f (Get-ItemProperty -Path $p.PSPath -Name LocalProfileLoadTimeLow -ErrorAction SilentlyContinue).LocalProfileLoadTimeLow
$UTH = '{0:X8}' -f (Get-ItemProperty -Path $p.PSPath -Name LocalProfileUnloadTimeHigh -ErrorAction SilentlyContinue).LocalProfileUnloadTimeHigh
$UTL = '{0:X8}' -f (Get-ItemProperty -Path $p.PSPath -Name LocalProfileUnloadTimeLow -ErrorAction SilentlyContinue).LocalProfileUnloadTimeLow
$LoadTime = if ($LTH -and $LTL) {
[datetime]::FromFileTime("0x$LTH$LTL")
} else {
$null
}
$UnloadTime = if ($UTH -and $UTL) {
[datetime]::FromFileTime("0x$UTH$UTL")
} else {
$null
}
[pscustomobject][ordered]@{
User = $objUser
SID = $p.PSChildName
Loadtime = $LoadTime
UnloadTime = $UnloadTime
}
}
Esta lista contiene el último tiempo de carga para cada perfil de usuario.
Eliminar perfiles de usuario antiguos con PowerShell Script
En lugar de usar la política de limpieza automática de perfiles descrita anteriormente, puede usar un script de PowerShell simple para buscar y eliminar los perfiles de usuarios deshabilitados o inactivos.
Primero, intentemos calcular el tamaño del perfil de cada usuario en C:\Users usando un script simple del artículo Cómo obtener el tamaño de la carpeta con PowerShell
gci -force ‘C:\Users\’-ErrorAction SilentlyContinue | Where { !($_.Attributes -match " ReparsePoint") }| ? { $_ -is [io.directoryinfo] } | % {
$len = 0
gci -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length }
$_.fullname, ‘{0:N2} GB’ -f ($len / 1Gb)
$sum = $sum + $len
}
"Total size of profiles",'{0:N2} GB' -f ($sum / 1Gb)El tamaño total de todos los perfiles de usuario en C:\Users es de unos 32 GB.
El script ignora los enlaces simbólicos de Windows (enlaces simbólicos) al calcular el tamaño del perfil de usuario.
Veamos la lista de usuarios cuyos perfiles no se han utilizado durante más de 60 días. Puede usar el valor en el campo LastUseTime del perfil para encontrarlos.
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))}| Measure-ObjectResultó que tenía 127 cuentas de usuario inactivas en mi host RDS (con un tamaño total de perfiles de aproximadamente 18 GB).
El siguiente script de PowerShell enumera los detalles de los perfiles de usuario que no se han actualizado durante más de 60 días. El script convierte el SID del usuario en un nombre, calcula el tamaño del perfil de cada usuario y muestra una tabla resultante:
$allprofilesinfo = @()
$OldProfiles=Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))}
Foreach ($OldProfile in $OldProfiles)
{$objSID = New-Object System.Security.Principal.SecurityIdentifier ($OldProfile.SID)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$userinfo = New-Object PSObject -Property @{
userName = $objUser.Value
ProfilePath = $OldProfile.localpath
LastUsedDate = $OldProfile.ConvertToDateTime($OldProfile.LastUseTime)
FolderSize = "{0:N2} GB" -f ((gci -force $OldProfile.localpath -Recurse -ErrorAction SilentlyContinue| measure Length -s).sum / 1Gb)
}
$allprofilesinfo += $userinfo
}
$allprofilesinfoPara eliminar todos estos perfiles de usuario, basta con canalizar la lista de usuarios al comando Remove-WmiObject (se recomienda que verifique la salida del script con el parámetro -WhatIf antes de ejecutarlo):
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))} | Remove-WmiObject -WhatIfComo se mencionó anteriormente, al instalar algunas actualizaciones de Windows, el servicio Instalador de confianza puede cambiar la fecha de modificación del archivo NTUSER.dat en el perfil de cada usuario.
La captura de pantalla anterior muestra que todos los perfiles se cambiaron aproximadamente al mismo tiempo. Consulta la fecha de las últimas actualizaciones instaladas en Windows:
gwmi win32_quickfixengineering |sort installedon |select InstalledOn -Last 1O usando el módulo PSWindowsUpdate:
Get-WUHistory | Select-Object -First 10Lo más probable es que coincida con la fecha en que se cambiaron los perfiles. Por lo tanto, en versiones anteriores de Windows, puede obtener una lista de perfiles inactivos mediante otro script que verifica el atributo lastwritetime del directorio de perfil del usuario:
$USERS= (Get-ChildItem -directory -force 'C:\Users' | Where { ((Get-Date) — $_.lastwritetime).days -ge 60 } | % {'c:\users\' + $_.Name})
foreach ($User in $USERS) {
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.LocalPath -eq $User)} | Remove-WmiObject WhatIf }Para evitar eliminar los perfiles de algunos usuarios (como cuentas de Sistema y Servicio de red, una cuenta de administrador local, cuentas de usuarios con sesiones activas y otras cuentas de la lista de excepciones), puede modificar el script de la siguiente manera:
#The list of accounts, which profiles must not be deleted
$ExcludedUsers ="Public","zabbix_agent","svc",”user_1”,”user_2”
$LocalProfiles=Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))}
foreach ($LocalProfile in $LocalProfiles)
{
if (!($ExcludedUsers -like $LocalProfile.LocalPath.Replace("C:\Users\","")))
{
$LocalProfile | Remove-WmiObject
Write-host $LocalProfile.LocalPath, "profile deleted” -ForegroundColor Magenta
}
}Puede ejecutar este script de PowerShell a través de un GPO al apagar o con un script de PowerShell en el Programador de tareas.
¡Se recomienda que pruebe el script en su entorno antes de configurar la eliminación automática de perfiles!
Puede modificar el script para eliminar automáticamente todos los perfiles de usuario agregados al grupo AD específico. Por ejemplo, desea eliminar los perfiles de los usuarios que han dejado de fumar. Simplemente agregue estas cuentas al grupo DisabledUsers y ejecute el script en el host de destino:
$users = Get-ADGroupMember -Identity DisabledUsers | Foreach {$_.Sid.Value}
$profiles = Get-WmiObject Win32_UserProfile
$profiles | Where {$users -eq $_.Sid} | Foreach {$_.Delete()}








