Применяется к
Windows 10 Windows 10, version 1607, all editions Win 10 Ent LTSC 2019 Win 10 IoT Ent LTSC 2019 Windows 10 IoT Core LTSC Windows 10 Enterprise LTSC 2021 Windows 10 IoT Enterprise LTSC 2021 Windows 10, version 22H2, all editions Windows 11 Home and Pro, version 21H2 Windows 11 Enterprise Multi-Session, version 21H2 Windows 11 Enterprise and Education, version 21H2 Windows 11 IoT Enterprise, version 21H2 Windows 11 Home and Pro, version 22H2 Windows 11 Enterprise Multi-Session, version 22H2 Windows 11 Enterprise and Education, version 22H2 Windows 11 IoT Enterprise, version 22H2 Windows 11 SE, version 23H2 Windows 11 Home and Pro, version 23H2 Windows 11 Enterprise and Education, version 23H2 Windows 11 Enterprise Multi-Session, version 23H2 Windows 11 SE, version 24H2 Windows 11 Enterprise and Education, version 24H2 Windows 11 Enterprise Multi-Session, version 24H2 Windows 11 Home and Pro, version 24H2 Windows 11 IoT Enterprise, version 24H2 Windows Server 2012 ESU Windows Server 2012 R2 ESU Windows Server 2016 Windows Server 2019 Windows Server 2022 Windows Server 2025

Исходная дата публикации: 17 ноября 2025 г.

Идентификатор базы знаний: 5072718

Дата изменения

Описание изменений

24 февраля 2026 г.

  • Обновлен пример сценария сбора данных инвентаризации безопасной загрузки.

22 февраля 2026 г.

  • Обновлен пример сценария сбора данных инвентаризации безопасной загрузки.

13 февраля 2026 г.

  • Обновлен пример сценария сбора данных инвентаризации безопасной загрузки.

Пример сценария сбора данных инвентаризации безопасной загрузки

Скопируйте и вставьте этот пример скрипта и измените его при необходимости для своей среды: пример сценария сбора данных инвентаризации безопасной загрузки.

<# . ОБЗОР     Определяет состояние обновления сертификата безопасной загрузки для мониторинга на уровне всего парка.

. ОПИСАНИЕ     Этот скрипт обнаружения собирает сведения о состоянии безопасной загрузки, значениях реестра обновления сертификатов,     и сведения об устройстве. Он выводит строку JSON для мониторинга и создания отчетов.

    Совместимо с Intune исправлениями, коллекцией на основе объектов групповой политики и другими средствами управления.Скрипт исправления не требуется — это только мониторинг.

    Выход 0 = "Без проблем" (сертификаты обновлены)     Выход 1 = "С проблемой" (сертификаты не обновлены — только информационные)

. Параметр OutputPath     Дополнительные. Путь к папке, в которой будет сохранен JSON-файл.Если этот параметр указан, сохраняет HOSTNAME_latest.json в этой папке.Если это не указано, выводит JSON в stdout (исходное поведение).

. ПРИМЕРЕ     # Выходные данные в stdout (обнаружение Intune/SCCM)     .\Detect-SecureBootCertUpdateStatus.ps1

. ПРИМЕРЕ     # Сохранение в сетевую папку (развертывание объекта групповой политики)     .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"

. ЗАМЕТКИ     Пути к реестру на https://aka.ms/securebootplaybook:       HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot       HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing

    ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЭКСПРЕСС ИЛИ     ПОДРАЗУМЕВАЕМЫЕ, ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ,     ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕСОВЕРШЕНИЕ. НИ В КАКИХ СЛУЧАЯХ НЕ ДОЛЖЕН     АВТОРЫ ИЛИ ВЛАДЕЛЬЦЫ АВТОРСКИХ ПРАВ НЕСУТ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УБЫТКИ ИЛИ ДРУГИЕ     ОТВЕТСТВЕННОСТЬ, БУДЬ ТО В ИНОМ ДОГОВОРЕ, ДЕЛИКТЕ ИЛИ ИНЫМ ОБРАЗОМ, ВОЗНИКАЮЩАЯ ИЗ,     ВНЕ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ, ИСПОЛЬЗОВАНИЕ ИЛИ ДРУГИЕ СДЕЛКИ В     ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ.#> param(     [Parameter(Обязательный = $false)]     [строка]$OutputPath )

# URL-адрес для скачивания: https://aka.ms/getsecureboot -> "Примеры развертывания и мониторинга" # Примечание. Этот скрипт выполняется на конечных точках для сбора данных о состоянии безопасной загрузки.

# 1. Узла # Версия PS: Все | Администратор: Нет | Требования к системе: нет try {     $hostname = $env:COMPUTERNAME     if ([string]::IsNullOrEmpty($hostname)) {         Write-Warning "Не удалось определить имя узла"         $hostname = "Unknown"     }     Write-Host "Имя узла: $hostname" } catch {     Write-Warning "Ошибка при получении имени узла: $_"     $hostname = "Ошибка"     Write-Host "Имя узла: $hostname" }

# 2. CollectionTime # Версия PS: Все | Администратор: Нет | Требования к системе: нет try {     $collectionTime = Get-Date     if ($null -eq $collectionTime) {         Write-Warning "Не удалось получить текущую дату и время"         $collectionTime = "Unknown"     }     Write-Host "Время сбора: $collectionTime" } catch {     Write-Warning "Ошибка получения даты и времени: $_"     $collectionTime = "Error"     Write-Host "Время сбора: $collectionTime" }

# Реестр: главный ключ безопасной загрузки (3 значения)

# 3. SecureBootEnabled # PS Version: 3.0+ | Администратор: может потребоваться | Требования к системе: система с поддержкой UEFI и безопасной загрузки try {     $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop     Write-Host "Безопасная загрузка включена: $secureBootEnabled" } catch {     Write-Warning "Не удается определить состояние безопасной загрузки с помощью командлета: $_"     # Попробуйте резервный реестр     try {         $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop         $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled         Write-Host "Безопасная загрузка включена: $secureBootEnabled"     } catch {         Write-Warning "Не удается определить состояние безопасной загрузки с помощью реестра. Система может не поддерживать UEFI и безопасную загрузку".         $secureBootEnabled = $null         Write-Host "Безопасная загрузка включена: недоступна"     } }

# 4. HighConfidenceOptOut # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop     $highConfidenceOptOut = $regValue.HighConfidenceOptOut     Write-Host "Отказ с высокой достоверностью: $highConfidenceOptOut" } catch {     # HighConfidenceOptOut является необязательным — отсутствует в большинстве систем     $highConfidenceOptOut = $null     Write-Host "Отказ с высокой достоверностью: не задано" }

No 4b. MicrosoftUpdateManagedOptIn # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop     $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn     Write-Host "Управляемое согласие Центра обновления Майкрософт: $microsoftUpdateManagedOptIn" } catch {     # MicrosoftUpdateManagedOptIn является необязательным — отсутствует в большинстве систем     $microsoftUpdateManagedOptIn = $null     Write-Host "Управляемое согласие Центра обновления Майкрософт: не задано" }

# 5. AvailableUpdates # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop     $availableUpdates = $regValue.AvailableUpdates     if ($null -ne $availableUpdates) {         # Преобразование в шестнадцатеричный формат         $availableUpdatesHex = "0x{0:X}" -f $availableUpdates         Write-Host "Доступные Обновления: $availableUpdatesHex"     } else {         Write-Host "Доступное Обновления: недоступно"     } } catch {     Write-Warning "AvailableUpdates раздел реестра не найден или недоступен"     $availableUpdates = $null     Write-Host "Доступное Обновления: недоступно" }

No 5b. AvailableUpdatesPolicy (постоянное значение, управляемое GPO) # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop     $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy     if ($null -ne $availableUpdatesPolicy) {         # Преобразование в шестнадцатеричный формат         $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy         Write-Host "Доступная политика Обновления: $availableUpdatesPolicyHex"     } else {         Write-Host "Доступная политика Обновления: не задано"     } } catch {     # AvailableUpdatesPolicy является необязательным— устанавливается только при применении объекта групповой политики.     $availableUpdatesPolicy = $null     Write-Host "Доступная политика Обновления: не задано" }

# Реестр: обслуживающий ключ (3 значения)

# 6. UEFICA2023Status # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop     $uefica 2023Status = $regValue.UEFICA2023Status     Write-Host "Windows UEFI CA 2023 Status: $uefica 2023Status" } catch {     Write-Warning "Раздел реестра состояния Windows UEFI CA 2023 не найден или недоступен"     $uefica 2023Status = $null     Write-Host "Windows UEFI CA 2023 Status: Not Available" (Состояние windows UEFI CA 2023: недоступно) }

# 7. UEFICA2023Error # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop     $uefica 2023Error = $regValue.UEFICA2023Error     Write-Host "Ошибка UEFI CA 2023: $uefica 2023Error" } catch {     # UEFICA2023Error существует только в том случае, если произошла ошибка — отсутствие хорошо     $uefica 2023Error = $null     Write-Host "Ошибка UEFI CA 2023: Нет" }

# 8. UEFICA2023ErrorEvent # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop     $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent     Write-Host "Событие ошибки UEFI CA 2023: $uefica 2023ErrorEvent" } catch {     $uefica 2023ErrorEvent = $null     Write-Host "Событие ошибки UEFI CA 2023: недоступно" }

# Реестр: атрибуты устройства (7 значений: 9–15)

# 9. OEMManufacturerName # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMManufacturerName -ErrorAction Stop     $oemManufacturerName = $regValue.OEMManufacturerName     if ([string]::IsNullOrEmpty($oemManufacturerName)) {         Write-Warning "OEMManufacturerName является пустым"         $oemManufacturerName = "Unknown"     }     Write-Host "Имя изготовителя oem: $oemManufacturerName" } catch {     Write-Warning "КЛЮЧ реестра OEMManufacturerName не найден или недоступен"     $oemManufacturerName = $null     Write-Host "Имя изготовителя oem: недоступно" }

# 10. OEMModelSystemFamily # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelSystemFamily -ErrorAction Stop     $oemModelSystemFamily = $regValue.OEMModelSystemFamily     if ([string]::IsNullOrEmpty($oemModelSystemFamily)) {         Write-Warning "OEMModelSystemFamily пусто"         $oemModelSystemFamily = "Unknown"     }     Write-Host "Семейство систем моделей OEM: $oemModelSystemFamily" } catch {     Write-Warning "РАЗДЕЛ реестра OEMModelSystemFamily не найден или недоступен"     $oemModelSystemFamily = $null     Write-Host "Семейство систем моделей oem: недоступно" }

# 11. OEMModelNumber # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelNumber -ErrorAction Stop     $oemModelNumber = $regValue.OEMModelNumber     if ([string]::IsNullOrEmpty($oemModelNumber)) {         Write-Warning "OEMModelNumber is empty"         $oemModelNumber = "Unknown"     }     Write-Host "Номер модели OEM: $oemModelNumber" } catch {     Write-Warning "Раздел реестра OEMModelNumber не найден или недоступен"     $oemModelNumber = $null     Write-Host "Номер модели OEM: недоступно" }

# 12. FirmwareVersion # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareVersion -ErrorAction Stop     $firmwareVersion = $regValue.FirmwareVersion     if ([string]::IsNullOrEmpty($firmwareVersion)) {         Write-Warning "FirmwareVersion is empty"         $firmwareVersion = "Unknown"     }     Write-Host "Версия встроенного ПО: $firmwareVersion" } catch {     Write-Warning "Раздел реестра FirmwareVersion не найден или недоступен"     $firmwareVersion = $null     Write-Host "Версия встроенного ПО: недоступна" }

# 13. FirmwareReleaseDate # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareReleaseDate -ErrorAction Stop     $firmwareReleaseDate = $regValue.FirmwareReleaseDate     if ([string]::IsNullOrEmpty($firmwareReleaseDate)) {         Write-Warning "FirmwareReleaseDate is empty"         $firmwareReleaseDate = "Unknown"     }     Write-Host "Дата выпуска встроенного ПО: $firmwareReleaseDate" } catch {     Write-Warning "FirmwareReleaseDate раздел реестра не найден или недоступен"     $firmwareReleaseDate = $null     Write-Host "Дата выпуска встроенного ПО: недоступно" }

# 14. OSArchitecture # Версия PS: Все | Администратор: Нет | Требования к системе: нет try {     $osArchitecture = $env:PROCESSOR_ARCHITECTURE     if ([string]::IsNullOrEmpty($osArchitecture)) {         # Попробуйте резервный реестр         $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OSArchitecture -ErrorAction Stop         $osArchitecture = $regValue.OSArchitecture     }     if ([string]::IsNullOrEmpty($osArchitecture)) {         Write-Warning "Не удалось определить OSArchitecture"         $osArchitecture = "Unknown"     }     Write-Host "Архитектура ОС: $osArchitecture" } catch {     Write-Warning "Ошибка при получении OSArchitecture: $_"     $osArchitecture = "Unknown"     Write-Host "Архитектура ОС: $osArchitecture" }

# 15. CanAttemptUpdateAfter (FILETIME) # Версия PS: Все | Администратор: может потребоваться | Требования к системе: нет try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop     $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter     # Преобразование FILETIME в UTC DateTime — реестр хранит как REG_BINARY (байт[]) или REG_QWORD (long)     if ($null -ne $canAttemptUpdateAfter) {         try {             if ($canAttemptUpdateAfter -is [byte[]]) {                 $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter, 0)                 $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime). ToUniversalTime()             } elseif ($canAttemptUpdateAfter -is [long]) {                 $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter). ToUniversalTime()             }         } catch {             Write-Warning "Не удалось преобразовать CanAttemptUpdateAfter FILETIME в DateTime"         }     }     Write-Host "Можно выполнить попытку обновления после: $canAttemptUpdateAfter" } catch {     Write-Warning "CanAttemptUpdateAfter раздел реестра не найден или недоступен"     $canAttemptUpdateAfter = $null     Write-Host "Может предпринять попытку обновления после: недоступно" }

# Журналы событий: системный журнал (10 значений: 16–25)

# 16-25. Запросы журнала событий # Идентификаторы событий: # 1801 — обновление инициировано, требуется перезагрузка No 1808 — обновление успешно завершено # 1795 — возвращена ошибка встроенного ПО (код ошибки записи) No 1796 — ошибка, зарегистрированная с кодом ошибки (код записи) # 1800 — требуется перезагрузка (не ошибка — обновление будет продолжаться после перезагрузки) No 1802 — известное обновление с блокировкой встроенного ПО (запись номера KI_<> из SkipReason) # 1803 — не найдено соответствующее обновление KEK (oem должен предоставить KEK с подписью PK) # PS Version: 3.0+ | Администратор: может потребоваться для системного журнала | Требования к системе: нет try {     # Запрос всех соответствующих идентификаторов событий безопасной загрузки     $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808)     $events = @(Get-WinEvent -FilterHashtable @{LogName='System'; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)

    if ($events. Count -eq 0) {         Write-Warning "События безопасной загрузки не найдены в системном журнале"         $latestEventId = $null         $bucketId = $null         $confidence = $null         $skipReasonKnownIssue = $null         $event 1801Count = 0         $event 1808Count = 0         $event 1795Count = 0         $event 1795ErrorCode = $null         $event 1796Count = 0         $event 1796ErrorCode = $null         $event 1800Count = 0         $rebootPending = $false         $event 1802Count = 0         $knownIssueId = $null         $event 1803Count = 0         $missingKEK = $false         Write-Host "Последнее событие: недоступно"         Write-Host "Идентификатор контейнера: недоступно"         Write-Host "Достоверность: недоступно"         Write-Host "Число событий 1801: 0"         Write-Host "Число событий 1808: 0"     } else {         # 16. LatestEventId         $latestEvent = $events | Sort-Object TimeCreated -убывание | Select-Object -Первый 1         if ($null -eq $latestEvent) {             Write-Warning "Не удалось определить последнее событие"             $latestEventId = $null             Write-Host "Последнее событие: недоступно"         } else {             $latestEventId = $latestEvent.Id             Write-Host "Последнее событие: $latestEventId"         }

        # 17. BucketID — извлечено из события 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketId:\s*(.+)') {                 $bucketId = $matches[1]. Trim()                 Write-Host "Идентификатор контейнера: $bucketId"             } else {                 Write-Warning "BucketId не найден в сообщении о событии"                 $bucketId = $null                 Write-Host "Идентификатор контейнера: не найден в событии"             }         } else {             Write-Warning "Последнее событие или сообщение имеет значение NULL, не удается извлечь BucketId"             $bucketId = $null             Write-Host "Идентификатор контейнера: недоступно"         }

        # 18. Достоверность — извлечено из события 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') {                 $confidence = $matches[1]. Trim()                 Write-Host "Доверие: $confidence"             } else {                 Write-Warning "Уровень достоверности не найден в сообщении о событии"                 $confidence = $null                 Write-Host "Достоверность: не найдена в событии"             }         } else {             Write-Warning "Последнее событие или сообщение имеет значение NULL, не удается извлечь достоверность"             $confidence = $null             Write-Host "Достоверность: недоступно"         }

        No 18b. SkipReason — извлечение KI_<числовых> из SkipReason в том же событии, что и BucketId         # Записывает идентификаторы известных проблем, которые отображаются вместе с BucketId/Confidence (а не только событие 1802).         $skipReasonKnownIssue = $null         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'SkipReason:\s*(KI_\d+)') {                 $skipReasonKnownIssue = $matches[1]                 Write-Host "Известная проблема SkipReason: $skipReasonKnownIssue" -ForegroundColor Yellow             }         }

        # 19. Event1801Count         $event 1801Array = @($events | Where-Object {$_. Id -eq 1801})         $event 1801Count = $event 1801Array.Count         Write-Host "Число событий 1801: $event 1801Count"

        # 20. Event1808Count         $event 1808Array = @($events | Where-Object {$_. Id -eq 1808})         $event 1808Count = $event 1808Array.Count         Write-Host "Число событий 1808: $event 1808Count"         # Инициализация переменных события ошибки         $event 1795Count = 0         $event 1795ErrorCode = $null         $event 1796Count = 0         $event 1796ErrorCode = $null         $event 1800Count = 0         $rebootPending = $false         $event 1802Count = 0         $knownIssueId = $null         $event 1803Count = 0         $missingKEK = $false         # проверка только для событий ошибок, если обновление не завершено         # Пропустить анализ ошибок, если: 1808 является последним событием или UEFICA2023Status имеет значение "Обновлено"         $updateComplete = ($latestEventId -eq 1808) -or ($uefica 2023Status -eq "Updated")         if (-not $updateComplete) {             Write-Host "Обновление не завершено - проверка на наличие ошибок..." -ForegroundColor Yellow             # 21.                                         Событие1795 — ошибка встроенного ПО (код ошибки записи)             $event 1795Array = @($events | Where-Object {$_. Id -eq 1795})             $event 1795Count = $event 1795Array.Count             if ($event 1795Count -gt 0) {                 $latestEvent 1795 = $event 1795Array | Sort-Object TimeCreated -убывание | Select-Object -Первый 1                 if ($latestEvent 1795.Message -match '(?:error|code|status)[:\s]*(?:0x)?( [0-9A-Fa-f]{8}|[0-9A-Fa-f]+)') {                     $event 1795ErrorCode = $matches[1]                 }                 Write-Host "Число событий 1795 (ошибка встроенного ПО): $event 1795Count" $(if ($event 1795ErrorCode) { "Code: $event 1795ErrorCode" })             }                          # 22. Событие1796 — зарегистрированный код ошибки (код ошибки записи)             $event 1796Array = @($events | Where-Object {$_. Id -eq 1796})             $event 1796Count = $event 1796Array.Count             if ($event 1796Count -gt 0) {                 $latestEvent 1796 = $event 1796Array | Sort-Object TimeCreated -убывание | Select-Object -Первый 1                 if ($latestEvent 1796.Message -match '(?:error|code|status)[:\s]*(?:0x)?( [0-9A-Fa-f]{8}|[0-9A-Fa-f]+)') {                     $event 1796ErrorCode = $matches[1]                 }                 Write-Host "Event 1796 (error logged) Count: $event 1796Count" $(if ($event 1796ErrorCode) { "Code: $event 1796ErrorCode" })             }                          # 23. Событие1800 — требуется перезагрузка (не ошибка — обновление будет продолжаться после перезагрузки)             $event 1800Array = @($events | Where-Object {$_. Id -eq 1800})             $event 1800Count = $event 1800Array.Count             $rebootPending = $event 1800Count -gt 0             if ($rebootPending) {                 Write-Host "Событие 1800 (ожидание перезагрузки): обновление продолжится после перезагрузки" -ForegroundColor Cyan             }                          # 24. Событие1802 — известная проблема с встроенным ПО (запись KI_<номер> из SkipReason)             $event 1802Array = @($events | Where-Object {$_. Id -eq 1802})             $event 1802Count = $event 1802Array.Count             if ($event 1802Count -gt 0) {                 $latestEvent 1802 = $event 1802Array | Sort-Object TimeCreated -убывание | Select-Object -Первый 1                 if ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)")) {                     $knownIssueId = $matches[1]                 }                 Write-Host "Число событий 1802 (известная проблема с встроенным ПО): $event 1802Count" $(if ($knownIssueId) { "KI: $knownIssueId" })             }                          # 25. Event1803 — отсутствует обновление KEK (oem должен предоставить KEK с подписью PK)             $event 1803Array = @($events | Where-Object {$_. Id -eq 1803})             $event 1803Count = $event 1803Array.Count             $missingKEK = $event 1803Count -gt 0             if ($missingKEK) {                 Write-Host "Событие 1803 (отсутствует KEK): ИЗГОТОВИТЕЛЬ должен предоставить KEK со знаком PK" -ForegroundColor Yellow             }         } else {             Write-Host "Обновление завершено (событие 1808 или Status=Updated) - пропуск анализа ошибок" -ForegroundColor Green         }     } } catch {     Write-Warning "Ошибка получения журналов событий. Могут потребоваться права администратора: $_"     $latestEventId = $null     $bucketId = $null     $confidence = $null     $skipReasonKnownIssue = $null     $event 1801Count = 0     $event 1808Count = 0     $event 1795Count = 0     $event 1795ErrorCode = $null     $event 1796Count = 0     $event 1796ErrorCode = $null     $event 1800Count = 0     $rebootPending = $false     $event 1802Count = 0     $knownIssueId = $null     $event 1803Count = 0     $missingKEK = $false     Write-Host "Последнее событие: ошибка"     Write-Host "Идентификатор контейнера: ошибка"     Write-Host "Достоверность: ошибка"     Write-Host "Число событий 1801: 0"     Write-Host "Число событий 1808: 0" }

# Запросы WMI/CIM (5 значений)

# 26. OSVersion # ВЕРСИЯ PS: 3.0+ (используйте Get-WmiObject для версии 2.0) | Администратор: Нет | Требования к системе: нет try {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -or [string]::IsNullOrEmpty($osInfo.Version)) {         Write-Warning "Не удалось получить версию ОС"         $osVersion = "Unknown"     } else {         $osVersion = $osInfo.Version     }     Write-Host "Версия ОС: $osVersion" } catch {     # CIM может завершиться сбоем в некоторых средах — используйте резервный вариант     $osVersion = [System.Environment]::OSVersion.Version.ToString()     if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" }     Write-Host "Версия ОС: $osVersion" }

# 27. LastBootTime # ВЕРСИЯ PS: 3.0+ (используйте Get-WmiObject для версии 2.0) | Администратор: Нет | Требования к системе: нет try {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -or $null -eq $osInfo.LastBootUpTime) {         Write-Warning "Не удалось получить время последней загрузки"         $lastBootTime = $null         Write-Host "Время последней загрузки: недоступно"     } else {         $lastBootTime = $osInfo.LastBootUpTime         Write-Host "Время последней загрузки: $lastBootTime"     } } catch {     # CIM может завершиться сбоем в некоторых средах — используйте резервный вариант     try {         $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue). Starttime     } catch {         $lastBootTime = $null     }     if ($lastBootTime) { Write-Host "Время последней загрузки: $lastBootTime" } else { Write-Host "Время последней загрузки: недоступно" } }

# 28. BaseBoardManufacturer # ВЕРСИЯ PS: 3.0+ (используйте Get-WmiObject для версии 2.0) | Администратор: Нет | Требования к системе: нет try {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) {         Write-Warning "Не удалось получить изготовителя основной платы"         $baseBoardManufacturer = "Unknown"     } else {         $baseBoardManufacturer = $baseBoard.Manufacturer     }     Write-Host "Изготовитель основной платы: $baseBoardManufacturer" } catch {     # CIM может завершиться ошибкой — сведения о основной панели являются дополнительными     $baseBoardManufacturer = "Unknown"     Write-Host "Изготовитель основной платы: $baseBoardManufacturer" }

# 29. BaseBoardProduct # ВЕРСИЯ PS: 3.0+ (используйте Get-WmiObject для версии 2.0) | Администратор: Нет | Требования к системе: нет try {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) {         Write-Warning "Не удалось получить продукт основной платы"         $baseBoardProduct = "Unknown"     } else {         $baseBoardProduct = $baseBoard.Product     }     Write-Host "Продукт основной платы: $baseBoardProduct" } catch {     # CIM может завершиться ошибкой — сведения о основной панели являются дополнительными     $baseBoardProduct = "Unknown"     Write-Host "Основной продукт: $baseBoardProduct" }

# 30. SecureBootTaskEnabled # Версия PS: Все | Администратор: Нет | Требования к системе: запланированная задача существует # Проверяет, включена ли запланированная задача безопасной загрузки и обновления $secureBootTaskEnabled = $null $secureBootTaskStatus = "Unknown" try {     $taskOutput = schtasks.exe /Query /TN "\Microsoft\Windows\PI\Secure-Boot-Update" /FO CSV 2>&1     if ($LASTEXITCODE -eq 0) {         $taskData = $taskOutput | ConvertFrom-Csv         if ($taskData) {             $secureBootTaskStatus = $taskData.Status             $secureBootTaskEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running')         }     } else {         $secureBootTaskStatus = NotFound         $secureBootTaskEnabled = $false     }     if ($secureBootTaskEnabled -eq $false) {         Write-Host "Задача обновления SecureBoot: $secureBootTaskStatus (Включено: $secureBootTaskEnabled)" -ForegroundColor Yellow     } else {         Write-Host "Задача обновления SecureBoot: $secureBootTaskStatus (Включено: $secureBootTaskEnabled)" - ForegroundColor Green     } } catch {     $secureBootTaskStatus = "Error"     $secureBootTaskEnabled = $false     Write-Host "Задача обновления SecureBoot: проверка ошибок - $_" -ForegroundColor Red }

# 31. Состояние ключа WinCS (F33E0C8E002 — обновление сертификата безопасной загрузки) # Версия PS: Все | Администратор: Да (для запроса) | Требования к системе: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Unknown" try {     # Проверка распространенных расположений для WinCsFlags.exe     $wincsFlagsPath = $null     $possiblePaths = @(         "$env:SystemRoot\System32\WinCsFlags.exe",         "$env:SystemRoot\SysWOW64\WinCsFlags.exe"     )     foreach ($p в $possiblePaths) {         if (Test-Path $p) { $wincsFlagsPath = $p; break }     }     if ($wincsFlagsPath) {         # Определенный ключ запроса — требуются права администратора         $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1         $queryOutputStr = $queryOutput -join "'n"         if ($LASTEXITCODE -eq 0) {             # Проверьте, применен ли ключ (найдите "Активная конфигурация" или аналогичный индикатор)             если ($queryOutputStr -match "Active Configuration.*:*enabled" -или $queryOutputStr -match "Configuration.*applied") {                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Применено"                 Write-Host "F33E0C8E002 ключа WinCS: применено" -ForegroundColor Green             } elseif ($queryOutputStr -match "not found|Без конфигурации") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = NotApplied                 Write-Host "F33E0C8E002 ключа WinCS: не применяется" -ForegroundColor Yellow             } else {                 # Key exists — проверка выходные данные для состояния                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Применено"                 Write-Host "F33E0C8E002 ключей WinCS: применено" -ForegroundColor Green             }         } else {             # Проверьте наличие определенных сообщений об ошибках             if ($queryOutputStr -match "Access denied|administrator") {                 $wincsKeyStatus = AccessDenied                 Write-Host "F33E0C8E002 ключа WinCS: доступ запрещен (запуск от имени администратора)" -ForegroundColor DarkGray             } elseif ($queryOutputStr -match "not found|Без конфигурации") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = NotApplied                 Write-Host "F33E0C8E002 ключа WinCS: не применяется" -ForegroundColor Yellow             } else {                 $wincsKeyStatus = "QueryFailed"                 Write-Host "F33E0C8E002 ключа WinCS: сбой запроса" - ForegroundColor Red             }         }     } else {         $wincsKeyStatus = "WinCsFlagsNotFound"         Write-Host "F33E0C8E002 ключа WinCS: WinCsFlags.exe не найден" -ForegroundColor Gray     } } catch {     $wincsKeyStatus = "Ошибка"     Write-Host "WinCS Key F33E0C8E002: error checking - $_" -ForegroundColor Red }              

# ============================================================================= # Исправление обнаружения — вывод состояния & код выхода # =============================================================================

# Создание объекта состояния из всех собранных данных инвентаризации $status = [упорядочено]@{     UEFICA2023Status = $uefica 2023Status     UEFICA2023Error = $uefica 2023Error     UEFICA2023ErrorEvent = $uefica 2023ErrorEvent     AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } else { $null }     AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } else { $null }     Имя узла = $hostname     CollectionTime = if ($collectionTime -is [datetime]) { $collectionTime.ToString("o") } else { "$collectionTime" }     SecureBootEnabled = $secureBootEnabled     HighConfidenceOptOut = $highConfidenceOptOut     MicrosoftUpdateManagedOptIn = $microsoftUpdateManagedOptIn     OEMManufacturerName = $oemManufacturerName     OEMModelSystemFamily = $oemModelSystemFamily     OEMModelNumber = $oemModelNumber     FirmwareVersion = $firmwareVersion     FirmwareReleaseDate = $firmwareReleaseDate     OSArchitecture = $osArchitecture     CanAttemptUpdateAfter = if ($canAttemptUpdateAfter -is [datetime]) { $canAttemptUpdateAfter.ToString("o") } else { "$canAttemptUpdateAfter" }     LatestEventId = $latestEventId     BucketId = $bucketId     Достоверность = $confidence     SkipReasonKnownIssue = $skipReasonKnownIssue # KI_<число> из события SkipReason in BucketId     Event1801Count = $event 1801Count     Event1808Count = $event 1808Count     # События ошибок с собранными сведениями     Event1795Count = $event 1795Count # Встроенное ПО возвращает ошибку     Event1795ErrorCode = $event 1795ErrorCode # Код ошибки из встроенного ПО     Event1796Count = $event 1796Count # Зарегистрирован код ошибки     Event1796ErrorCode = $event 1796ErrorCode # Захваченный код ошибки     Event1800Count = $event 1800Count # Требуется перезагрузка (не ошибка)     RebootPending = $rebootPending # True, если присутствует событие 1800     Event1802Count = $event 1802Count # Известная проблема с встроенным ПО     KnownIssueId = $knownIssueId # KI_<число> из SkipReason     Event1803Count = $event 1803Count # Отсутствует обновление KEK     MissingKEK = $missingKEK # OEM должен предоставить KEK с подписью PK     OSVersion = $osVersion     LastBootTime = if ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } else { "$lastBootTime" }     BaseBoardManufacturer = $baseBoardManufacturer     BaseBoardProduct = $baseBoardProduct     SecureBootTaskEnabled = $secureBootTaskEnabled     SecureBootTaskStatus = $secureBootTaskStatus     WinCSKeyApplied = $wincsKeyApplied # True, если применяется F33E0C8E002 ключ     WinCSKeyStatus = $wincsKeyStatus # Applied, NotApplied, WinCsFlagsNotFound и т. д. }

# Вывод состояния — для агрегирования данных $jsonOutput = $status | ConvertTo-Json -Compress

# Если outputPath указан, сохраните в файл; в противном случае выходные данные в stdout if (-not [string]::IsNullOrEmpty($OutputPath)) {     # Проверка OutputPath — пропустите, если он выглядит как запрос на помощь или содержит недопустимые символы.     если ($OutputPath -match '^[/\-]' -или $OutputPath -match '[<>:"|? *]') {         Write-Host "Указан недопустимый выходной путь, вывод в stdout" -ForegroundColor Yellow         Write-Output $jsonOutput         if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") { exit 0 } else { exit 1 }     }          # Убедитесь, что выходная папка существует     if (-not (Test-Path $OutputPath)) {         try {             New-Item -ItemType Directory -Path $OutputPath -Force | Out-NULL         } catch {             Write-Warning "Не удалось создать выходную папку: $OutputPath - $_"         }     }          # Сохранить в HOSTNAME_latest.json     $outputFile = Join-Path $OutputPath "$($hostname)_latest.json"     try {         $jsonOutput | Out-File -FilePath $outputFile -Encoding UTF8 -Force         Write-Host "JSON сохранен в: $outputFile" -ForegroundColor Green     } catch {         Write-Warning "Не удалось записать в файл: $outputFile - $_"         # Вернуться к stdout         Write-Output $jsonOutput     } } else {     # Исходное поведение — вывод в stdout     Write-Output $jsonOutput }

# Код выхода: "Обновлено" — это значение успешного выполнения в сборнике схем. if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") {     Exit 0 # Без проблемы } else {     выход 1 # С проблемой }

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.