Windows 워크스테이션과 서버, 특히 RDS(원격 데스크톱 서비스) 서버에서는 C:\Users 폴더에 쌓이는 오래되고 사용하지 않는 사용자 프로필을 주기적으로 정리해야 할 필요가 있습니다. 원격 데스크톱 서버의 가장 큰 고민은 로컬 드라이브에서 사용자 프로필 디렉터리 크기가 끊임없이 증가한다는 점입니다. FSRM이나 NTFS 할당량으로 프로필 최대 크기를 제한하면 어느 정도 완화할 수 있지만, 터미널 서버 사용자가 많다면 시간이 지날수록 C:\Users에는 더 이상 필요 없는 프로필 폴더가 수없이 많이 쌓이게 됩니다.
Windows에서 사용자 프로필을 수동으로 삭제하는 방법
초보 관리자들은 흔히 C:\Users에서 프로필 폴더를 그냥 삭제하려고 합니다. 폴더를 삭제한 후 레지스트리 키 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList에서 해당 폴더를 가리키는 프로필 항목까지 함께 제거하면 가능은 합니다.
그러나 올바른 수동 삭제 방법은 시스템 속성을 열어 고급 시스템 설정 → 사용자 프로필 → 설정으로 이동한 뒤, 목록에서 사용자를 선택하고(크기 열에서 로컬 드라이브의 프로필 용량을 확인할 수 있습니다) 삭제 버튼을 클릭하는 것입니다.
다만 이 방법은 어디까지나 수동 작업이므로, 규모가 있는 환경에서는 자동화를 고려하게 됩니다.
GPO: 지정한 일수보다 오래된 사용자 프로필 삭제
Windows에는 일정 일수보다 오래된 사용자 프로필을 자동으로 삭제하는 기본 그룹 정책이 내장되어 있습니다. GPO 섹션 컴퓨터 구성 → 관리 템플릿 → 시스템 → 사용자 프로필에서 '시스템 다시 시작 시 지정된 일수보다 오래된 사용자 프로필 삭제' 정책을 찾을 수 있습니다. 로컬 그룹 정책 편집기(gpedit.msc)에서 활성화하거나, 도메인 환경에서는 GPMC.msc를 통해 배포할 수 있습니다.
정책을 사용으로 설정한 뒤, 사용자 프로필을 활성 상태로 간주할 일수를 지정합니다. 이 기간이 지나면 Windows 사용자 프로필 서비스가 다음 재시작 시 해당 프로필을 자동으로 삭제합니다. 일반적으로 45~90일을 권장합니다.
이 정책을 적용할 때는 서버를 종료하거나 재시작할 때 시스템 시간에 문제가 없는지 반드시 확인해야 합니다('재부팅 후 시스템 시간·날짜 변경' 관련 문서 참고). 그렇지 않으면 활성 상태의 사용자 프로필까지 삭제될 위험이 있습니다.
이 자동 정리 방식의 단점은 서버 재시작 시점을 기다려야 한다는 점과 선택성이 없다는 점입니다. 즉, 로컬 계정이나 관리자 계정처럼 특정 프로필의 삭제를 제외할 수 없습니다. 또한 일부 서드파티 소프트웨어(대표적으로 백신 프로그램)가 사용자 프로필의 NTUSER.DAT 파일에 접근해 마지막 사용 날짜를 갱신하는 경우, 이 정책이 의도대로 동작하지 않을 수 있습니다.
PowerShell 스크립트로 오래된 사용자 프로필 삭제하기
앞서 설명한 자동 정리 정책 대신, 간단한 PowerShell 스크립트를 사용해 비활성화되었거나 장기간 사용하지 않은 사용자의 프로필을 찾아 제거할 수 있습니다.
먼저 C:\Users 아래 모든 사용자 프로필 폴더의 크기를 계산해 보겠습니다:
gci -force 'C:\Users' -ErrorAction SilentlyContinue | ? { $_ -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)
실행 결과, C:\Users의 전체 사용자 프로필 크기는 31.5GB였습니다.
이번에는 60일 이상 사용되지 않은 프로필을 가진 사용자 목록을 출력해 보겠습니다. 프로필의 LastUseTime 필드 값을 활용하면 됩니다.
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))} | Measure-Object
결과적으로 RDS 호스트에서 총 약 18GB를 차지하는 127개의 비활성 사용자 계정이 확인되었습니다.
이 프로필들을 모두 삭제하려면 사용자 목록을 Remove-WmiObject 명령으로 파이프하면 됩니다. 스크립트를 본격 실행하기 전에 –WhatIf 매개변수로 삭제 대상을 미리 검토하는 것이 좋습니다:
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))} | Remove-WmiObject –WhatIf
System, Network Service 같은 시스템 계정, 로컬 관리자 계정, 활성 세션이 있는 사용자 계정 등 특정 프로필을 삭제 대상에서 제외하려면 예외 목록을 추가해 스크립트를 수정할 수 있습니다:
#삭제하면 안 되는 계정 목록
$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
}
}
이 PowerShell 스크립트는 GPO의 종료 시 스크립트로 실행하거나, 작업 스케줄러(Task Scheduler)에 등록해 주기적으로 실행할 수 있습니다.
주의: 프로필 자동 삭제를 구성하기 전에 반드시 실제 운영 환경과 유사한 조건에서 스크립트를 충분히 테스트하세요!
또한 특정 AD 그룹(예: DisabledUsers 그룹)에 추가된 모든 사용자의 프로필을 자동으로 삭제하도록 스크립트를 변형할 수도 있습니다:
$users = Get-ADGroupMember -Identity DisabledUsers | Foreach {$_.Sid.Value}
$profiles = Get-WmiObject Win32_UserProfile
$profiles | Where {$users -eq $_.Sid} | Foreach {$_.Delete()}