Практика / рабочие места
Как применять материал
Материал стоит воспринимать как короткий runbook: сначала сохранить рабочее состояние, затем проверить симптом, выполнить минимально достаточное исправление и зафиксировать результат. Так единичная проблема не превращается в бесконечную переписку.
Практический порядок
- открыть PowerShell от имени администратора и сохранить рабочие документы
- запустить скрипт в стандартном режиме: он создаст лог, проверит DISM/SFC и очистит только старые временные файлы
- если есть явные проблемы Windows Update, повторить запуск с ResetWindowsUpdateCache=true
- после перезагрузки проверить журнал, Windows Update и исходный симптом
Улучшенный PowerShell-скрипт
Скопируйте код в файл, например `WDI-WindowsRepair.ps1`, запустите PowerShell от имени администратора и выполните скрипт. Сброс кэша Windows Update выключен по умолчанию; временные файлы удаляются только если они старше заданного возраста. Для более жесткого сценария используйте параметр `-ResetWindowsUpdateCache $true`.
<#
WDI Windows Repair / Health Check
Запускать в PowerShell от имени администратора.
Что делает:
- проверяет состояние образа Windows через DISM;
- запускает восстановление DISM RestoreHealth;
- проверяет системные файлы через SFC;
- пишет подробный лог;
- очищает только старые временные файлы;
- опционально сбрасывает кэш Windows Update.
#>
[CmdletBinding()]
param(
[bool]$CreateRestorePoint = $true,
[bool]$CleanTemp = $true,
[int]$TempOlderThanDays = 2,
[bool]$ResetWindowsUpdateCache = $false,
[string]$LogPath = "$env:SystemDrive\WDI-WindowsRepair"
)
$ErrorActionPreference = "Continue"
$principal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw "Запустите PowerShell от имени администратора."
}
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$transcriptPath = Join-Path $LogPath "windows-repair-$stamp.log"
function Write-Step {
param([Parameter(Mandatory)][string]$Message)
Write-Host ""
Write-Host "== $Message ==" -ForegroundColor Cyan
}
function Invoke-LoggedProcess {
param(
[Parameter(Mandatory)][string]$FilePath,
[Parameter(Mandatory)][string[]]$Arguments,
[Parameter(Mandatory)][string]$Name
)
Write-Step $Name
$process = Start-Process -FilePath $FilePath -ArgumentList $Arguments -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
Write-Warning "$Name завершился с кодом $($process.ExitCode). Проверьте лог."
}
}
Start-Transcript -Path $transcriptPath -Force | Out-Null
try {
if ($CreateRestorePoint) {
Write-Step "Создание точки восстановления"
try {
Checkpoint-Computer -Description "Before WDI Windows repair $stamp" -RestorePointType "MODIFY_SETTINGS"
} catch {
Write-Warning "Точка восстановления не создана: $($_.Exception.Message)"
}
}
Write-Step "Информация о системе"
if (Get-Command Get-ComputerInfo -ErrorAction SilentlyContinue) {
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsBuildNumber, OsArchitecture | Format-List
} else {
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, OSArchitecture | Format-List
}
Invoke-LoggedProcess -FilePath "dism.exe" -Arguments @("/Online", "/Cleanup-Image", "/CheckHealth") -Name "DISM CheckHealth"
Invoke-LoggedProcess -FilePath "dism.exe" -Arguments @("/Online", "/Cleanup-Image", "/ScanHealth") -Name "DISM ScanHealth"
Invoke-LoggedProcess -FilePath "dism.exe" -Arguments @("/Online", "/Cleanup-Image", "/RestoreHealth") -Name "DISM RestoreHealth"
Invoke-LoggedProcess -FilePath "sfc.exe" -Arguments @("/scannow") -Name "SFC /scannow"
if ($ResetWindowsUpdateCache) {
Write-Step "Сброс кэша Windows Update"
foreach ($service in @("wuauserv", "bits", "cryptsvc")) {
Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
}
foreach ($folder in @(
(Join-Path $env:SystemRoot "SoftwareDistribution"),
(Join-Path $env:SystemRoot "System32\catroot2")
)) {
if (Test-Path -LiteralPath $folder) {
$backupName = "$(Split-Path $folder -Leaf).old-$stamp"
Rename-Item -LiteralPath $folder -NewName $backupName -ErrorAction SilentlyContinue
Write-Host "Папка переименована: $folder -> $backupName"
}
}
foreach ($service in @("cryptsvc", "bits", "wuauserv")) {
Start-Service -Name $service -ErrorAction SilentlyContinue
}
}
if ($CleanTemp) {
Write-Step "Очистка старых временных файлов"
$cutoff = (Get-Date).AddDays(-[Math]::Abs($TempOlderThanDays))
$tempRoots = @(
(Join-Path $env:SystemRoot "Temp"),
$env:TEMP
) | Where-Object { $_ -and (Test-Path -LiteralPath $_) }
$profiles = Get-CimInstance Win32_UserProfile | Where-Object {
-not $_.Special -and $_.LocalPath -and (Test-Path -LiteralPath $_.LocalPath)
}
foreach ($profile in $profiles) {
$profileTemp = Join-Path $profile.LocalPath "AppData\Local\Temp"
if (Test-Path -LiteralPath $profileTemp) {
$tempRoots += $profileTemp
}
}
foreach ($root in ($tempRoots | Select-Object -Unique)) {
Write-Host "Очистка: $root"
Get-ChildItem -LiteralPath $root -Force -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt $cutoff } |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
Write-Step "Финальная быстрая проверка"
dism.exe /Online /Cleanup-Image /CheckHealth
Write-Host ""
Write-Host "Лог сохранен: $transcriptPath"
Write-Host "Рекомендация: перезагрузите ПК и проверьте Windows Update / Event Viewer."
} finally {
Stop-Transcript | Out-Null
}
Важно: перед запуском проверьте код под свою задачу, сохраните важные данные и не используйте административные скрипты из интернета без понимания каждого действия.
Что проверить перед внедрением
- скрипт не запускается без прав администратора
- лог сохраняется в отдельную папку на системном диске
- временные файлы удаляются только если они старше заданного количества дней
- сброс кэша Windows Update выключен по умолчанию и включается отдельным параметром
Итог: Windows проверена по шагам, результаты записаны в лог, а рискованные действия отделены параметрами и не выполняются молча.