Блог / 1 декабря 2024 г.

Скрипт PowerShell для проверки и устранения ошибок в ОС Windows

Готовый PowerShell-скрипт для безопасной проверки Windows: DISM, SFC, логирование, старая временная очистка и опциональный сброс кэша обновлений.

Для кого администратор или руководитель офиса
Главный риск локальная проблема быстро превращается в простой сотрудника, если нет фиксации симптома и проверки результата
На выходе Windows проверена по шагам, результаты записаны в лог, а рискованные действия отделены параметрами и не выполняются молча.

Практика / рабочие места

Как применять материал

Материал стоит воспринимать как короткий runbook: сначала сохранить рабочее состояние, затем проверить симптом, выполнить минимально достаточное исправление и зафиксировать результат. Так единичная проблема не превращается в бесконечную переписку.

01 Симптом
02 Диагностика
03 Исправление
04 Контроль

Практический порядок

  1. открыть PowerShell от имени администратора и сохранить рабочие документы
  2. запустить скрипт в стандартном режиме: он создаст лог, проверит DISM/SFC и очистит только старые временные файлы
  3. если есть явные проблемы Windows Update, повторить запуск с ResetWindowsUpdateCache=true
  4. после перезагрузки проверить журнал, Windows Update и исходный симптом

Улучшенный PowerShell-скрипт

Совместимость: Windows 10/11, Windows Server 2016-2025; PowerShell 5.1 или PowerShell 7; запуск от администратора.

Скопируйте код в файл, например `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 проверена по шагам, результаты записаны в лог, а рискованные действия отделены параметрами и не выполняются молча.

Исходный материал Сохраненная версия статьи и дополнительные детали
Скрипт выполняет проверку и восстановление системных файлов Windows, очищает временные файлы и управляет службой обновления Windows. Он автоматически обрабатывает ошибки на каждом этапе выполнения. Этот скрипт на PowerShell состоит из следующих этапов: Проверка прав администратора: Убедится, что скрипт запущен с правами администратора. Если права недостаточны, завершает выполнение с предупреждением. Управление службой обновления Windows: Остановка службы обновления Windows (wuauserv) перед выполнением операций восстановления, чтобы избежать конфликтов. Перезапуск службы обновления Windows в конце, чтобы система могла продолжить проверку обновлений. Проверка и восстановление системных файлов: Выполняет проверку целостности системного образа Windows с помощью DISM: CheckHealth: Быстрая проверка состояния образа. RestoreHealth: Восстановление повреждённого системного образа. Использует SFC для проверки и восстановления системных файлов. Очистка временных файлов: Удаляет временные файлы в системных каталогах: Системный каталог C:\Windows\Temp. Временные файлы текущего пользователя C:\Users\<Имя>\AppData\Local\Temp. Для каждого профиля пользователя, кроме системных, выполняет очистку временных файлов из папки Temp. Обработка ошибок: Каждый этап обёрнут в конструкцию try-catch для предотвращения полного завершения скрипта при возникновении ошибок. Выводит информативные сообщения в случае возникновения проблем, чтобы пользователь мог диагностировать ситуацию. Сообщения для пользователя: Каждый шаг сопровождается информацией в консоли, чтобы пользователь понимал, что происходит в данный момент. Для чего предназначен скрипт Скрипт полезен для: Восстановления стабильности операционной системы. Устранения проблем с системными файлами и обновлениями. Очистки временных файлов для освобождения места и улучшения производительности. Примечание Перед использованием рекомендуется сохранить данные и протестировать скрипт в тестовой среде, чтобы избежать потери важной информации. Скрипт: # Проверяем права администратораif (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Warning "Скрипт должен быть запущен с правами администратора!" Exit} # Останавливаем службу обновления Windowstry { Write-Host "Останавливаем службу обновления Windows..." Stop-Service -Name wuauserv -Force -ErrorAction Stop} catch { Write-Warning "Не удалось остановить службу обновления Windows: $_"} # Проверка целостности образа Windows с помощью DISMWrite-Host "Проверка целостности образа Windows с помощью DISM..."try { Start-Process -FilePath "dism.exe" -ArgumentList "/Online /Cleanup-Image /CheckHealth" -Wait -NoNewWindow} catch { Write-Warning "Ошибка при выполнении проверки целостности образа: $_"} # Восстановление образа Windows с помощью DISMWrite-Host "Восстановление образа Windows с помощью DISM..."try { Start-Process -FilePath "dism.exe" -ArgumentList "/Online /Cleanup-Image /RestoreHealth" -Wait -NoNewWindow} catch { Write-Warning "Ошибка при восстановлении образа: $_"} # Проверка целостности системных файловWrite-Host "Проверка целостности системных файлов..."try { Start-Process -FilePath "sfc.exe" -ArgumentList "/scannow" -Wait -NoNewWindow} catch { Write-Warning "Ошибка при проверке системных файлов: $_"} # Очистка временных файловWrite-Host "Очистка временных файлов..."try { Remove-Item -Path "$env:SystemRoot\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "$env:USERPROFILE\AppData\Local\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue} catch { Write-Warning "Ошибка при очистке временных файлов: $_"} # Получаем список профилей пользователей$userProfiles = Get-CimInstance Win32_UserProfile | Where-Object { $_.Special -ne $true } foreach ($profile in $userProfiles) { try { # Путь к временным файлам текущего пользователя $tempPath = Join-Path -Path $profile.LocalPath -ChildPath "AppData\Local\Temp\*" Write-Host "Очистка временных файлов для пользователя $($profile.LocalPath)" Remove-Item -Path $tempPath -Recurse -Force -ErrorAction SilentlyContinue } catch { Write-Warning "Ошибка при очистке временных файлов для пользователя $($profile.LocalPath): $_" }} # Перезапуск службы обновления Windowstry { Write-Host "Перезапуск службы обновления Windows..." Start-Service -Name wuauserv -ErrorAction Stop} catch { Write-Warning "Не удалось перезапустить службу обновления Windows: $_"}
Все материалы Задать вопрос