Giải cứu ổ C Windows Server 2025: Cách dùng lệnh PowerShell dọn dẹp ổ đĩa tự động, an toàn

Tác giả: Trần Thảo 20 tháng 06, 2026

Cảnh báo Low Disk Space nhấp nháy đỏ rực trên ổ C của máy chủ Production lúc 2 giờ sáng. Dịch vụ IIS bắt đầu crash ngắt quãng vì không thể ghi thêm log, tiến trình sao lưu bị treo, và bạn thậm chí không đủ dung lượng trống để tải xuống một bản vá bảo mật khẩn cấp (Hotfix). Bạn đã từng gặp tình huống này chưa? Nếu bạn là một quản trị viên hệ thống hoặc Developer quản lý hạ tầng, đây chắc chắn là tình huống sự cố không ai muốn gặp phải. Tình trạng này kéo dài chính là nguyên nhân hàng đầu khiến VPS bị chậm, lag mà khởi động lại cũng không giải quyết được triệt để.

Thực tế, hệ điều hành Windows Server 2025 dù được tối ưu tốt đến đâu, ổ C vẫn sẽ liên tục bị ăn mòn dung lượng bởi các tiến trình hệ thống, file nhật ký truy cập (IIS Log), lỗi nén file hệ thống (CBS Log) và sự phình to không kiểm soát của kho lưu trữ thành phần (WinSxS). Việc dọn dẹp thủ công bằng giao diện Disk Cleanup không những chậm chạp mà còn bỏ sót rất nhiều dữ liệu rác ẩn. Đó là lý do bạn cần một giải pháp can thiệp sâu hơn, tự động hóa hoàn toàn bằng lệnh PowerShell dọn dẹp ổ đĩa để dọn dẹp sạch hệ thống tận gốc mà không gây rủi ro hỏng hóc dịch vụ.

Nhưng liệu bạn có đang lạm dụng các lệnh DISM trôi nổi trên mạng để rồi vĩnh viễn đánh mất khả năng khôi phục (rollback) hệ thống khi bản vá gây lỗi? Làm thế nào để viết script tự động nhận biết và dọn dẹp an toàn chuẩn xác theo đúng khuyến nghị của Microsoft? Hãy cùng bóc tách từng vấn đề kỹ thuật.

Ngoài script dọn dẹp này, bạn có thể tham khảo Cẩm nang 10 Script PowerShell hỗ trợ tự động hóa quản trị VPS Windows để giải phóng hoàn toàn thời gian bảo trì.

Infographic minh họa các nguyên nhân gây đầy ổ C trên Windows Server 2025 bao gồm IIS Log, Update Cache và WinSxS.

Những nguyên nhân thầm lặng đang làm hao hụt dung lượng ổ C của máy chủ mỗi ngày.

Tiền xử lý: Đo lường chính xác “kẻ chiếm đất” trên Windows Server 2025

Trước khi xóa bất cứ thành phần nào trên server, quy tắc kỹ thuật cơ bản là phải biết rõ mình đang thao tác với tệp tin nào và dung lượng thực tế được giải phóng là bao nhiêu. Bạn không thể chỉ nhìn vào con số báo cáo trên Windows Explorer rồi vội vàng thao tác xóa.

Trong trường hợp ổ C vật lý thực sự quá nhỏ, bạn có thể cân nhắc việc chia ổ cứng và gộp ổ cứng trên VPS Windows trước khi tiến hành dọn dẹp.

Lỗi hiển thị sai dung lượng WinSxS (cơ chế Hard Link)

Thư mục C:\Windows\WinSxS (Windows Component Store) thường là nguyên nhân số 1 bị nghi ngờ khi ổ C đầy. Nhấp chuột phải vào thư mục này, Properties có thể báo nó đang chiếm tới 15GB hoặc 20GB. Tuy nhiên, sự thật là Windows Explorer đang tính toán thiếu chính xác.

Lý do nằm ở cơ chế Hard Link (liên kết cứng) của hệ điều hành Windows. Rất nhiều file nằm trong thư mục WinSxS thực chất chỉ là các con trỏ (pointer) liên kết cứng trỏ đến các file gốc (binaries) đang thực sự lưu trữ ở những vị trí khác trong hệ thống, điển hình nhất là thư mục System32. Các file này là cốt lõi cho hoạt động của hệ điều hành và không hề chiếm thêm không gian đĩa vật lý.

Tuy nhiên, cơ chế tính toán dung lượng mặc định của File Explorer lại cực kỳ máy móc: nó cộng dồn kích thước của tất cả các file hiển thị trong thư mục, bất kể đó là file vật lý độc lập hay chỉ là Hard Link. Hậu quả là dung lượng của WinSxS luôn bị thổi phồng lên gấp nhiều lần so với thực tế.

Sơ đồ giải thích cơ chế Hard Link khiến Windows Explorer hiển thị sai dung lượng thực tế của thư mục WinSxS.

Cơ chế Hard Link khiến Windows Explorer luôn tính toán sai dung lượng thực của WinSxS.

Lệnh kiểm tra dung lượng và phân tích chuyên sâu trước khi xóa

Để nhìn thấy con số dung lượng thực sự, chúng ta phải dùng lệnh PowerShell dọn dẹp ổ đĩa kết hợp với các bộ công cụ phân tích chuẩn.

Đầu tiên, hãy kiểm tra tình trạng tổng thể dung lượng ổ C bằng Native Cmdlet của PowerShell. Mở PowerShell với quyền Administrator và gõ:

Get-CimInstance Win32_LogicalDisk | 
Where-Object {$_.DeviceID -eq "C:"} | 
Select-Object DeviceID, 
@{Name="FreeSpace(GB)";Expression={[math]::Round($_.FreeSpace/1GB,2)}}, 
@{Name="TotalSize(GB)";Expression={[math]::Round($_.Size/1GB,2)}}

Tiếp theo, để xác định dung lượng hiển thị sai của WinSxS, Microsoft cung cấp cho chúng ta một tham số cực kỳ hữu dụng của DISM. Hãy chạy lệnh sau và đợi hệ thống rà soát:

Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore

Kết quả trả về sẽ cho bạn một báo cáo cực kỳ chi tiết. Bạn chỉ cần quan tâm đến hai chỉ số để biết dung lượng hao phí thực tế (overhead) có thể dọn dẹp:

  1. Backups and disabled features (Bản sao lưu và các tính năng bị vô hiệu hóa).
  2. Cache and temporary data (Bộ nhớ đệm và dữ liệu tạm thời).

Nếu thuộc tính Component Store Cleanup Recommended báo là Yes, lúc đó chúng ta mới thực sự cần can thiệp dọn dẹp WinSxS.

Xây dựng script: Xử lý IIS Log, CBS Log và bộ ba dịch vụ cứng đầu

Sau khi đã nắm rõ tình hình, đây là lúc chúng ta bắt tay vào xử lý những tệp tin rác không cần thiết. Trên một máy chủ web production, log file chính là thứ phát triển nhanh nhất và khó kiểm soát nhất.

Quét sạch IIS Log, CBS Log và DISM Log quá hạn theo thời gian

IIS Log: Nếu server của bạn chạy web (Internet Information Services), mặc định IIS sẽ ghi nhận mọi request HTTP (GET, POST, v.v.) vào các file log lưu tại %SystemDrive%\inetpub\logs\LogFiles. Với một website có lượng truy cập lớn, mỗi tháng IIS có thể sinh ra hàng chục GB log. Đáng lo ngại hơn, IIS không hề có cơ chế tự động xoay vòng hay xóa log cũ mặc định.

CBS Log: Windows lưu trữ nhật ký cập nhật tại %systemroot%\Logs\CBS (thường là C:\Windows\Logs\CBS). Khi file cbs.log đạt dung lượng khoảng 50MB, hệ thống sẽ tự động đóng gói (nén) nó thành một file .cab. Tuy nhiên, đây là vấn đề phát sinh: nếu quá trình nén gặp lỗi (thường do file quá lớn), Windows sẽ liên tục sinh ra các file log dư thừa dung lượng lớn và không bao giờ tự xóa, có thể nuốt chửng hàng chục GB ổ đĩa.

Giải pháp là sử dụng Script PowerShell để lọc các file này theo thuộc tính LastWriteTime (Thời gian ghi lần cuối) và tự động xóa. Dưới đây là đoạn code thực chiến dọn dẹp log cũ hơn 30 ngày:

# Định nghĩa số ngày giữ lại log
$DaysToKeep = 30

# Mảng chứa các đường dẫn cần dọn dẹp
$LogPaths = @(
    "C:\inetpub\logs\LogFiles",
    "C:\Windows\Logs\CBS",
    "C:\Windows\Logs\DISM"
)

foreach ($LogPath in $LogPaths) {
    if (Test-Path $LogPath) {
        Write-Host "Đang rà soát thư mục: $LogPath" -ForegroundColor Cyan
        
        # Lọc và xóa file .log và .cab cũ hơn 30 ngày
        Get-ChildItem -Path $LogPath -Recurse -File | 
        Where-Object { 
            ($_.Extension -match "\.(log|cab)") -and 
            ($_.LastWriteTime -lt ((Get-Date).AddDays(-$DaysToKeep))) 
        } | 
        Remove-Item -Force -Verbose -ErrorAction SilentlyContinue
        
        Write-Host "Hoàn tất dọn dẹp tại: $LogPath`n" -ForegroundColor Green
    }
}

Kinh nghiệm thực chiến (Pro-tip): Riêng với thư mục CBS, bạn có thể xóa thẳng file cbs.log hiện tại (Windows sẽ tự tái tạo file mới). NHƯNG điều này chỉ thành công nếu dịch vụ Windows Modules Installer (TrustedInstaller) đang không chiếm quyền (giữ lock) file đó. Việc dùng tham số -ErrorAction SilentlyContinue giúp script bỏ qua file bị lock mà không làm gián đoạn toàn bộ tiến trình chạy ngầm.

Mẹo xử lý triệt để Windows Update Cache không bị lỗi lock file

Thư mục C:\Windows\SoftwareDistribution\Download là nơi Windows Update tải về các gói cài đặt. Sau khi vá xong, thư mục này trở thành dữ liệu dư thừa. Nhiều quản trị viên cố gắng vào thư mục này nhấn Shift+Delete hoặc dùng lệnh PowerShell Remove-Item cơ bản, kết quả là sẽ gặp phải thông báo lỗi: The action can’t be completed because the folder or a file in it is open in another program.

Nguyên nhân là do các tiến trình chạy ngầm của Windows Update vẫn đang khóa (lock) thư mục. Để xử lý triệt để, bạn cần thực hiện một kỹ thuật vô hiệu hóa tuần tự bộ 4 dịch vụ liên quan, và phương pháp đổi tên thay vì xóa.

Thực thi tuần tự đoạn script sau:

Write-Host "1. Đang ngắt các dịch vụ liên quan đến Windows Update..." -ForegroundColor Yellow
net stop wuauserv
net stop bits
net stop cryptSvc
net stop msiserver

Write-Host "2. Xử lý thư mục SoftwareDistribution an toàn..." -ForegroundColor Yellow
$SWDir = "C:\Windows\SoftwareDistribution"
$SWOldDir = "C:\Windows\SoftwareDistribution.old"

# Xóa thư mục .old cũ nếu tồn tại
if (Test-Path $SWOldDir) { Remove-Item -Path $SWOldDir -Recurse -Force }

# Đổi tên thư mục hiện tại thành .old (nhanh chóng và không bị lỗi lock file)
if (Test-Path $SWDir) { Rename-Item -Path $SWDir -NewName "SoftwareDistribution.old" }

Write-Host "3. Khởi động lại các dịch vụ hệ thống..." -ForegroundColor Yellow
net start wuauserv
net start bits
net start cryptSvc
net start msiserver

Write-Host "4. Xóa thư mục .old trong background..." -ForegroundColor Yellow
# Bước này có thể để chạy nền hoặc chạy trong chu kỳ tiếp theo
Remove-Item -Path $SWOldDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Dọn dẹp Windows Update Cache thành công!" -ForegroundColor Green

Việc đổi tên thư mục thành .old là một giải pháp cực kỳ an toàn. Nó diễn ra ngay lập tức, giải phóng lock, và hệ điều hành sẽ tự động tạo một thư mục SoftwareDistribution mới, sạch sẽ khi dịch vụ khởi động lại.

Sơ đồ 4 bước dùng PowerShell ngắt dịch vụ và đổi tên thư mục SoftwareDistribution để tránh lỗi lock file.

Quy trình 4 bước vô hiệu hóa dịch vụ để dọn sạch Windows Update Cache mà không gây lỗi hệ thống.

Dọn dẹp WinSxS an toàn: Lệnh PowerShell dọn dẹp ổ đĩa gọi Task StartComponentCleanup thay vì DISM /ResetBase

Đây là phần tối quan trọng, nơi phân định rõ ranh giới giữa một quản trị viên hệ thống mới vào nghề và một chuyên gia hệ thống lão luyện. WinSxS (Component Store) phình to vì nó lưu lại mọi phiên bản cũ của các file hệ thống đã được cập nhật. Mục đích là để bạn có thể gỡ cài đặt (rollback) bản vá nếu bản vá đó gây ra lỗi Màn hình xanh (BSOD) hoặc làm hỏng ứng dụng.

Hiểm họa từ tham số /ResetBase trên môi trường Production

Nếu tìm kiếm cách dọn WinSxS, 90% các bài viết sẽ khuyên bạn chạy lệnh này:

DISM /Online /Cleanup-Image /StartComponentCleanup /ResetBase

⚠️ CẢNH BÁO:

Lệnh trên kết hợp với tham số /ResetBase sẽ loại bỏ triệt để mọi phiên bản bản cập nhật đã bị thay thế (superseded) ngay lập tức. Hệ quả là: Bạn giải phóng được dung lượng lớn nhất, NHƯNG bạn sẽ vĩnh viễn mất khả năng gỡ bỏ các bản cập nhật đã cài đặt trước đó.

Nếu ngày mai, Microsoft xác nhận bản vá vừa cài làm crash dịch vụ Web IIS hoặc SQL Server của bạn, bạn không thể khôi phục lại trạng thái cũ. Bạn bị chặn đường lùi hoàn toàn. Tham số này CHỈ DÙNG khi bạn đang build một bản image mẫu để triển khai hàng loạt, tuyệt đối không lạm dụng trên máy chủ đang chạy Production.

Giải pháp chuẩn hóa: Trigger Scheduled Task ẩn của Microsoft

Thay vì lạm dụng tham số rủi ro, Microsoft đã thiết kế sẵn một cơ chế dọn dẹp cực kỳ thông minh và an toàn: một Scheduled Task ẩn mang tên StartComponentCleanup.

Điều làm nên sự khác biệt của Task này là Thời gian ân hạn (Grace Period 30 ngày). Khi bạn kích hoạt task này, nó sẽ rà soát WinSxS và dọn dẹp các thành phần cũ, nhưng nó CHỈ XÓA những phiên bản cũ của bản cập nhật khi bản cập nhật mới đã nằm ổn định trên hệ thống tối thiểu 30 ngày. Điều này đảm bảo rằng trong vòng 1 tháng đầu kể từ khi cập nhật, bạn vẫn giữ lại đường lùi an toàn nếu có sự cố xảy ra.

Đây chính là lúc bạn dùng lệnh PowerShell dọn dẹp ổ đĩa để kích hoạt task này một cách chủ động:

Gọi Scheduled Task chuẩn của Microsoft để dọn WinSxS an toàn:

schtasks.exe /Run /TN "\Microsoft\Windows\Servicing\StartComponentCleanup"

Hoặc dùng cmdlet native của PowerShell:

Start-ScheduledTask -TaskPath "\Microsoft\Windows\Servicing\" -TaskName "StartComponentCleanup"

Lệnh này sẽ ra lệnh cho Task chạy ngầm. Quá trình này có thể mất từ 15 đến 45 phút tùy thuộc vào lượng bản vá dồn ứ, và không hề gây gián đoạn dịch vụ.

Infographic so sánh rủi ro của lệnh dọn dẹp DISM ResetBase và sự an toàn của tác vụ StartComponentCleanup.

Tuyệt đối không lạm dụng tham số /ResetBase trên môi trường Production nếu không muốn vô hiệu hóa khả năng khôi phục hệ thống.

Bảng so sánh các phương pháp dọn WinSxS:

Phương pháp Lệnh thực thi Độ an toàn Giữ khả năng gỡ bản vá (Rollback)
Scheduled Task (khuyên dùng) schtasks /Run /TN "\Microsoft\Windows\Servicing\StartComponentCleanup" ✅ Cực cao ✅ Có (Giữ Grace period 30 ngày)
DISM tiêu chuẩn DISM /Online /Cleanup-Image /StartComponentCleanup ⚠️ Trung bình ❌ Xóa ngay (Không có Grace period)
DISM ResetBase DISM ... /StartComponentCleanup /ResetBase ❌ Nguy hiểm ❌ KHÔNG (Khóa vĩnh viễn trạng thái hiện tại)

Triển khai tự động hóa 100% bằng PowerShell Native Cmdlets

Quản trị viên xuất sắc không giải quyết cùng một vấn đề hai lần. Đừng chạy script thủ công mỗi khi ổ cứng cảnh báo đầy, hãy tự động hóa nó.

Thay vì dùng giao diện Task Scheduler GUI cơ bản hoặc lệnh schtasks truyền thống, Windows Server 2025 hỗ trợ bộ Native PowerShell Cmdlets mạnh mẽ để thiết lập quy trình. Giả sử bạn muốn gộp tất cả các thao tác dọn IIS Log, CBS Log, Update Cache và gọi Task WinSxS vào một file script (ví dụ: C:\Scripts\ServerCleanup.ps1).

Ngoài script dọn dẹp này, bạn có thể tham khảo danh sách 5 Scripts PowerShell hỗ trợ tự động hóa quản trị VPS Windows để giải phóng hoàn toàn thời gian bảo trì.

Dưới đây là khối lệnh PowerShell giúp bạn tự động đăng ký một tác vụ chạy ngầm định kỳ hàng tuần (vào lúc 2:00 sáng Chủ Nhật) dưới quyền hệ thống cao nhất (SYSTEM), đảm bảo không vướng mắc vấn đề phân quyền.

Chạy khối lệnh này một lần duy nhất với quyền Administrator:

# 1. Định nghĩa hành động: Chạy file script PowerShell với quyền vượt chính sách (Bypass)
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"C:\Scripts\ServerCleanup.ps1`""

# 2. Định nghĩa lịch trình (Trigger): Chạy lúc 2:00 AM sáng Chủ nhật hàng tuần
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 2:00AM

# 3. Định nghĩa chủ thể thực thi: Chạy dưới quyền tài khoản "SYSTEM" cấp cao nhất
$Principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest

# 4. Đăng ký tác vụ vào hệ thống
Register-ScheduledTask -TaskName "Weekly-System-Cleanup" -Action $Action -Trigger $Trigger -Principal $Principal -Description "Tự động dọn dẹp ổ C, IIS Log, Update Cache và an toàn thu gọn WinSxS"

Write-Host "Đăng ký thành công Task tự động dọn dẹp hàng tuần!" -ForegroundColor Green

Kể từ thời điểm này, vào mỗi 2 giờ sáng Chủ Nhật, kịch bản lệnh PowerShell dọn dẹp ổ đĩa của bạn sẽ âm thầm kích hoạt, ngắt các dịch vụ cần thiết, xử lý các file log quá hạn, giải phóng Windows Update Cache và kích hoạt dọn WinSxS một cách tối ưu.

Sơ đồ luồng tự động hóa chạy script PowerShell dọn dẹp máy chủ hàng tuần bằng Task Scheduler.

Biến việc bảo trì máy chủ thành quy trình tự động 100% chỉ với một lần cấu hình Script.

Câu hỏi thường gặp (FAQ)

1. Tại sao WinSxS báo dung lượng khổng lồ trên Explorer nhưng bài viết khuyên không nên xóa bừa?

Do cơ chế Hard Link. Windows Explorer tính toán máy móc bằng cách cộng dồn cả các liên kết ảo trỏ về file gốc, khiến dung lượng bị thổi phồng. Để biết dung lượng hao phí thật, hãy chạy lệnh DISM /Online /Cleanup-Image /AnalyzeComponentStore.

2. Có nên dùng lệnh DISM /ResetBase để dọn hệ thống cho hoàn toàn trống không?

TUYỆT ĐỐI KHÔNG dùng trên server Production. Nó dọn dẹp rất triệt để nhưng sẽ vô hiệu hóa khả năng khôi phục, tước vĩnh viễn quyền gỡ cài đặt bản vá của bạn. Nếu cập nhật gây crash Windows, bạn không còn khả năng khôi phục lại trạng thái cũ. Hãy dùng task StartComponentCleanup để giữ an toàn trong 30 ngày.

3. Tại sao tôi xóa thư mục Windows Update Cache toàn bị lỗi File in use?

Do các dịch vụ ngầm đang giữ lock file. Bạn phải ngắt đủ 4 dịch vụ (wuauserv, bits, cryptsvc, msiserver). Phương pháp hiệu quả: Đừng xóa thẳng, hãy đổi tên thành SoftwareDistribution.old, khởi động lại dịch vụ rồi thực hiện xóa thư mục .old sau.

4. Windows Server 2025 có tự động xóa IIS Log không?

KHÔNG. IIS sẽ liên tục ghi log cho đến khi server ngừng hoạt động vì hết dung lượng ổ cứng. Bạn bắt buộc phải cấu hình script lọc ngày (ví dụ: > 30 ngày) để hệ thống tự xử lý.

5. Làm sao để chạy lệnh powershell dọn dẹp ổ đĩa này tự động mỗi tuần?

Thêm script vào Task Scheduler. Dùng bộ cmdlet chuẩn (New-ScheduledTaskAction, Register-ScheduledTask) thiết lập lịch chạy ngầm lúc 2h sáng Chủ Nhật dưới quyền cao nhất là SYSTEM. Hoàn tất rà soát sẽ tự động kết thúc, bạn không cần can thiệp thủ công.

Kết luận

Việc duy trì không gian lưu trữ ổn định cho phân vùng hệ điều hành trên Windows Server 2025 không chỉ đơn thuần là xóa các file dư thừa, mà là một kỹ thuật quản trị hạ tầng chuyên sâu. Thông qua việc thấu hiểu cơ chế Hard Link, nắm rõ vòng đời của các file log (IIS, CBS) và đặc biệt là nhận thức được ranh giới an toàn khi xử lý kho WinSxS, bạn đã sở hữu trong tay phương pháp luận chuẩn xác nhất.

Hãy triển khai ngay lệnh PowerShell dọn dẹp ổ đĩa và tích hợp chúng vào Task Scheduler để đưa hệ thống vào trạng thái tự động bảo trì. Tuy nhiên, để chủ động hơn trước khi hệ thống cảnh báo đầy, bạn nên thiết lập hệ thống cảnh báo Telegram thông qua script PowerShell giám sát VPS để phát hiện sớm các bất thường về dung lượng.

Tài liệu tham khảo