Първоначална дата на публикуване: 17 ноември 2025 г.
ИД на КБ: 5072718
|
Промяна на датата |
Промяна на описанието |
|
24 февруари 2026 г. |
|
|
22 февруари 2026 г. |
|
|
13 февруари 2026 г. |
|
Sample Secure Boot Inventory Data Collection script
Копирайте и поставете този примерен скрипт и променете, както е необходимо за вашата среда: скриптът за събиране на данни за примерно защитено стартиране.
< на 200 000 000 . СИНОПСИС Открива състоянието на актуализацията на сертификата за защитено стартиране за наблюдение за целия флот.
. ОПИСАНИЕ Този скрипт за откриване събира състоянието на защитеното стартиране, стойностите в системния регистър за актуализиране на сертификата, и информация за устройството. Той извежда JSON низ за наблюдение и отчитане.
Съвместими с Intune отстраняване на грешки, колекция, базирана на GPO, и други инструменти за управление.Не е необходим скрипт за лечение – това е само наблюдение.
Exit 0 = "Without issue" (сертификатите са актуализирани) Изход 1 = "С проблем" (сертификатите не са актуализирани – само информационни)
. PARAMETER OutputPath Незадължителен. Път до папка, където ще се запише JSON файлът.Ако е предоставено, записва HOSTNAME_latest.json в тази папка.Ако не е предоставено, извежда JSON към stdout (първоначално поведение).
. ПРИМЕР # Изход към stdout (откриване на Intune/SCCM) .\Detect-SecureBootCertUpdateStatus.ps1
. ПРИМЕР # Save to network share (GPO deployment) .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\сървър\SecureBootLogs$"
. БЕЛЕЖКИ Пътища на системния регистър за https://aka.ms/securebootplaybook: HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ПОДРАЗБИРАЩИ СЕ, ВКЛЮЧИТЕЛНО, НО НЕ САМО, ГАРАНЦИИТЕ ЗА ПРОДАВАЕМОСТ, ГОДНОСТ ЗА ОПРЕДЕЛЕНА ЦЕЛ И НЕИНФРАГМЕНТ. В НИКАКЪВ СЛУЧАЙ АВТОРИ ИЛИ ПРИТЕЖАТЕЛИ НА АВТОРСКИ ПРАВА НОСЯТ ОТГОВОРНОСТ ЗА КАКВИТО И ДА Е ИСКОВЕ, ЩЕТИ ИЛИ ДРУГИ ОТГОВОРНОСТ, БИЛО ТО В ДЕЙСТВИЕ ПО ДОГОВОР, ЗАКОНОНАРУШЕНИЕ ИЛИ ПО ДРУГ НАЧИН, ИЗВЪН ИЛИ ВЪВ ВРЪЗКА СЪС СОФТУЕРА, ИЗПОЛЗВАНЕТО ИЛИ ДРУГИ ДЕЙСТВИЯ В СОФТУЕР.#> парам( [Parameter(Mandatory = $false)] [низ]$OutputPath )
# Изтегляне на URL адрес: https://aka.ms/getsecureboot > "Примери за разполагане и мониторинг" # Забележка: Този скрипт се изпълнява на крайни точки за събиране на данни за състоянието на защитеното стартиране.
# 1. Хост # PS версия: всички | Администрация: Не | Изисквания към системата: Няма опитайте { $hostname = $env:ИМЕ_НА_КОМПЮТЪР if ([низ]::IsNullOrEmpty($hostname)) { Write-Warning "Името на хоста не можа да бъде определено" $hostname = "Неизвестен" } Write-Host "Hostname: $hostname" } улов { Write-Warning "Грешка при извличане на име на хост: $_" $hostname = "Грешка" Write-Host "Hostname: $hostname" }
# 2. Време за събиране # PS версия: всички | Администрация: Не | Изисквания към системата: Няма опитайте { $collectionTime = Get-Date ако ($null -eq $collectionTime) { Write-Warning "Не можа да се извлече текущата дата/час" $collectionTime = "Неизвестен" } Write-Host "Час на събиране: $collectionTime" } улов { Write-Warning "Грешка при извличане на дата/час: $_" $collectionTime = "Грешка" Write-Host "Час на събиране: $collectionTime" }
# Registry: Secure Boot Main Key (3 values)
# 3. SecureBootEnabled # PS версия: 3.0+ | Администрация: Може да се изисква | Изисквания към системата: Система, поддържаща UEFI/защитено стартиране опитайте { $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop Write-Host "Защитеното стартиране е разрешено: $secureBootEnabled" } улов { Write-Warning "Не може да се определи състоянието на защитеното стартиране чрез кратка команда: $_" # Опитайте отпадането на системния регистър опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled Write-Host "Защитеното стартиране е разрешено: $secureBootEnabled" } улов { Write-Warning "Състоянието на защитеното стартиране не може да се определи чрез системния регистър. Системата може да не поддържа UEFI/защитено зареждане." $secureBootEnabled = $null Write-Host "Защитеното стартиране е разрешено: не е налично" } }
# 4. HighConfidenceOptOut # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" - Name HighConfidenceOptOut –ErrorAction Stop $highConfidenceOptOut = $regValue.HighConfidenceOptOut Write-Host "Отписване с висока достоверност: $highConfidenceOptOut" } улов { # HighConfidenceOptOut е по желание – липсва на повечето системи $highConfidenceOptOut = $null Write-Host "Отписване с висока достоверност: не е зададено" }
Това е най-еротната ти титла. MicrosoftUpdateManagedOptIn # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" - Name MicrosoftUpdateManagedOptIn – ErrorAction Stop $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn Write-Host "Управлявано включване на Microsoft Update: $microsoftUpdateManagedOptIn" } улов { # MicrosoftUpdateManagedOptIn е по желание – липсва на повечето системи $microsoftUpdateManagedOptIn = $null Write-Host "Управлявано включване на Microsoft Update: не е зададено" }
# 5. Наличниupdates # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" –Name AvailableUpdates - ErrorAction Stop $availableUpdates = $regValue.AvailableUpdates ако ($null -ne $availableUpdates) { # Преобразуване в шестнадесетичен формат $availableUpdatesHex = "0x{0:X}" -f $availableUpdates Write-Host "Предлага се Актуализации: $availableUpdatesHex" } друго { Write-Host "Налично Актуализации: не е налично" } } улов { Write-Warning "AvailableUpdates ключът от системния регистър не е намерен или недостъпен" $availableUpdates = $null Write-Host "Налично Актуализации: не е налично" }
Не, не AvailableUpdatesPolicy (постоянна стойност, контролирана от GPO) # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" - Name AvailableUpdatesPolicy -ErrorAction Stop $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy ако ($null -ne $availableUpdatesPolicy) { # Преобразуване в шестнадесетичен формат $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy Write-Host "Налични правила за Актуализации: $availableUpdatesPolicyHex" } друго { Write-Host "Налични правила за Актуализации: не е зададено" } } улов { # AvailableUpdatesPolicy не е задължително – задава се само когато се прилага GPO $availableUpdatesPolicy = $null Write-Host "Налични правила за Актуализации: не е зададено" }
# Registry: Ключ за обслужване (3 стойности)
# 6. UEFICA2023Status # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" - Name UEFICA2023Status -ErrorAction Stop $uefica 2023Status = $regValue.UEFICA2023Status Write-Host "Състояние на Windows UEFI CA 2023: $uefica 2023Status" } улов { Write-Warning "Ключът от системния регистър за състоянието на Windows UEFI CA 2023 не е намерен или недостъпен" $uefica 2023Status = $null Write-Host "Състояние на Windows UEFI CA 2023: не е налично" }
# 7. UEFICA2023Грешка # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" - Name UEFICA2023Error -ErrorAction Stop $uefica 2023Error = $regValue.UEFICA2023Error Write-Host "Грешка UEFI CA 2023: $uefica 2023Error" } улов { # UEFICA2023Грешка съществува само ако е възникнала грешка – отсъствието е добро $uefica 2023Error = $null Write-Host "Грешка UEFI CA 2023: няма" }
# 8. UEFICA2023ErrorEvent # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" – име UEFICA2023ErrorEvent –ErrorAction Stop $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent Write-Host "Събитие за грешка на UEFI CA 2023: $uefica 2023ErrorEvent" } улов { $uefica 2023ErrorEvent = $null Write-Host "Събитие за грешка на UEFI CA 2023: не е налично" }
# Registry: Device Attributes (7 values: 9-15)
# 9. Име на OEMmanufacturer # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" - Name OEMManufacturerName -ErrorAction Stop $oemManufacturerName = $regValue.OEMManufacturerName if ([низ]::IsNullOrEmpty($oemManufacturerName)) { Write-Warning "OEMManufacturerName е празно" $oemManufacturerName = "Неизвестен" } Write-Host "Име на производителя на OEM: $oemManufacturerName" } улов { Write-Warning "Ключът от системния регистър OEMManufacturerName не е намерен или недостъпен" $oemManufacturerName = $null Write-Host "Име на производителя на OEM: не е налично" }
# 10. OEMModelSystemFamily # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" – име OEMModelSystemFamily – ErrorAction Stop $oemModelSystemFamily = $regValue.OEMModelSystemFamily if ([низ]::IsNullOrEmpty($oemModelSystemFamily)) { Write-Warning "OEMModelSystemFamily е празно" $oemModelSystemFamily = "Неизвестен" } Write-Host "OEM Model System Family: $oemModelSystemFamily" } улов { Write-Warning "Ключът от системния регистър OEMModelSystemFamily не е намерен или недостъпен" $oemModelSystemFamily = $null Write-Host "OEM Model System Family: Not Available" }
# 11. OEMModelNumber # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" – Име OEMModelNumber –ErrorAction Stop $oemModelNumber = $regValue.OEMModelNumber if ([низ]::IsNullOrEmpty($oemModelNumber)) { Write-Warning "OEMModelNumber е празен" $oemModelNumber = "Неизвестен" } Write-Host "Номер на OEM модел: $oemModelNumber" } улов { Write-Warning "Ключът от системния регистър OEMModelNumber не е намерен или недостъпен" $oemModelNumber = $null Write-Host "Номер на OEM модел: не е наличен" }
# 12. FirmwareVersion # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" - Name FirmwareVersion - ErrorAction Stop $firmwareVersion = $regValue.FirmwareVersion if ([низ]::IsNullOrEmpty($firmwareVersion)) { Write-Warning "FirmwareVersion е празно" $firmwareVersion = "Неизвестен" } Write-Host "Версия на фърмуера: $firmwareVersion" } улов { Write-Warning "FirmwareVersion ключът от системния регистър не е намерен или недостъпен" $firmwareVersion = $null Write-Host "Версия на фърмуера: не е налична" }
# 13. FirmwareReleaseDate # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" – Name FirmwareReleaseDate -errorAction Stop $firmwareReleaseDate = $regValue.FirmwareReleaseDate if ([низ]::IsNullOrEmpty($firmwareReleaseDate)) { Write-Warning "FirmwareReleaseDate е празно" $firmwareReleaseDate = "Неизвестен" } Write-Host "Дата на издаване на фърмуера: $firmwareReleaseDate" } улов { Write-Warning "FirmwareReleaseDate ключът от системния регистър не е намерен или недостъпен" $firmwareReleaseDate = $null Write-Host "Дата на издаване на фърмуера: не е налична" }
# 14. OsArchitecture # PS версия: всички | Администрация: Не | Изисквания към системата: Няма опитайте { $osArchitecture = $env:PROCESSOR_ARCHITECTURE if ([низ]::IsNullOrEmpty($osArchitecture)) { # Опитайте отпадането на системния регистър $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" - Name OSArchitecture -ErrorAction Stop $osArchitecture = $regValue.OSArchitecture } if ([низ]::IsNullOrEmpty($osArchitecture)) { Write-Warning "OSArchitecture не можа да бъде определена" $osArchitecture = "Неизвестен" } Write-Host "Архитектура на ОС: $osArchitecture" } улов { Write-Warning "Грешка при извличане на OSArchitecture: $_" $osArchitecture = "Неизвестен" Write-Host "Архитектура на ОС: $osArchitecture" }
# 15. CanAttemptUpdateAfter (FILETIME) # PS версия: всички | Администрация: Може да се изисква | Изисквания към системата: Няма опитайте { $regValue = Get-ItemProperty път "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" - Name CanAttemptUpdateAfter -ErrorAction Stop $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter # Преобразуване на FILETIME в UTC DateTime – съхранява в системния регистър като REG_BINARY (байт[]) или REG_QWORD (дълъг) ако ($null -ne $canAttemptUpdateAfter) { опитайте { ако ($canAttemptUpdateAfter -е [байт[]]) { $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter; 0) $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime). ToUniversalTime() } elseif ($canAttemptUpdateAfter -is [long]) { $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter). ToUniversalTime() } } улов { Write-Warning "CanAttemptUpdateAfter FILETIME в DateTime" } } Write-Host "Може да се опита да се актуализира след: $canAttemptUpdateAfter" } улов { Write-Warning "CanAttemptUpdateAfter ключът от системния регистър не е намерен или недостъпен" $canAttemptUpdateAfter = $null Write-Host "Може да се опита актуализация след: не е налична" }
# Регистри на събитията: Системен регистрационен файл (10 стойности: 16-25)
# 16-25. Заявки в регистъра на събитията # ИД на събитие: # 1801 – инициирана актуализация, изисква се рестартиране # 1808 – актуализацията завърши успешно # 1795 – Фърмуерът върна грешка (снемане на код на грешка) # 1796 - Грешка, регистрирана с код на грешка (снемане на код) # 1800 - Необходимо е рестартиране (НЕ е грешка – актуализацията ще продължи след рестартиране) # 1802 - Известен проблем с фърмуера блокира актуализация (заснемане KI_<номер> от SkipReason) # 1803 - Съвпадаща KEK актуализация не е намерена (OEM трябва да предостави PK подписан KEK) # PS версия: 3.0+ | Администрация: Може да се изисква за системния регистрационен файл | Изисквания към системата: Няма опитайте { # Заявка до всички съответни ИД на събитие на защитено стартиране $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808) $events = @(Get-WinEvent -FilterHashtable @{LogName='System"; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)
ако ($events. Брой -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" } друго { # 16. LatestEventId $latestEvent = $events | Sort-Object времеСъздаден - Низходящ | Select-Object - първи 1 ако ($null -eq $latestEvent) { Write-Warning "Не можа да се определи последното събитие" $latestEventId = $null Write-Host "Последен ИД на събитие: не е наличен" } друго { $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]. Изрязване() Write-Host "ИД на набор: $bucketId" } друго { Write-Warning "BucketId не е намерен в съобщение за събитие" $bucketId = $null Write-Host "ИД на набор: не е намерен в събитието" } } друго { 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]. Изрязване() Write-Host "Достоверност: $confidence" } друго { Write-Warning "Доверителното ниво не е намерено в съобщението за събитие" $confidence = $null Write-Host "Достоверност: не е намерено в събитието" } } друго { Write-Warning "Последното събитие или съобщение е Null, не може да извлече увереност" $confidence = $null Write-Host "Увереност: не е налично" }
Това е номер 18б. 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" – Цвят на преден план – жълт } }
# 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) -или ($uefica 2023Status -eq "Актуализирано") ако (-не $updateComplete) { Write-Host "Актуализацията не е завършена – проверка за събития за грешки..." -ForegroundColor Yellow # 21. Event1795 – грешка във фърмуера (снемане на код на грешка) $event 1795Array = @($events | Where-Object {$_. Id -eq 1795}) $event 1795Count = $event 1795Array.Count ако ($event 1795Count -gt 0) { $latestEvent 1795 = $event 1795Array | Sort-Object времеСъздаден - Низходящ | 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) { "Код: $event 1795ErrorCode" }) } # 22. Event1796 – регистриран код на грешка (снемане на код на грешка) $event 1796Array = @($events | Where-Object {$_. Id -eq 1796}) $event 1796Count = $event 1796Array.Count if ($event 1796Count -gt 0) { $latestEvent 1796 = $event 1796Array | Sort-Object времеСъздаден - Низходящ | 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 "Събитие 1796 (регистриран е грешка): $event 1796Count" $(if ($event 1796ErrorCode) { "Код: $event 1796ErrorCode" }) } # 23. Event1800 – Необходимо е рестартиране (НЕ е грешка – актуализацията ще продължи след рестартиране) $event 1800Array = @($events | Where-Object {$_. Id -eq 1800}) $event 1800Count = $event 1800Array.Count $rebootPending = $event 1800Count -gt 0 ако ($rebootPending) { Write-Host "Събитие 1800 (чакащо рестартиране): Актуализацията ще продължи след рестартиране" -ForegroundColor Cyan } # 24. Event1802 – известен проблем с фърмуера (снемане на KI_<номер> от SkipReason) $event 1802Array = @($events | Where-Object {$_. Id -eq 1802}) $event 1802Count = $event 1802Array.Count ако ($event 1802Count -gt 0) { $latestEvent 1802 = $event 1802Array | Sort-Object времеСъздаден - Низходящ | 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 трябва да предостави подписана от PK KEK) $event 1803Array = @($events | Where-Object {$_. Id -eq 1803}) $event 1803Count = $event 1803Array.Count $missingKEK = $event 1803Count -gt 0 ако ($missingKEK) { Write-Host "Събитие 1803 (липсва KEK): OEM трябва да предостави PK подписан KEK" -ForegroundColor жълто } } друго { Write-Host "Актуализирането завърши (събитие 1808 или състояние=актуализирано) – пропускане на анализа на грешките" -ForegroundColor Green } } } улов { 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) | Администрация: Не | Изисквания към системата: Няма опитайте { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -или [string]::IsNullOrEmpty($osInfo.Version)) { Write-Warning "Не можа да се извлече версията на операционната система" $osVersion = "Неизвестен" } друго { $osVersion = $osInfo.версия } Write-Host "Версия на ОС: $osVersion" } улов { # CIM може да се провали в някои среди – използвайте резервен $osVersion = [System.Environment]::OSVersion.Version.ToString() if ([низ]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" } Write-Host "Версия на ОС: $osVersion" }
# 27. LastBootTime # PS версия: 3.0+ (използвайте Get-WmiObject за 2.0) | Администрация: Не | Изисквания към системата: Няма опитайте { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop ако ($null -eq $osInfo или $null -eq $osInfo.LastBootUpTime) { Write-Warning "Не можа да се извлече часът на последното стартиране" $lastBootTime = $null Write-Host "Час на последно стартиране: не е налично" } друго { $lastBootTime = $osInfo.LastBootUpTime Write-Host "Час на последно стартиране: $lastBootTime" } } улов { # CIM може да се провали в някои среди – използвайте резервен опитайте { $lastBootTime = (Get-Process -Id 0 - ErrorAction SilentlyContinue). StartTime } улов { $lastBootTime = $null } if ($lastBootTime) { Write-Host "Час на последно стартиране: $lastBootTime" } друго { Write-Host "Час на последно стартиране: не е налично" } }
# 28. BaseBoardManufacturer # PS версия: 3.0+ (използвайте Get-WmiObject за 2.0) | Администрация: Не | Изисквания към системата: Няма опитайте { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -или [string]::IsNullOrEmpty($baseBoard.Manufacturer)) { Write-Warning "Не можа да се извлече производител на базовата платка" $baseBoardManufacturer = "Неизвестен" } друго { $baseBoardManufacturer = $baseBoard.Manufacturer } Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" } улов { # CIM може да е неуспешен – информацията за базовата дъска е допълнителна $baseBoardManufacturer = "Неизвестен" Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" }
# 29. BaseBoardProduct # PS версия: 3.0+ (използвайте Get-WmiObject за 2.0) | Администрация: Не | Изисквания към системата: Няма опитайте { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -или [string]::IsNullOrEmpty($baseBoard.Product)) { Write-Warning "Не можа да се извлече продукт с основа" $baseBoardProduct = "Неизвестен" } друго { $baseBoardProduct = $baseBoard.Product } Write-Host "Продукт на основата: $baseBoardProduct" } улов { # CIM може да е неуспешен – информацията за базовата дъска е допълнителна $baseBoardProduct = "Неизвестен" Write-Host "Основен продукт: $baseBoardProduct" }
# 30. SecureBootTaskEnabled # PS версия: всички | Администрация: Не | Изисквания към системата: Планирана задача съществува # Проверява дали планираната задача за защитено стартиране е разрешена $secureBootTaskEnabled = $null $secureBootTaskStatus = "Неизвестен" опитайте { $taskOutput = schtasks.exe /Query /TN "\Microsoft\Windows\PI\Secure-Boot-Update" /FO CSV 2>&1 ако ($LASTEXITCODE -eq 0) { $taskData = $taskOutput | ConvertFrom-Csv ако ($taskData) { $secureBootTaskStatus = $taskData.състояние $secureBootTaskEnabled = ($taskData.Status -eq "Готов" - или $taskData.Състояние -eq "Изпълнява се") } } друго { $secureBootTaskStatus = "NotFound" $secureBootTaskEnabled = $false } ако ($secureBootTaskEnabled -eq $false) { Write-Host "Задача за актуализиране на SecureBoot: $secureBootTaskStatus (разрешено: $secureBootTaskEnabled)" - ForegroundColor жълто } друго { Write-Host "Задача за актуализиране на SecureBoot: $secureBootTaskStatus (разрешено: $secureBootTaskEnabled)" – ForegroundColor Green } } улов { $secureBootTaskStatus = "Грешка" $secureBootTaskEnabled = $false Write-Host "Задача за актуализиране на SecureBoot: Проверка за грешки – $_" -ForegroundColor Red }
# 31. Състояние на ключа на WinCS (F33E0C8E002 – актуализация на сертификата за защитено стартиране) # PS версия: всички | Администрация: Да (за заявка) | Изисквания към системата: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Неизвестен" опитайте { # Проверете често срещаните местоположения за WinCsFlags.exe $wincsFlagsPath = $null $possiblePaths = @( "$env:SystemRoot\System32\WinCsFlags.exe", "$env:SystemRoot\SysWOW64\WinCsFlags.exe" ) търсене на място ($p в $possiblePaths) { ако (тест-път $p) { $wincsFlagsPath = $p; прекъсване } } ако ($wincsFlagsPath) { # Ключ, конкретен за заявката – изисква администраторски права $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1 $queryOutputStr = $queryOutput -join "'n" ако ($LASTEXITCODE -eq 0) { # Проверете дали е приложен ключ (потърсете "Активна конфигурация" или подобен индикатор) if ($queryOutputStr -match "Active Configuration.*:.*enabled" -или $queryOutputStr -match "Configuration.*applied") { $wincsKeyApplied = $true $wincsKeyStatus = "Приложено" Write-Host "WinCS Key F33E0C8E002: Applied" - ForegroundColor Green } elseif ($queryOutputStr -match "не е намерен|Няма конфигурация") { $wincsKeyApplied = $false $wincsKeyStatus = "Не се прилага" Write-Host "WinCS key F33E0C8E002: Not Applied" - ForegroundColor yellow } друго { # Ключът съществува – проверете резултата за състоянието $wincsKeyApplied = $true $wincsKeyStatus = "Приложено" Write-Host "WinCS Key F33E0C8E002: Applied" - ForegroundColor Green } } друго { # Проверка за конкретни съобщения за грешка ако ($queryOutputStr -match "Достъпът е отказан|администратор") { $wincsKeyStatus = "AccessDenied" Write-Host "WinCS Key F33E0C8E002: Access denied (run as admin)" -ForegroundColor DarkGray } elseif ($queryOutputStr -match "не е намерен|Няма конфигурация") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "WinCS key F33E0C8E002: Not Applied" - ForegroundColor yellow } друго { $wincsKeyStatus = "QueryFailed" Write-Host "WinCS Key F33E0C8E002: Query failed" -ForegroundColor Red } } } друго { $wincsKeyStatus = "WinCsFlagsNotFound" Write-Host "Ключ за WinCS, F33E0C8E002: WinCsFlags.exe не е намерен" – Цвят на текста Сиво } } улов { $wincsKeyStatus = "Грешка" Write-Host "WinCS Key F33E0C8E002: Проверка за грешки – $_" -ForegroundColor Red }
============================================================================= # Откриване на отстраняване на грешки – състояние на изходния & изходния код # =============================================================================
# Build status object from all collected inventory data $status = [поръчано]@{ UEFICA2023Status = $uefica 2023Status UEFICA2023Error = $uefica 2023Грешка UEFICA2023ErrorEvent = $uefica 2023ErrorEvent AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } друго { $null } AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } друго { $null } Hostname = $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 в BucketId събитие Event1801Count = $event 1801Count Event1808Count = $event 1808Count # Error events with captured details Event1795Count = $event 1795Count # Грешка, върната от фърмуера Event1795ErrorCode = $event 1795Код на грешка # Код на грешка от фърмуера 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 трябва да предостави PK подписан KEK 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 – Компресиране
# Ако OutputPath е предоставен, запишете във файл; в противен случай се извежда към stdout if (-not [string]::IsNullOrEmpty($OutputPath)) { # Validate OutputPath – пропуснете, ако изглежда като заявка за помощ или има невалидни знаци ако ($OutputPath -match '^[/\-]' -или $OutputPath -match '[<>:"|? *]') { Write-Host "Зададен е невалиден OutputPath, извеждане на stdout" - ForegroundColor жълто Write-Output $jsonOutput if ($secureBootEnabled -and $uefica 2023Status -eq "Актуализирано") { exit 0 } друго { exit 1 } } # Уверете се, че изходната папка съществува if (-not (Test-Path $OutputPath)) { опитайте { New-Item -ItemType директория -път $OutputPath -Force | Out-Null } улов { Write-Warning "Неуспешно създаване на изходна папка: $OutputPath - $_" } } # Запиши в HOSTNAME_latest.json $outputFile = Join-Path $OutputPath "$($hostname)_latest.json" опитайте { $jsonOutput | Out-File – FilePath $outputFile – Кодиране UTF8 – принудително Write-Host "JSON записан в: $outputFile" -ForegroundColor Green } улов { Write-Warning "Не можа да се запише във файла: $outputFile - $_" # Отстъпи назад към stdout Write-Output $jsonOutput } } друго { # Първоначално поведение - изход към stdout Write-Output $jsonOutput }
# Код на излизане: "Актуализиран" е стойността за успех за тактическия указател if ($secureBootEnabled и $uefica 2023Status -eq "Актуализирано") { exit 0 # Without issue } друго { exit 1 # With issue }