Dotyczy
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

Oryginalna data publikacji: 17 listopada 2025 r.

Identyfikator BAZY WIEDZY: 5072718

Zmień datę

Zmień opis

24 lutego 2026 r.

  • Zaktualizowano skrypt zbierania danych w ekspiecie bezpiecznego rozruchu.

22 lutego 2026 r.

  • Zaktualizowano skrypt zbierania danych w ekspiecie bezpiecznego rozruchu.

13 lutego 2026 r.

  • Zaktualizowano skrypt zbierania danych w ekspiecie bezpiecznego rozruchu.

Przykładowy skrypt zbierania danych bezpiecznego rozruchu

Skopiuj i wklej ten przykładowy skrypt i modyfikuj go zgodnie z potrzebami środowiska: skrypt zbierania danych przykładowego bezpiecznego rozruchu.

<# . STRESZCZENIE     Wykrywa stan aktualizacji certyfikatu bezpiecznego rozruchu na potrzeby monitorowania całej floty.

. OPIS     Ten skrypt wykrywania zbiera stan bezpiecznego rozruchu, wartości rejestru aktualizacji certyfikatu,     i informacje o urządzeniu. Powoduje ona utworzenie ciągu JSON w celu monitorowania i raportowania.

    Zgodny z rozwiązaniami Intune, kolekcjami opartymi na obiektach GPO i innymi narzędziami do zarządzania.Skrypty naprawcze nie są potrzebne — jest to tylko monitorowanie.

    Zakończenie 0 = "Bez problemu" (zaktualizowano certyfikaty)     Zakończenie 1 = "Z problemem" (certyfikaty nie zostały zaktualizowane — tylko informacyjne)

. PARAMETER OutputPath     Opcjonalne. Ścieżka do folderu, w którym zostanie zapisany plik JSON.Jeśli zostanie udostępniona, HOSTNAME_latest.json zostanie zapisana w tym folderze.Jeśli nie podano, wyjście JSON do stdout (zachowanie oryginalne).

. PRZYKŁAD     # Wyjście do stdout (wykrywanie Intune/SCCM)     .\Detect-SecureBootCertUpdateStatus.ps1

. PRZYKŁAD     # Zapisz w udziale sieciowym (wdrożenie obiektu zasad grupy)     .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"

. NOTATKI     Ścieżki rejestru na https://aka.ms/securebootplaybook:       HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot       HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing

    OPROGRAMOWANIE JEST DOSTARCZANE "W TAKIEJ POSTACI, W JAKIEJ JEST", BEZ JAKICHKOLWIEK GWARANCJI,     DOROZUMIANE, W TYM MIĘDZY INNYMI GWARANCJE PRZYDATNOŚCI HANDLOWEJ,     PRZYDATNOŚĆ DO OKREŚLONEGO CELU I BEZ NARUSZENIA. W ŻADNYM WYPADKU NIE     AUTORZY LUB POSIADACZE PRAW AUTORSKICH PONOSZĄ ODPOWIEDZIALNOŚĆ ZA JAKIEKOLWIEK ROSZCZENIA, SZKODY LUB INNE     ODPOWIEDZIALNOŚĆ, CZY TO W AKCJI NA RZECZ UMOWY, CZYNU NIEDOZWOLONEGO LUB W INNY SPOSÓB,     LUB W ZWIĄZKU Z OPROGRAMOWANIEM, UŻYWANIEM LUB INNYMI TRANSAKCJAMI W     OPROGRAMOWANIA.#> param(     [Parameter(Mandatory = $false)]     [ciąg]$OutputPath )

# Pobierz adres URL: https://aka.ms/getsecureboot -> "Przykłady wdrażania i monitorowania" # Uwaga: Ten skrypt działa w punktach końcowych w celu zbierania danych o stanie bezpiecznego rozruchu.

# 1. Nazwa hosta # Wersja PS: Wszystkie | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $hostname = $env:COMPUTERNAME     if ([ciąg]:IsNullOrEmpty($hostname)) {         Write-Warning "Nie można ustalić nazwy hosta"         $hostname = "Nieznany"     }     Write-Host "Hostname: $hostname" } złapać {     Write-Warning "Błąd podczas pobierania nazwy hosta: $_"     $hostname = "Błąd"     Write-Host "Hostname: $hostname" (Nazwa hosta: $hostname) }

# 2. CollectionTime # Wersja PS: Wszystkie | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $collectionTime = Data uzyskania     if ($null -eq $collectionTime) {         Write-Warning "Nie można pobrać bieżącej daty/godziny"         $collectionTime = "Nieznany"     }     Write-Host "Czas zbierania danych: $collectionTime" } złapać {     Write-Warning "Błąd podczas pobierania daty/godziny: $_"     $collectionTime = "Błąd"     Write-Host "Czas zbierania danych: $collectionTime" }

# Rejestr: Klucz główny bezpiecznego rozruchu (3 wartości)

# 3. SecureBootEnabled # PS Wersja: 3.0 + | Administracja: Może być wymagane | Wymagania systemowe: system z obsługą interfejsu UEFI/bezpiecznego rozruchu wypróbuj {     $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop     Write-Host "Włączony bezpieczny rozruch: $secureBootEnabled" } złapać {     Write-Warning "Nie można ustalić stanu bezpiecznego rozruchu za pomocą polecenia cmdlet: $_"     # Wypróbuj rezerwowe dane rejestru     wypróbuj {         $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop         $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled         Write-Host "Włączony bezpieczny rozruch: $secureBootEnabled"     } złapać {         Write-Warning "Nie można ustalić stanu bezpiecznego rozruchu za pośrednictwem rejestru. System może nie obsługiwać interfejsu UEFI/bezpiecznego rozruchu".         $secureBootEnabled = $null         Write-Host "Włączony bezpieczny rozruch: niedostępny"     } }

# 4. HighConfidenceOptOut # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop     $highConfidenceOptOut = $regValue.HighConfidenceOptOut     Write-Host "High Confidence Opt Out: $highConfidenceOptOut" } złapać {     # HighConfidenceOptOut jest opcjonalne — nie występuje w większości systemów     $highConfidenceOptOut = $null     Write-Host "High Confidence Opt Out: Not Set" (Rezygnacja z dużej pewności siebie: nie ustawiono) }

# 4b. MicrosoftUpdateManagedOptIn # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop     $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn     Write-Host "Microsoft Update Managed Opt In: $microsoftUpdateManagedOptIn" } złapać {     # MicrosoftUpdateManagedOptIn jest opcjonalny — nie występuje w większości systemów     $microsoftUpdateManagedOptIn = $null     Write-Host "Microsoft Update Managed Opt In: Not Set" }

# 5. DostępneUpdates # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop     $availableUpdates = $regValue.AvailableUpdates     if ($null -ne $availableUpdates) {         # Konwertuj na format szesnastkowo         $availableUpdatesHex = "0x{0:X}" -f $availableUpdates         Write-Host "Dostępne Aktualizacje: $availableUpdatesHex"     } inaczej {         Write-Host "Dostępne Aktualizacje: niedostępne"     } } złapać {     Write-Warning "AvailableUpdates registry key not found or inaccessible"     $availableUpdates = $null     Write-Host "Dostępne Aktualizacje: niedostępne" }

# 5b. AvailableUpdatesPolicy (trwała wartość kontrolowana przez obiekt zasad grupy) # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop     $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy     if ($null -ne $availableUpdatesPolicy) {         # Konwertuj na format szesnastkowo         $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy         Write-Host "Dostępne zasady Aktualizacje: $availableUpdatesPolicyHex"     } inaczej {         Write-Host "Dostępne zasady Aktualizacje: nie ustawiono"     } } złapać {     # AvailableUpdatesPolicy jest opcjonalne — ustawienie tylko po zastosowaniu obiektu zasad grupy     $availableUpdatesPolicy = $null     Write-Host "Dostępne zasady Aktualizacje: nie ustawiono" }

# Rejestr: Klucz obsługi (3 wartości)

# 6. UEFICA2023Status # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop     $uefica 2023Status = $regValue.UEFICA2023Status     Write-Host "Stan systemu Windows UEFI CA 2023: $uefica 2023Status" } złapać {     Write-Warning "Klucz rejestru stanu systemu Windows UEFI CA 2023 nie został znaleziony lub niedostępny"     $uefica 2023Status = $null     Write-Host "Windows UEFI CA 2023 Status: Niedostępne" }

# 7. UEFICA2023Error # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop     $uefica 2023Error = $regValue.UEFICA2023Error     Write-Host "Błąd UEFI CA 2023: $uefica 2023Error" } złapać {     # UEFICA2023Error istnieje tylko wtedy, gdy wystąpił błąd — brak jest dobry     $uefica 2023Error = $null     Write-Host "Błąd UEFI CA 2023: Brak" }

# 8. UEFICA2023ErrorEvent # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop     $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent     Write-Host "Zdarzenie błędu UEFI CA 2023: $uefica 2023ErrorEvent" } złapać {     $uefica 2023ErrorEvent = $null     Write-Host "Zdarzenie błędu UEFI CA 2023: niedostępne" }

# Rejestr: Atrybuty urządzenia (7 wartości: 9-15)

# 9. OEMManufacturerName # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMManufacturerName -ErrorAction Stop     $oemManufacturerName = $regValue.OEMManufacturerName     if ([ciąg]:IsNullOrEmpty($oemManufacturerName)) {         Write-Warning "Nazwa OEMManufacturerName jest pusta"         $oemManufacturerName = "Nieznany"     }     Write-Host "Nazwa producenta OEM: $oemManufacturerName" } złapać {     Write-Warning "Klucz rejestru OEMManufacturerName nie został znaleziony lub niedostępny"     $oemManufacturerName = $null     Write-Host "Nazwa producenta OEM: niedostępne" }

# 10. OEMModelSystemFamily # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $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 is empty"         $oemModelSystemFamily = "Nieznany"     }     Write-Host "Rodzina systemów OEM: $oemModelSystemFamily" } złapać {     Write-Warning "Klucz rejestru OEMModelSystemFamily nie został znaleziony lub niedostępny"     $oemModelSystemFamily = $null     Write-Host "Rodzina systemów modeli OEM: niedostępne" }

# 11. OEMModelNumber # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelNumber -ErrorAction Stop     $oemModelNumber = $regValue.OEMModelNumber     if ([ciąg]:IsNullOrEmpty($oemModelNumber)) {         Write-Warning "OEMModelNumber jest pusty"         $oemModelNumber = "Nieznany"     }     Write-Host "Numer modelu OEM: $oemModelNumber" } złapać {     Write-Warning "Klucz rejestru OEMModelNumber nie został znaleziony lub niedostępny"     $oemModelNumber = $null     Write-Host "Numer modelu OEM: niedostępny" }

# 12. FirmwareVersion # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareVersion -ErrorAction Stop     $firmwareVersion = $regValue.FirmwareVersion     if ([ciąg]:IsNullOrEmpty($firmwareVersion)) {         Write-Warning "FirmwareVersion is empty" (Wersja oprogramowania układowego jest pusta)         $firmwareVersion = "Nieznany"     }     Write-Host "Wersja oprogramowania układowego: $firmwareVersion" } złapać {     Write-Warning "Klucz rejestru firmwareVersion nie został znaleziony lub niedostępny"     $firmwareVersion = $null     Write-Host "Wersja oprogramowania układowego: niedostępna" }

# 13. FirmwareReleaseDate # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $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 = "Nieznany"     }     Write-Host "Data wydania oprogramowania układowego: $firmwareReleaseDate" } złapać {     Write-Warning "FirmwareReleaseDate registry key not found or inaccessible"     $firmwareReleaseDate = $null     Write-Host "Data wydania oprogramowania układowego: niedostępne" }

# 14. OSArchitecture # Wersja PS: Wszystkie | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $osArchitecture = $env:PROCESSOR_ARCHITECTURE     if ([ciąg]:IsNullOrEmpty($osArchitecture)) {         # Wypróbuj rezerwowe dane rejestru         $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OSArchitecture -ErrorAction Stop         $osArchitecture = $regValue.OSArchitecture     }     if ([ciąg]:IsNullOrEmpty($osArchitecture)) {         Write-Warning "Nie można ustalić OSArchitecture"         $osArchitecture = "Nieznany"     }     Write-Host "Architektura systemu operacyjnego: $osArchitecture" } złapać {     Write-Warning "Error retrieving OSArchitecture: $_"     $osArchitecture = "Nieznany"     Write-Host "Architektura systemu operacyjnego: $osArchitecture" }

# 15. CanAttemptUpdateAfter (FILETIME) # Wersja PS: Wszystkie | Administracja: Może być wymagane | Wymagania systemowe: Brak wypróbuj {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop     $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter     # Convert FILETIME to UTC DateTime — registry stores as REG_BINARY (byte[]) or REG_QWORD (long)     if ($null -ne $canAttemptUpdateAfter) {         wypróbuj {             if ($canAttemptUpdateAfter -is [bajt[]]) {                 $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter; 0)                 $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime). ToUniversalTime()             } elseif ($canAttemptUpdateAfter -is [long]) {                 $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter). ToUniversalTime()             }         } złapać {             Write-Warning "Could not convert CanAttemptUpdateAfter FILETIME to DateTime"         }     }     Write-Host "Może próbować zaktualizować po: $canAttemptUpdateAfter" } złapać {     Write-Warning "CanAttemptUpdateAfter registry key not found or inaccessible"     $canAttemptUpdateAfter = $null     Write-Host "Może próbować zaktualizować po: niedostępne" }

# Dzienniki zdarzeń: Dziennik systemowy (10 wartości: 16-25)

# 16-25. Zapytania dziennika zdarzeń # Identyfikatory zdarzeń: # 1801 — Aktualizacja zainicjowana, wymagane ponowne uruchomienie # 1808 — Pomyślnie ukończono aktualizację # 1795 — Zwrócono błąd oprogramowania układowego (kod błędu przechwytywania) # 1796 — Błąd zarejestrowany z kodem błędu (kod przechwytywania) # 1800 - Wymagane ponowne uruchomienie (NIE błąd - aktualizacja będzie kontynuowana po ponownym uruchomieniu) # 1802 — Znany problem z oprogramowaniem układowym zablokował aktualizację (przechwytywanie KI_<numeru> z SkipReason) # 1803 - Pasujące aktualizacji KEK nie znaleziono (OEM musi dostarczyć PK podpisane KEK) # PS Wersja: 3.0 + | Administracja: Może być wymagane w dzienniku systemowym | Wymagania systemowe: Brak wypróbuj {     # Prześlij zapytanie o wszystkie odpowiednie identyfikatory zdarzeń bezpiecznego rozruchu     $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808)     $events = @(Get-WinEvent -FilterHashtable @{LogName='System'; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)

    jeżeli ($events. Liczba -eq 0) {         Write-Warning "Brak zdarzeń bezpiecznego rozruchu znalezionych w dzienniku systemu"         $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 "Najnowszy identyfikator zdarzenia: niedostępne"         Write-Host "Identyfikator zasobnika: niedostępny"         Write-Host "Pewność siebie: niedostępne"         Write-Host "Liczba zdarzeń 1801: 0"         Write-Host "Zdarzenie 1808 Liczba: 0"     } inaczej {         # 16. LatestEventId         $latestEvent = $events | Sort-Object TimeCreated -Descending | Select-Object -Pierwsza 1         if ($null -eq $latestEvent) {             Write-Warning "Nie można ustalić najnowszego zdarzenia"             $latestEventId = $null             Write-Host "Najnowszy identyfikator zdarzenia: niedostępne"         } inaczej {             $latestEventId = $latestEvent.Id             Write-Host "Najnowszy identyfikator zdarzenia: $latestEventId"         }

        # 17. Identyfikator zasobnika — wyodrębnione z zdarzenia 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketId:\s*(.+)') {                 $bucketId = $matches[1]. Trim()                 Write-Host "Identyfikator zasobnika: $bucketId"             } inaczej {                 Write-Warning "Nie można odnaleźć zasobnika w komunikacie zdarzenia"                 $bucketId = $null                 Write-Host "Identyfikator zasobnika: nie można odnaleźć w zdarzeniu"             }         } inaczej {             Write-Warning "Najnowsze zdarzenie lub wiadomość ma wartość null, nie można wyodrębnić identyfikatora zasobnika"             $bucketId = $null             Write-Host "Identyfikator zasobnika: niedostępne"         }

        # 18. Pewność siebie — wyodrębniona z wydarzenia 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') {                 $confidence = $matches[1]. Trim()                 Write-Host "Pewność siebie: $confidence"             } inaczej {                 Write-Warning "Poziom ufności nie można odnaleźć w komunikacie zdarzenia"                 $confidence = $null                 Write-Host "Pewność siebie: nie znaleziono w zdarzeniu"             }         } inaczej {             Write-Warning "Najnowsze zdarzenie lub wiadomość ma wartość null, nie można wyodrębnić ufności"             $confidence = $null             Write-Host "Pewność siebie: niedostępne"         }

        # 18b. SkipReason — wyodrębnianie KI_<numeru> z SkipReason w tym samym zdarzeniu co Identyfikator Zasobnika         # Spowoduje to przechwycenie identyfikatorów znanych problemów, które są wyświetlane obok identyfikatora zasobnika/ufności (nie tylko zdarzenia 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 Known Issue: $skipReasonKnownIssue" -ForegroundColor Yellow             }         }

        # 19. Event1801Count         $event 1801Array = @($events | Where-Object {$_. Identyfikator -eq 1801})         $event 1801Count = $event 1801Array.Count         Write-Host "Event 1801 Count: $event 1801Count"

        # 20. Event1808Count         $event 1808Array = @($events | Where-Object {$_. Identyfikator -eq 1808})         $event 1808Count = $event 1808Array.Count         Write-Host "Event 1808 Count: $event 1808Count"                  # Inicjowanie zmiennych zdarzeń błędu         $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                  # Sprawdź tylko występowanie zdarzeń błędów, jeśli aktualizacja NIE została ukończona         # Pomiń analizę błędów, jeśli: 1808 jest najnowszym zdarzeniem LUB UEFICA2023Status is "Updated"         $updateComplete = ($latestEventId -eq 1808) -lub ($uefica 2023Status -eq "Aktualizacja")                  jeżeli (nie $updateComplete) {             Write-Host "Update not complete - checking for error events..." -ForegroundColor Yellow                          # 21. Zdarzenie1795 — błąd oprogramowania układowego (kod błędu przechwytywania)             $event 1795Array = @($events | Where-Object {$_. Identyfikator —1795})             $event 1795Count = $event 1795Array.Count             if ($event 1795Count -gt 0) {                 $latestEvent 1795 = $event 1795Array | Sort-Object TimeCreated -Descending | Select-Object -Pierwsza 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 "Zdarzenie 1795 (błąd oprogramowania układowego) Liczba: $event 1795Count" $(if ($event 1795ErrorCode) { "Kod: $event 1795ErrorCode" })             }                          # 22. Zdarzenie1796 — Kod błędu Zarejestrowany (kod błędu przechwytywania)             $event 1796Array = @($events | Where-Object {$_. Identyfikator -eq 1796})             $event 1796Count = $event 1796Array.Count             if ($event 1796Count -gt 0) {                 $latestEvent 1796 = $event 1796Array | Sort-Object TimeCreated -Descending | Select-Object -Pierwsza 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. Zdarzenie1800 — wymagane ponowne uruchomienie (NIE jest to błąd — aktualizacja będzie kontynuowana po ponownym uruchomieniu)             $event 1800Array = @($events | Where-Object {$_. Identyfikator —1800})             $event 1800Count = $event 1800Array.Count             $rebootPending = $event 1800Count -gt 0             if ($rebootPending) {                 Write-Host "Zdarzenie 1800 (oczekiwanie na ponowne uruchomienie): Aktualizacja będzie kontynuowana po ponownym uruchomieniu" -ForegroundColor Cyan             }                          # 24. Zdarzenie1802 — znany problem z oprogramowaniem układowym (przechwytywanie numeru KI_<> z SkipReason)             $event 1802Array = @($events | Where-Object {$_. Identyfikator —eq 1802})             $event 1802Count = $event 1802Array.Count             if ($event 1802Count -gt 0) {                 $latestEvent 1802 = $event 1802Array | Sort-Object TimeCreated -Descending | Select-Object -Pierwsza 1                 if ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)') {                     $knownIssueId = $matches[1]                 }                 Write-Host "Zdarzenie 1802 (znany problem z oprogramowaniem układowym) Liczba: $event 1802Count" $(if ($knownIssueId) { "KI: $knownIssueId" })             }                          # 25. Zdarzenie1803 - Brak aktualizacji KEK (OEM musi dostarczyć KEK podpisane PK)             $event 1803Array = @($events | Where-Object {$_. Identyfikator —1803})             $event 1803Count = $event 1803Array.Count             $missingKEK = $event 1803Count -gt 0             if ($missingKEK) {                 Write-Host "Event 1803 (missing KEK): OEM needs to supply PK signed KEK" -ForegroundColor Yellow             }         } inaczej {             Write-Host "Update complete (Event 1808 or Status=Updated) - skipping error analysis" -ForegroundColor Green         }     } } złapać {     Write-Warning "Błąd podczas pobierania dzienników zdarzeń. Może wymagać uprawnień administratora: $_"     $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 "Najnowszy identyfikator zdarzenia: błąd"     Write-Host "Identyfikator zasobnika: błąd"     Write-Host "Ufność: błąd"     Write-Host "Zdarzenie 1801 Liczba: 0"     Write-Host "Zdarzenie 1808 Liczba: 0" }

# Zapytania WMI/CIM (5 wartości)

# 26. Osversion # PS Wersja: 3.0 + (użyj Get-WmiObject dla 2.0) | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -lub [string]::IsNullOrEmpty($osInfo.Version)) {         Write-Warning "Nie można pobrać wersji systemu operacyjnego"         $osVersion = "Nieznany"     } inaczej {         $osVersion = $osInfo.Version     }     Write-Host "Wersja systemu operacyjnego: $osVersion" } złapać {     # CIM może zakończyć się niepowodzeniem w niektórych środowiskach — użycie rezerwy     $osVersion = [System.Environment]::OSVersion.Version.ToString()     if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" }     Write-Host "Wersja systemu operacyjnego: $osVersion" }

# 27. LastBootTime # PS Wersja: 3.0 + (użyj Get-WmiObject dla 2.0) | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -lub $null -eq $osInfo.LastBootUpTime) {         Write-Warning "Nie można pobrać ostatniego rozruchu"         $lastBootTime = $null         Write-Host "Czas ostatniego rozruchu: niedostępny"     } inaczej {         $lastBootTime = $osInfo.LastBootUpTime         Write-Host "Czas ostatniego rozruchu: $lastBootTime"     } } złapać {     # CIM może zakończyć się niepowodzeniem w niektórych środowiskach — użycie rezerwy     wypróbuj {         $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue). Starttime     } złapać {         $lastBootTime = $null     }     if ($lastBootTime) { Write-Host "Last Boot Time: $lastBootTime" } else { Write-Host "Last Boot Time: Not Available" } }

# 28. BaseBoardManufacturer # PS Wersja: 3.0 + (użyj Get-WmiObject dla 2.0) | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -lub [string]::IsNullOrEmpty($baseBoard.Manufacturer)) {         Write-Warning "Nie można pobrać producenta płyty podstawowej"         $baseBoardManufacturer = "Nieznany"     } inaczej {         $baseBoardManufacturer = $baseBoard.Producent     }     Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" } złapać {     #CIM may fail - baseboard info is supplementary     $baseBoardManufacturer = "Nieznany"     Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" }

# 29. Produkt BaseBoard # PS Wersja: 3.0 + (użyj Get-WmiObject dla 2.0) | Administracja: Nie | Wymagania systemowe: Brak wypróbuj {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -lub [ciąg]::IsNullOrEmpty($baseBoard.Product)) {         Write-Warning "Nie można pobrać produktu baseboard"         $baseBoardProduct = "Nieznany"     } inaczej {         $baseBoardProduct = $baseBoard.Product     }     Write-Host "Produkt baseboard: $baseBoardProduct" } złapać {     #CIM may fail - baseboard info is supplementary     $baseBoardProduct = "Nieznany"     Write-Host "Produkt baseboard: $baseBoardProduct" }

# 30. SecureBootTaskEnabled # Wersja PS: Wszystkie | Administracja: Nie | Wymagania systemowe: zaplanowane zadanie istnieje # Sprawdza, czy zaplanowane zadanie bezpiecznego rozruchu jest włączone $secureBootTaskEnabled = $null $secureBootTaskStatus = "Nieznany" wypróbuj {     $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' -lub $taskData.Status -eq 'Running')         }     } inaczej {         $secureBootTaskStatus = "NotFound"         $secureBootTaskEnabled = $false     }     if ($secureBootTaskEnabled -eq $false) {         Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Enabled: $secureBootTaskEnabled)" -ForegroundColor Yellow     } inaczej {         Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Enabled: $secureBootTaskEnabled)" -ForegroundColor Green     } } złapać {     $secureBootTaskStatus = "Błąd"     $secureBootTaskEnabled = $false     Write-Host "SecureBoot Update Task: Error checking - $_" -ForegroundColor Red }

# 31. Stan klucza WinCS (F33E0C8E002 — aktualizacja certyfikatu bezpiecznego rozruchu) # Wersja PS: Wszystkie | Administracja: Tak (dla zapytania) | Wymagania systemowe: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Nieznany" wypróbuj {     # Sprawdzanie typowych lokalizacji pod kątem WinCsFlags.exe     $wincsFlagsPath = $null     $possiblePaths = @(         "$env:SystemRoot\System32\WinCsFlags.exe",         "$env:SystemRoot\SysWOW64\WinCsFlags.exe"     )     foreach ($p w $possiblePaths) {         if (Test-Path $p) { $wincsFlagsPath = $p; break }     }     if ($wincsFlagsPath) {         # Klucz zapytania — wymaga praw administratora         $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1         $queryOutputStr = $queryOutput -join "'n"         if ($LASTEXITCODE -eq 0) {             # Sprawdź, czy klawisz został zastosowany (poszukaj pozycji "Aktywna konfiguracja" lub podobny wskaźnik)             if ($queryOutputStr -match "Active Configuration.*:.*enabled" -lub $queryOutputStr -match "Configuration.*applied") {                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Zastosowano"                 Write-Host "WinCS Key F33E0C8E002: Applied" -ForegroundColor Green             } elseif ($queryOutputStr -match "nie znaleziono|Brak konfiguracji") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = "NotApplied"                 Write-Host "WinCS Key F33E0C8E002: Not Applied" -ForegroundColor Yellow             } inaczej {                 # Key exists - check output for state                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Zastosowano"                 Write-Host "WinCS Key F33E0C8E002: Applied" -ForegroundColor Green             }         } inaczej {             # Sprawdź, czy nie ma konkretnych komunikatów o błędach             if ($queryOutputStr -match "Odmowa dostępu|administrator") {                 $wincsKeyStatus = "AccessDenied"                 Write-Host "WinCS Key F33E0C8E002: Access denied (run as admin)" -ForegroundColor DarkGray             } elseif ($queryOutputStr -match "nie znaleziono|Brak konfiguracji") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = "NotApplied"                 Write-Host "WinCS Key F33E0C8E002: Not Applied" -ForegroundColor Yellow             } inaczej {                 $wincsKeyStatus = "Zapytanie nie powiodło się"                 Write-Host "F33E0C8E002 klucza WinCS: zapytanie nie powiodło się" —Kolor pierwszego planu Kolor czerwony             }         }     } inaczej {         $wincsKeyStatus = "WinCsFlagsNotFound"         Write-Host "WinCS Key F33E0C8E002: WinCsFlags.exe nie można odnaleźć" -ForegroundColor Gray     } } złapać {     $wincsKeyStatus = "Błąd"     Write-Host "WinCS Key F33E0C8E002: Error checking - $_" -ForegroundColor Red }              

# ============================================================================= # Wykrywanie korygowania — kod wyjścia stanu & # =============================================================================

# Build status object from all collected inventory data $status = [zamówione]@{     UEFICA2023Status = $uefica 2023Status     UEFICA2023Error = $uefica 2023Error     UEFICA2023ErrorEvent = $uefica 2023ErrorEvent     AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } inaczej { $null }     AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } inaczej { $null }     Hostname = $hostname     CollectionTime = if ($collectionTime -is [datetime]) { $collectionTime.ToString("o") } inaczej { "$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") } inaczej { "$canAttemptUpdateAfter" }     LatestEventId = $latestEventId     BucketId = $bucketId     Pewność siebie = $confidence     SkipReasonKnownIssue = $skipReasonKnownIssue # KI_<> numeru z skipReason w zdarzeniu BucketId     Event1801Count = $event 1801Count     Event1808Count = $event 1808Count     # Zdarzenia błędów z przechwyconymi szczegółami     Zdarzenie1795Count = $event 1795Count # Firmware returned error     Zdarzenie1795ErrorCode = $event 1795ErrorCode # Kod błędu z oprogramowania układowego     Event1796Count = $event 1796Count #Error code logged     Zdarzenie1796ErrorCode = $event 1796ErrorCode # Przechwycony kod błędu     Zdarzenie1800Count = $event 1800Count # Wymagane ponowne uruchomienie (NIE jest to błąd)     RebootPending = $rebootPending # True if Event 1800 present     Event1802Count = $event 1802Count # Znany problem z oprogramowaniem układowym     KnownIssueId = $knownIssueId # KI_<> numeru z SkipReason     Event1803Count = $event 1803Count # Missing KEK update     MissingKEK = $missingKEK # OEM musi dostarczyć KEK podpisane PK     OSVersion = $osVersion     LastBootTime = if ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } inaczej { "$lastBootTime" }     BaseBoardManufacturer = $baseBoardManufacturer     BaseBoardProduct = $baseBoardProduct     SecureBootTaskEnabled = $secureBootTaskEnabled     SecureBootTaskStatus = $secureBootTaskStatus     WinCSKeyApplied = $wincsKeyApplied # True, jeśli zastosowano klawisz F33E0C8E002     WinCSKeyStatus = $wincsKeyStatus # Applied, NotApplied, WinCsFlagsNotFound itp. }

# Wyprowadź stan — dla agregacji danych $jsonOutput = $status | ConvertTo-Json -Kompresuj

# Jeśli program OutputPath jest podany, zapisz go w pliku; w przeciwnym razie dane wyjściowe do stdout if (-not [string]::IsNullOrEmpty($OutputPath)) {     #Validate OutputPath - skip if it looks like a help request or has invalid chars     if ($OutputPath -match '^[/\-]' -lub $OutputPath -match '[<>:"|? *]') {         Write-Host "Określono nieprawidłowy program OutputPath, wyjście do wydruku" —Kolor pierwszego planu Żółty         Write-Output $jsonOutput         if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") { exit 0 } inaczej { exit 1 }     }          # Upewnij się, że folder wyjściowy istnieje     if (-not (Test-Path $OutputPath)) {         wypróbuj {             New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null         } złapać {             Write-Warning "Nie można utworzyć folderu wyjściowego: $OutputPath - $_"         }     }          # Zapisz w HOSTNAME_latest.json     $outputFile = Join-Path $OutputPath "$($hostname)_latest.json"     wypróbuj {         $jsonOutput | Out-File -FilePath $outputFile -Kodowanie UTF8 -Force         Write-Host "JSON saved to: $outputFile" -ForegroundColor Green     } złapać {         Write-Warning "Nie można pisać do pliku: $outputFile - $_"         # Powrót do stdout         Write-Output $jsonOutput     } } inaczej {     # Oryginalne zachowanie — wyjście do stdout     Write-Output $jsonOutput }

# Kod wyjścia: "Zaktualizowano" to wartość sukcesu dla każdego podręcznika if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") {     exit 0 # Without issue } inaczej {     exit 1 # With issue }

Potrzebujesz dalszej pomocy?

Chcesz uzyskać więcej opcji?

Poznaj korzyści z subskrypcji, przeglądaj kursy szkoleniowe, dowiedz się, jak zabezpieczyć urządzenie i nie tylko.