Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы

Картина знакомая до боли: системный диск сервера забит под завязку, хотя вы туда ничего не клали. Открываешь проводник — и сразу всё ясно: папка C:\Windows\SoftwareDistribution тянет на 18 ГБ, WinSxS перевалил за 20 ГБ, Temp раздулся непонятно чем и непонятно когда. Стандартная Очистка диска (cleanmgr.exe) в таких случаях почти бесполезна — а на серверах её возможностей не хватает вовсе. Дальше — полный арсенал PowerShell-инструментов для системной очистки. Без лишних кликов и без риска положить обновления.
Почему системный диск заполняется сам по себе
Windows Server копит мусор сразу из нескольких мест — и делает это тихо, годами:
- SoftwareDistribution\Download — сюда Windows Update сбрасывает пакеты перед установкой. В теории после успешной установки файлы должны сами удаляться. На практике — при любом сбое или прерванной сессии они остаются там навсегда.
- WinSxS (Component Store) — хранилище компонентов ОС. Здесь живут предыдущие версии компонентов на случай отката. Каждое крупное обновление добавляет своё, и папка только растёт.
- catroot2 — кэш подписей криптографических каталогов. Если он повреждается или слишком разрастается, новые обновления просто перестают устанавливаться.
- Temp и %TEMP% — системная и пользовательская временные папки. Приложения пишут туда файлы исправно, а вот убирают за собой — далеко не всегда.
- Prefetch — кэш предзагрузки приложений. На десктопах от него есть толк, на серверах — практически никакого, но место занимает исправно.
Диагностика: что именно ест место
Прежде чем что-то чистить — смотрим реальные размеры подозреваемых папок. PowerShell делает это одной командой:
# Размер ключевых системных папок (в ГБ)
$paths = @(
"C:\Windows\SoftwareDistribution\Download",
"C:\Windows\WinSxS",
"C:\Windows\System32\catroot2",
"C:\Windows\Temp",
"$env:TEMP"
)
foreach ($p in $paths) {
if (Test-Path $p) {
$size = (Get-ChildItem $p -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum / 1GB
Write-Host ("{0,-50} {1:N2} GB" -f $p, $size)
}
}
Запускайте от администратора. Сразу увидите, кто главный виновник.
Быстро проверить свободное место на всех дисках:
Get-PSDrive -PSProvider FileSystem |
Select-Object Name,
@{N='Used GB';E={[math]::Round($_.Used/1GB,1)}},
@{N='Free GB';E={[math]::Round($_.Free/1GB,1)}},
@{N='Total GB';E={[math]::Round(($_.Used+$_.Free)/1GB,1)}} |
Format-Table -AutoSize
Очистка кэша Windows Update через PowerShell
Кэш обновлений — первый подозреваемый в 80% случаев. Схема простая: останавливаем зависимые службы, переименовываем папки — Windows сам пересоздаст их пустыми — и поднимаем службы обратно.
# Остановка служб Windows Update
$services = 'wuauserv','bits','cryptsvc','msiserver'
foreach ($svc in $services) {
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
Write-Host "Остановлена: $svc"
}
# Переименовываем папки кэша (с меткой времени, чтобы можно было откатить)
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$sd = "C:\Windows\SoftwareDistribution"
$cr = "C:\Windows\System32\catroot2"
if (Test-Path $sd) { Rename-Item $sd "${sd}_bak_$ts" }
if (Test-Path $cr) { Rename-Item $cr "${cr}_bak_$ts" }
# Запускаем службы обратно
foreach ($svc in $services) {
Start-Service -Name $svc -ErrorAction SilentlyContinue
Write-Host "Запущена: $svc"
}
Write-Host "Готово. Windows Update создаст новые папки при следующей проверке."
_bak_ можно удалить через неделю, убедившись, что обновления работают нормально.Сжатие хранилища компонентов WinSxS
Папку WinSxS удалять нельзя — это хранилище компонентов ОС, без него система не взлетит. Но её можно безопасно ужать через встроенную утилиту DISM: команда вырезает устаревшие версии компонентов, которые уже не нужны для отката.
# Анализ — сколько можно освободить (не удаляет ничего)
Dism.exe /Online /Cleanup-Image /AnalyzeComponentStore
# Фактическая очистка (требует перезагрузки на некоторых версиях)
Dism.exe /Online /Cleanup-Image /StartComponentCleanup
# Агрессивный вариант — удаляет пакеты обновлений (нельзя откатиться)
Dism.exe /Online /Cleanup-Image /StartComponentCleanup /ResetBase
/ResetBase необратим — после него откатить установленные обновления будет невозможно. Используйте только на серверах, которые прошли тестирование и стабильно работают.На Windows Server 2019/2022 DISM с StartComponentCleanup в нашей практике стабильно освобождает 2–6 ГБ. Никакого риска — только терпение, процесс небыстрый.
Удаление временных файлов (Temp и %TEMP%)
Временные папки чистить можно и нужно — но только когда нет активных пользовательских сессий. Заблокированные файлы иначе посыплются ошибками. Скрипт удаляет всё доступное и молча обходит заблокированные файлы:
# Очистка системного Temp
Get-ChildItem "C:\Windows\Temp" -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
# Очистка пользовательского Temp (текущего пользователя)
Get-ChildItem $env:TEMP -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
# Очистка Temp всех профилей (запускать от SYSTEM или локального администратора)
$profiles = Get-ChildItem "C:\Users" -Directory
foreach ($profile in $profiles) {
$tempPath = Join-Path $profile.FullName "AppData\Local\Temp"
if (Test-Path $tempPath) {
Get-ChildItem $tempPath -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Очищен Temp для профиля: $($profile.Name)"
}
}
Очистка Prefetch и журналов событий
Папка Prefetch на серверах — рудимент, она нужна десктопам. Журналы событий — другая история: без настроенной ротации они легко разрастаются до сотен мегабайт, и никто этого не замечает месяцами.
# Очистка Prefetch (опционально, только если есть веская причина)
$prefetch = "C:\Windows\Prefetch"
if (Test-Path $prefetch) {
Get-ChildItem $prefetch -Force -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
Write-Host "Prefetch очищен"
}
# Проверка размера журналов событий
Get-WinEvent -ListLog * -ErrorAction SilentlyContinue |
Where-Object { $_.FileSize -gt 50MB } |
Select-Object LogName,
@{N='Size MB';E={[math]::Round($_.FileSize/1MB,1)}},
MaximumSizeInBytes |
Sort-Object 'Size MB' -Descending |
Format-Table -AutoSize
# Очистка конкретного журнала (пример: Application)
wevtutil cl Application
Оптимизация тома: TRIM для SSD, дефрагментация для HDD
После очистки файлов — оптимизация тома. Командлет Optimize-Volume сам разберётся, что нужно диску: дефрагментация или TRIM:
# Анализ всех томов
Get-Volume | Where-Object { $_.DriveLetter } |
ForEach-Object {
Optimize-Volume -DriveLetter $_.DriveLetter -Analyze -Verbose
}
# Оптимизация системного диска
# Для SSD — выполняет TRIM (ReTrim)
# Для HDD — выполняет дефрагментацию
Optimize-Volume -DriveLetter C -ReTrim -Verbose
# Принудительная дефрагментация HDD (если Analyze рекомендует)
Optimize-Volume -DriveLetter D -Defrag -Verbose
На виртуальных машинах — Hyper-V, VMware — дополнительно запустите -SlabConsolidate. Это реально уменьшает физический размер динамических VHDX-дисков на хосте:
Optimize-Volume -DriveLetter C -SlabConsolidate -Verbose
Автоматизация: планировщик задач для регулярной очистки
Разовая чистка — это полумера, через месяц всё вернётся. Правильный подход — повесить скрипт на расписание. Создаём задачу с еженедельным запуском в ночное время:
# Сохраняем скрипт очистки
$scriptContent = @'
# Cleanup script - auto maintenance
$services = 'wuauserv','bits','cryptsvc'
$services | ForEach-Object { Stop-Service $_ -Force -EA SilentlyContinue }
$ts = Get-Date -Format "yyyyMMdd"
$sd = "C:\Windows\SoftwareDistribution"
if (Test-Path $sd) {
$free = (Get-PSDrive C).Free / 1GB
if ($free -lt 10) { # чистим только если меньше 10 ГБ свободно
Rename-Item $sd "${sd}_bak_$ts" -EA SilentlyContinue
}
}
$services | ForEach-Object { Start-Service $_ -EA SilentlyContinue }
Get-ChildItem "C:\Windows\Temp" -Recurse -Force -EA SilentlyContinue |
Remove-Item -Recurse -Force -EA SilentlyContinue
# Удаляем старые бэкапы SoftwareDistribution (старше 14 дней)
Get-ChildItem "C:\Windows" -Filter "SoftwareDistribution_bak_*" -Directory |
Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-14) } |
Remove-Item -Recurse -Force -EA SilentlyContinue
'@
$scriptPath = "C:\Scripts\WeeklyCleanup.ps1"
New-Item -ItemType Directory -Path "C:\Scripts" -Force | Out-Null
$scriptContent | Out-File $scriptPath -Encoding UTF8
# Регистрируем задачу в планировщике
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NonInteractive -ExecutionPolicy Bypass -File `"$scriptPath`""
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At "03:00"
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
-RunOnlyIfIdle $false -StartWhenAvailable
Register-ScheduledTask -TaskName "WeeklyDiskCleanup" `
-Action $action -Trigger $trigger -Settings $settings `
-RunLevel Highest -User "SYSTEM" -Force
Write-Host "Задача WeeklyDiskCleanup зарегистрирована."
if ($free -lt 10) — очистка SoftwareDistribution запускается только если свободного места осталось меньше 10 ГБ. Это снижает нагрузку в штатных условиях и при этом гарантирует срабатывание в критических ситуациях.Полный скрипт: единая точка входа
Все шаги собраны в одном скрипте — с проверкой прав администратора и отчётом о занятом месте до и после:
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Комплексная очистка диска Windows Server
.DESCRIPTION
Очищает кэш Windows Update, Temp, Prefetch, запускает DISM и оптимизацию тома.
#>
function Get-FolderSize($path) {
if (-not (Test-Path $path)) { return 0 }
(Get-ChildItem $path -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
}
$drive = "C"
$freeBefore = (Get-PSDrive $drive).Free
Write-Host "=== Начало очистки ===" -ForegroundColor Cyan
Write-Host "Свободно до: $([math]::Round($freeBefore/1GB,2)) ГБ"
# 1. Остановка служб обновления
$svcs = 'wuauserv','bits','cryptsvc','msiserver'
$svcs | ForEach-Object { Stop-Service $_ -Force -EA SilentlyContinue }
# 2. Сброс кэша обновлений
$ts = Get-Date -Format "yyyyMMdd_HHmm"
@("C:\Windows\SoftwareDistribution","C:\Windows\System32\catroot2") | ForEach-Object {
if (Test-Path $_) { Rename-Item $_ "${_}_bak_$ts" -EA SilentlyContinue }
}
# 3. Запуск служб
$svcs | ForEach-Object { Start-Service $_ -EA SilentlyContinue }
# 4. Очистка Temp
@("C:\Windows\Temp", $env:TEMP) | ForEach-Object {
Get-ChildItem $_ -Recurse -Force -EA SilentlyContinue |
Remove-Item -Recurse -Force -EA SilentlyContinue
}
# 5. DISM: очистка хранилища компонентов
Write-Host "Запуск DISM /StartComponentCleanup..." -ForegroundColor Yellow
Dism.exe /Online /Cleanup-Image /StartComponentCleanup /Quiet
# 6. Оптимизация тома
Optimize-Volume -DriveLetter $drive -ReTrim -EA SilentlyContinue
$freeAfter = (Get-PSDrive $drive).Free
$freed = [math]::Round(($freeAfter - $freeBefore)/1GB, 2)
Write-Host "=== Готово ===" -ForegroundColor Green
Write-Host "Свободно после: $([math]::Round($freeAfter/1GB,2)) ГБ"
Write-Host "Освобождено: +$freed ГБ" -ForegroundColor Green
Что делать, если диск снова заполняется быстро
Если через неделю-две диск снова забит — проблема глубже, и просто чисткой её не решить. Вот с чего начинать диагностику:
- Проверьте, не ушли ли обновления в бесконечный цикл загрузки:
Get-WindowsUpdateLogвыгрузит ошибки вC:\Windows\Logs\WindowsUpdate\— там сразу видно, если что-то застряло. - Загляните в
C:\Windows\Logs\CBS\CBS.log— там хранится история установки компонентов, и зависшие операции видны невооружённым глазом. - Проверьте дампы памяти — они умеют весить гигабайтами и годами лежать никем не замеченными:
Get-ChildItem C:\Windows\Minidump,C:\Windows\MEMORY.DMP -EA SilentlyContinue | Measure-Object Length -Sum. - Если на сервере крутится IIS — обязательно проверьте
C:\inetpub\logs\LogFiles. При нагруженном сайте логи там накапливаются гигабайтами буквально за несколько дней. - Не забудьте про теневые копии VSS:
vssadmin list shadowstorage. Встречали серверы, где VSS молча съедал 15–20% диска — и никто об этом не знал.
# Проверка VSS / теневых копий
vssadmin list shadowstorage
vssadmin list shadows
# Ограничение хранилища VSS (максимум 5 ГБ)
vssadmin resize shadowstorage /For=C: /On=C: /MaxSize=5GB
# Проверка дампов памяти
Get-ChildItem C:\Windows -Filter "*.dmp" -Recurse -ErrorAction SilentlyContinue |
Sort-Object Length -Descending |
Select-Object FullName,
@{N='Size MB';E={[math]::Round($_.Length/1MB,1)}},
LastWriteTime |
Format-Table -AutoSize
Официальная документация: Microsoft Learn — Windows Server, Microsoft Learn — PowerShell
Часто задаваемые вопросы
Что такое Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы?
Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы — это важный аспект системного администрирования, который позволяет настроить и оптимизировать работу IT-инфраструктуры. В данной статье подробно рассматриваются все ключевые моменты.
Как правильно настроить Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы?
Для корректной настройки Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы необходимо следовать пошаговой инструкции, представленной в статье выше. Важно учитывать особенности вашей инфраструктуры и требования безопасности.
Какие типичные ошибки возникают при работе с Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы?
Наиболее частые ошибки при работе с Очистка диска Windows Server: удаляем мусор Windows Update и временные файлы: некорректная конфигурация, недостаточные права доступа и несовместимость версий. Рекомендуем обратиться к специалистам ITFresh для профессиональной настройки.
ООО «АйТи Фреш» возьмёт это на себя
Не хватает времени или своих специалистов — мы настроим, оптимизируем и возьмём вашу IT-инфраструктуру на постоянное сопровождение. Работаем с юридическими лицами в Москве и регионах. Собственный дата-центр, команда из 8 серверов Dell Xeon Platinum 8280 на базе МТС.
Комментарии