Gilt für
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

Ursprüngliches Veröffentlichungsdatum: 17. November 2025

KB ID: 5072718

Datum ändern

Beschreibung ändern

24. Februar 2026

  • Das Beispielskript zur Sammlung von Secure-Boot-Bestandsdaten wurde aktualisiert.

22. Februar 2026

  • Das Beispielskript zur Sammlung von Secure-Boot-Bestandsdaten wurde aktualisiert.

13. Februar 2026

  • Das Beispielskript zur Sammlung von Secure-Boot-Bestandsdaten wurde aktualisiert.

Beispielskript zur Sammlung von Secure-Boot-Bestandsdaten

Kopieren Sie dieses Beispielskript, fügen Sie es ein und passen Sie es bei Bedarf an Ihre Umgebung an: Das Beispielskript zur Sammlung von Secure-Boot-Bestandsdaten.

<# .SYNOPSIS     Erkennt den Status von Secure-Boot-Zertifikatupdates zur flottenweiten Überwachung.

.BESCHREIBUNG     Dieses Erkennungsskript sammelt den Secure-Boot-Status, Registrierungswerte zu Zertifikatupdates,     und Geräteinformationen. Es gibt eine JSON-Zeichenfolge zur Überwachung und Berichterstellung aus.

    Kompatibel mit Intune-Remediations, GPO-basierter Sammlung und anderen Verwaltungstools.     Es wird kein Korrekturskript benötigt – dies dient nur der Überwachung.

    Exit 0 = "Without issue" (Zertifikate aktualisiert)     Exit 1 = "With issue" (Zertifikate nicht aktualisiert – nur informativ)

.PARAMETER OutputPath     Optional. Pfad zu einem Ordner, in dem die JSON-Datei gespeichert wird.     Falls angegeben, wird HOSTNAME_latest.json in diesem Ordner gespeichert.     Wenn nicht angegeben, wird JSON an stdout ausgegeben (ursprüngliches Verhalten).

. BEISPIEL     # Ausgabe in stdout (Intune/SCCM-Erkennung) &nbsp; .\Detect-SecureBootCertUpdateStatus.ps1

. BEISPIEL     # In Netzwerkfreigabe speichern (GPO-Bereitstellung) &nbsp; .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"

.NOTIZEN     Registrierungspfade laut https://aka.ms/securebootplaybook:       HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecureBoot       HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\Servicing

    DIE SOFTWARE WIRD „WIE BESEHEN“ UND OHNE GARANTIE JEGLICHER ART BEREITGESTELLT, OB AUSDRÜCKLICH ODER     STILLSCHWEIGEND, EINSCHLIESSLICH U. A. DEN GARANTIEN DER MARKTGÄNGIGKEIT,     EIGNUNG FÜR EINEN BESTIMMTEN ZWECK UND NICHTVERLETZUNG GEWERBLICHER SCHUTZRECHTE. IN KEINEM FALL ÜBERNEHMEN DIE     AUTOREN ODER URHEBERRECHTSINHABER EINE HAFTUNG FÜR ANSPRÜCHE, SCHÄDEN ODER ANDERE     HAFTUNGEN, OB IM RAHMEN EINES VERTRAGS, UNERLAUBTER HANDLUNG ODER ANDERWEITIG, DIE SICH AUS     ODER IN VERBINDUNG MIT DER SOFTWARE ODER DER VERWENDUNG ODER ANDEREN AKTIVITÄTEN MIT DER     SOFTWARE ERGEBEN. #> param(     [Parameter(Mandatory = $false)]     [string]$OutputPath )

# Download-URL: https://aka.ms/getsecureboot -> "Beispiele für Bereitstellung und Überwachung" # Hinweis: Dieses Skript wird auf Endpunkten ausgeführt, um Daten zum Secure-Boot-Status zu sammeln.

# 1. HostName # PS Version: Alle | Admin: Nein | Systemanforderungen: Keine try {     $hostname = $env:COMPUTERNAME     if ([string]::IsNullOrEmpty($hostname)) {         Write-Warning "Hostname konnte nicht ermittelt werden"         $hostname = "Unbekannt"     }     Write-Host "Hostname: $hostname" } catch {     Write-Warning "Fehler beim Abrufen des Hostnamens: $_"     $hostname = "Fehler"     Write-Host "Hostname: $hostname" }

# 2. CollectionTime # PS Version: Alle | Admin: Nein | Systemanforderungen: Keine try {     $collectionTime = Get-Date     if ($null -eq $collectionTime) {         Write-Warning "Aktuelles Datum/Uhrzeit konnte nicht abgerufen werden"         $collectionTime = "Unbekannt"     }     Write-Host "Erfassungszeit: $collectionTime" } catch {     Write-Warning "Fehler beim Abrufen von Datum/Uhrzeit: $_"     $collectionTime = "Fehler"     Write-Host "Erfassungszeit: $collectionTime" }

# Registrierung: Secure Boot Main Key (3 Werte)

# 3. SecureBootEnabled # PS Version: 3.0 und höher | Admin: Möglicherweise erforderlich | Systemanforderungen: UEFI/Secure-Boot-fähiges System try {     $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop     Write-Host "Secure Boot aktiviert: $secureBootEnabled" } catch {     Write-Warning "Secure-Boot-Status konnte nicht über das Cmdlet ermittelt werden: $_"     # Versuchen Sie das Fallback über die Registrierung     try {         $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop         $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled         Write-Host "Secure Boot aktiviert: $secureBootEnabled"     } catch {         Write-Warning "Secure-Boot-Status konnte nicht über die Registrierung ermittelt werden." Das System unterstützt UEFI/Secure Boot möglicherweise nicht."         $secureBootEnabled = $null         Write-Host "Secure Boot aktiviert: Nicht verfügbar"     } }

# 4. HighConfidenceOptOut # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop     $highConfidenceOptOut = $regValue.HighConfidenceOptOut     Write-Host "High Confidence Opt Out: $highConfidenceOptOut" } catch {     # HighConfidenceOptOut ist optional – auf den meisten Systemen nicht vorhanden     $highConfidenceOptOut = $null     Write-Host "High Confidence Opt Out: Nicht festgelegt" }

# 4b. MicrosoftUpdateManagedOptIn # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop     $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn     Write-Host "Von Microsoft Update verwaltete Anmeldung: $microsoftUpdateManagedOptIn" } catch {     # MicrosoftUpdateManagedOptIn ist optional und auf den meisten Systemen nicht vorhanden.     $microsoftUpdateManagedOptIn = $null     Write-Host "Von Microsoft Update verwaltete Anmeldung: Nicht festgelegt" }

# 5. AvailableUpdates # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop     $availableUpdates = $regValue.AvailableUpdates     if ($null -ne $availableUpdates) {         # In hexadezimales Format konvertieren         $availableUpdatesHex = "0x{0:X}" -f $availableUpdates         Write-Host "Verfügbare Updates: $availableUpdatesHex"     } else {         Write-Host "Verfügbare Updates: Nicht verfügbar"     } } catch {     Write-Warning "AvailableUpdates-Registrierungsschlüssel nicht gefunden oder nicht zugänglich"     $availableUpdates = $null     Write-Host "Verfügbare Updates: Nicht verfügbar" }

# 5b. AvailableUpdatesPolicy (vom GPO gesteuerter persistenter Wert) # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop     $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy     if ($null -ne $availableUpdatesPolicy) {         # In hexadezimales Format konvertieren         $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy         Write-Host "Richtlinie für verfügbare Updates: $availableUpdatesPolicyHex"     } else {         Write-Host "Richtlinie für verfügbare Updates: Nicht festgelegt"     } } catch {     # AvailableUpdatesPolicy ist optional – nur gesetzt, wenn GPO angewendet wird     $availableUpdatesPolicy = $null     Write-Host "Richtlinie für verfügbare Updates: Nicht festgelegt" }

# Registrierung: Servicing Key (3 Werte)

# 6. UEFICA2023Status # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop     $uefica2023Status = $regValue.UEFICA2023Status     Write-Host "Windows UEFI CA 2023 Status: $uefica2023Status" } catch {     Write-Warning "Windows UEFI CA 2023 Status-Registrierungsschlüssel nicht gefunden oder nicht zugänglich"     $uefica2023Status = $null     Write-Host "Windows UEFI CA 2023 Status: Nicht verfügbar" }

# 7. UEFICA2023Fehler # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop     $uefica2023Error = $regValue.UEFICA2023Error     Write-Host "UEFI CA 2023 Fehler: $uefica2023Error" } catch {     # UEFICA2023Error ist nur vorhanden, wenn ein Fehler aufgetreten ist – Abwesenheit ist gut     $uefica2023Error = $null     Write-Host "UEFI CA 2023 Fehler: Keine" }

# 8. UEFICA2023ErrorEvent # PS-Version: Alle | Administrator: Möglicherweise erforderlich | Systemanforderungen: Keine versuchen{    $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop &nbsp; &nbsp; $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent &nbsp; &nbsp; Write-Host "UEFI CA 2023 Error Event: $uefica 2023ErrorEvent" } catch { &nbsp; $uefica 2023ErrorEvent = $null &nbsp; Schreibhost "UEFI CA 2023-Fehlerereignis: Nicht verfügbar" }

# Registrierung: Geräteattribute (7 Werte: 9-15)

# 9. OEMManufacturerName # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine 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 ist leer"         $oemManufacturerName = "Unbekannt"     }     Write-Host "OEM-Herstellername: $oemManufacturerName" } catch {     Write-Warning "OEMManufacturerName-Registrierungsschlüssel nicht gefunden oder nicht zugänglich"     $oemManufacturerName = $null     Write-Host "OEM-Herstellername: Nicht verfügbar" }

# 10. OEMModelSystemFamily # PS-Version: Alle | Administrator: Möglicherweise erforderlich | Systemanforderungen: Keine versuchen{    $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelSystemFamily -ErrorAction Stop &nbsp; &nbsp; $oemModelSystemFamily = $regValue.OEMModelSystemFamily &nbsp; wenn ([Zeichenfolge]::IsNullOrEmpty($oemModelSystemFamily)) { &nbsp; &nbsp; &nbsp; &nbsp; Schreibwarnung "OEMModelSystemFamily is empty" &nbsp; &nbsp; &nbsp; $oemModelSystemFamily = "Unknown" &nbsp; &nbsp; } &nbsp; Write-Host "OEM Model System Family: $oemModelSystemFamily" } catch { &nbsp; Schreibwarnung "OEMModelSystemFamily-Registrierungsschlüssel nicht gefunden oder nicht zugänglich" &nbsp; $oemModelSystemFamily = $null &nbsp; Schreibhost "OEM-Modellsystemfamilie: Nicht verfügbar" }

# 11. OEMModelNumber # PS-Version: Alle | Administrator: Möglicherweise erforderlich | Systemanforderungen: Keine versuchen{    $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelNumber -ErrorAction Stop &nbsp; &nbsp; $oemModelNumber = $regValue.OEMModelNumber &nbsp; wenn ([Zeichenfolge]::IsNullOrEmpty($oemModelNumber)) { &nbsp; &nbsp; &nbsp; &nbsp; Schreibwarnung "OEMModelNumber is empty" &nbsp; &nbsp; &nbsp; $oemModelNumber = "Unknown" &nbsp; &nbsp; } &nbsp; &nbsp; Write-Host "OEM Model Number: $oemModelNumber" } catch { &nbsp; Schreibwarnung "OEMModelNumber-Registrierungsschlüssel nicht gefunden oder nicht zugänglich" &nbsp; $oemModelNumber = $null &nbsp; Schreibhost "OEM-Modellnummer: Nicht verfügbar" }

# 12. FirmwareVersion # PS-Version: Alle | Administrator: Möglicherweise erforderlich | Systemanforderungen: Keine versuchen{    $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareVersion -ErrorAction Stop &nbsp; &nbsp; $firmwareVersion = $regValue.FirmwareVersion &nbsp; wenn ([Zeichenfolge]::IsNullOrEmpty($firmwareVersion)) { &nbsp; &nbsp; &nbsp; &nbsp; Schreibwarnung "FirmwareVersion is empty" &nbsp; &nbsp; &nbsp; $firmwareVersion = "Unknown" &nbsp; &nbsp; } &nbsp; &nbsp; Write-Host "Firmwareversion: $firmwareVersion" } catch { &nbsp; Schreibwarnung "FirmwareVersion-Registrierungsschlüssel nicht gefunden oder nicht zugänglich" &nbsp; $firmwareVersion = $null &nbsp; Schreibhost "Firmwareversion: Nicht verfügbar" }

# 13. FirmwareReleaseDate # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine 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 ist leer"         $firmwareReleaseDate = "Unbekannt"     }     Write-Host "Firmware-Veröffentlichungsdatum: $firmwareReleaseDate" } catch {     Write-Warning "FirmwareReleaseDate-Registrierungsschlüssel nicht gefunden oder nicht zugänglich"     $firmwareReleaseDate = $null     Write-Host "Firmware-Veröffentlichungsdatum: Nicht verfügbar" }

# 14. OSArchitecture # PS Version: Alle | Admin: Nein | Systemanforderungen: Keine try {     $osArchitecture = $env:PROCESSOR_ARCHITECTURE     if ([string]::IsNullOrEmpty($osArchitecture)) {         # Versuchen Sie das Fallback über die Registrierung         $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 konnte nicht bestimmt werden"         $osArchitecture = "Unbekannt"     }     Write-Host "Betriebssystemarchitektur: $osArchitecture" } catch {     Write-Warning "Fehler beim Abrufen von OSArchitecture: $_"     $osArchitecture = "Unbekannt"     Write-Host "Betriebssystemarchitektur: $osArchitecture" }

# 15. CanAttemptUpdateAfter (FILETIME) # PS Version: Alle | Admin: Möglicherweise erforderlich | Systemanforderungen: Keine try {     $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop     $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter     # FILETIME in UTC-Datum und -Uhrzeit konvertieren – im Registrierungswert als REG_BINARY (Byte[]) oder REG_QWORD (long) gespeichert     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 "Kann CanAttemptUpdateAfter FILETIME nicht in DateTime konvertieren"         }     }     Write-Host "Kann Updateversuch nach: $canAttemptUpdateAfter starten" } catch {     Write-Warning "CanAttemptUpdateAfter-Registrierungsschlüssel nicht gefunden oder nicht zugänglich"     $canAttemptUpdateAfter = $null     Write-Host "Kann Updateversuch nach: Nicht verfügbar" }

# Ereignisprotokolle: Systemprotokoll (10 Werte: 16-25)

# 16-25. Ereignisprotokollabfragen # Ereignis-IDs: #   1801 – Update initiiert, Neustart erforderlich #   1808 – Update erfolgreich abgeschlossen #   1795 – Firmwarefehler zurückgegeben (Fehlercode erfassen) #   1796 – Fehler mit Fehlercode protokolliert (Code erfassen) #   1800 – Neustart erforderlich (KEIN Fehler – Update wird nach Neustart fortgesetzt) #   1802 – Bekanntes Firmwareproblem blockierte das Update (KI_<number> aus SkipReason erfassen) #   1803 – Passendes KEK-Update nicht gefunden (OEM muss PK-signiertes KEK bereitstellen) # PS Version: 3.0 und höher | Admin: Für Systemprotokoll möglicherweise erforderlich | Systemanforderungen: Keine try {     # Alle relevanten Secure-Boot-Ereignis-IDs abfragen     $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 "Im Systemprotokoll wurden keine Secure-Boot-Ereignisse gefunden"         $latestEventId = $null         $bucketId = $null         $confidence = $null         $skipReasonKnownIssue = $null         $event1801Count = 0         $event1808Count = 0         $event1795Count = 0         $event1795ErrorCode = $null         $event1796Count = 0         $event1796ErrorCode = $null         $event1800Count = 0         $rebootPending = $false         $event1802Count = 0         $knownIssueId = $null         $event1803Count = 0         $missingKEK = $false         Write-Host "Neueste Ereignis-ID: Nicht verfügbar"         Write-Host "Bucket-ID: Nicht verfügbar"         Write-Host "Konfidenz: Nicht verfügbar"         Write-Host "Ereignis 1801 Count: 0"         Write-Host "Ereignis 1808 Count: 0"     } else {         # 16. LatestEventId         $latestEvent = $events | Sort-Object TimeCreated -Descending | Select-Object -First 1         if ($null -eq $latestEvent) {             Write-Warning "Das neueste Ereignis konnte nicht ermittelt werden"             $latestEventId = $null             Write-Host "Neueste Ereignis-ID: Nicht verfügbar"         } else {             $latestEventId = $latestEvent.Id             Write-Host "Neueste Ereignis-ID: $latestEventId"         }

        # 17. BucketID – Extrahiert aus Ereignis 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketId:\s*(.+)') {                 $bucketId = $matches[1].Trim()                 Write-Host "Bucket-ID: $bucketId"             } else {                 Write-Warning "BucketId in Ereignismeldung nicht gefunden"                 $bucketId = $null                 Write-Host "Bucket-ID: Im Ereignis nicht gefunden"             }         } else {             Write-Warning "Neueste Ereignis oder Nachricht ist NULL, BucketId kann nicht extrahiert werden"             $bucketId = $null             Write-Host "Bucket-ID: Nicht verfügbar"         }

        # 18. Konfidenz : Extrahiert aus Ereignis 1801/1808         if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) {             if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') {                 $confidence = $matches[1]. Trim()                 Write-Host "Vertrauen: $confidence"             } else {                 Write-Warning "Konfidenzniveau in Ereignismeldung nicht gefunden"                 $confidence = $null                 Write-Host "Confidence: Not Found in Event"             }         } else {             Write-Warning "Latest event or message is NULL, cannot extract Confidence" (Aktuelles Ereignis oder neueste Nachricht ist NULL, kann die Zuverlässigkeit nicht extrahieren)             $confidence = $null             Write-Host "Konfidenz: Nicht verfügbar"         }

        # 18b. SkipReason – Extrahieren KI_<number> aus SkipReason im selben Ereignis wie BucketId         # Erfasst bekannte Problem-IDs, die zusammen mit BucketId/Konfidenz angezeigt werden (nicht nur Ereignis 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         $event1801Array = @($events | Where-Object {$_.Id -eq 1801})         $event1801Count = $event1801Array.Count         Write-Host "Ereignis 1801 Anzahl: $event1801Count"

        # 20. Event1808Count         $event1808Array = @($events | Where-Object {$_.Id -eq 1808})         $event1808Count = $event1808Array.Count         Write-Host "Ereignis 1808 Count: $event1808Count"                  # Fehlerereignisvariablen initialisieren         $event1795Count = 0         $event1795ErrorCode = $null         $event1796Count = 0         $event1796ErrorCode = $null         $event1800Count = 0         $rebootPending = $false         $event1802Count = 0         $knownIssueId = $null         $event1803Count = 0         $missingKEK = $false                  # Nur nach Fehlerereignissen suchen, wenn das Update NICHT abgeschlossen ist         # Fehleranalyse überspringen, wenn 1808 das neueste Ereignis ist ODER UEFICA2023Status "Updated" ist         $updateComplete = ($latestEventId -eq 1808) -or ($uefica2023Status -eq "Updated")                  if (-not $updateComplete) {             Write-Host "Update nicht abgeschlossen – Überprüfung auf Fehlerereignisse..." -ForegroundColor Yellow                          # 21. Event1795 – Firmware-Fehler (Fehlercode erfassen)             $event1795Array = @($events | Where-Object {$_.Id -eq 1795})             $event1795Count = $event1795Array.Count             if ($event1795Count -gt 0) {                 $latestEvent1795 = $event1795Array | Sort-Object TimeCreated -Descending | Select-Object -First 1                 if ($latestEvent1795.Message -match '(?:error|code|status)[:\s]*(?:0x)?([0-9A-Fa-f]{8}|[0-9A-Fa-f]+)') {                     $event1795ErrorCode = $matches[1]                 }                 Write-Host "Event 1795 (Firmware-Fehler) Count: $event1795Count" $(if ($event1795ErrorCode) { "Code: $event1795ErrorCode" })             }                          # 22. Event1796 – Fehlercode protokolliert (Fehlercode erfassen)             $event1796Array = @($events | Where-Object {$_.Id -eq 1796})             $event1796Count = $event1796Array.Count             if ($event1796Count -gt 0) {                 $latestEvent1796 = $event1796Array | Sort-Object TimeCreated -Descending | Select-Object -First 1                 if ($latestEvent1796.Message -match '(?:error|code|status)[:\s]*(?:0x)?([0-9A-Fa-f]{8}|[0-9A-Fa-f]+)') {                     $event1796ErrorCode = $matches[1]                 }                 Write-Host "Event 1796 (Fehler protokolliert) Count: $event1796Count" $(if ($event1796ErrorCode) { "Code: $event1796ErrorCode" })             }                          # 23. Event1800 – Neustart erforderlich (KEIN Fehler – Update wird nach dem Neustart fortgesetzt)             $event1800Array = @($events | Where-Object {$_.Id -eq 1800})             $event1800Count = $event1800Array.Count             $rebootPending = $event1800Count -gt 0             if ($rebootPending) {                 Write-Host "Ereignis 1800 (Neustart ausstehend): Update wird nach dem Neustart fortgesetzt" -ForegroundColor Cyan             }                          # 24. Event1802 – Bekanntes Firmwareproblem (Erfassen KI_<number> von SkipReason)             $event1802Array = @($events | Where-Object {$_.Id -eq 1802})             $event1802Count = $event1802Array.Count             if ($event1802Count -gt 0) {                 $latestEvent1802 = $event1802Array | Sort-Object TimeCreated -Descending | Select-Object -First 1                 if ($latestEvent1802.Message -match 'SkipReason:\s*(KI_\d+)') {                     $knownIssueId = $matches[1]                 }                 Write-Host "Ereignis 1802 (Bekanntes Firmwareproblem) Anzahl: $event1802Count" $(if ($knownIssueId) { "KI: $knownIssueId" })             }                          # 25. Event1803 – Fehlendes KEK-Update (OEM muss PK-signierten KEK bereitstellen)             $event1803Array = @($events | Where-Object {$_.Id -eq 1803})             $event1803Count = $event1803Array.Count             $missingKEK = $event1803Count -gt 0             if ($missingKEK) {                 Write-Host "Ereignis 1803 (Fehlendes KEK): OEM muss PK-signierten KEK bereitstellen" -ForegroundColor Yellow             }         } else {             Write-Host "Update abgeschlossen (Ereignis 1808 oder Status=Aktualisiert) – Fehleranalyse wird übersprungen" -ForegroundColor Green         }     } } catch {     Write-Warning "Fehler beim Abrufen der Ereignisprotokolle." Möglicherweise sind Administratorrechte erforderlich: $_"     $latestEventId = $null     $bucketId = $null     $confidence = $null     $skipReasonKnownIssue = $null     $event1801Count = 0     $event1808Count = 0     $event1795Count = 0     $event1795ErrorCode = $null     $event1796Count = 0     $event1796ErrorCode = $null     $event1800Count = 0     $rebootPending = $false     $event1802Count = 0     $knownIssueId = $null     $event1803Count = 0     $missingKEK = $false     Write-Host "Neueste Ereignis-ID: Fehler"     Write-Host "Bucket-ID: Fehler"     Write-Host "Zuverlässigkeit: Fehler"     Write-Host "Ereignis 1801 Anzahl: 0"     Write-Host "Ereignis 1808 Anzahl: 0" }

# WMI/CIM-Abfragen (5 Werte)

# 26. OSVersion # PS Version: 3.0 und höher (für 2.0 Get-WmiObject verwenden) | Admin: Nein | Systemanforderungen: Keine try {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -or [string]::IsNullOrEmpty($osInfo.Version)) {         Write-Warning "Betriebssystemversion konnte nicht abgerufen werden"         $osVersion = "Unbekannt"     } else {         $osVersion = $osInfo.Version     }     Write-Host "Betriebssystemversion: $osVersion" } catch {     # CIM kann in manchen Umgebungen fehlschlagen – Fallback     $osVersion = [System.Environment]::OSVersion.Version.ToString()     if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unbekannt" }     Write-Host "Betriebssystemversion: $osVersion" }

# 27. LastBootTime # PS Version: 3.0 und höher (für 2.0 Get-WmiObject verwenden) | Admin: Nein | Systemanforderungen: Keine try {     $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop     if ($null -eq $osInfo -or $null -eq $osInfo.LastBootUpTime) {         Write-Warning "Zeitpunkt des letzten Starts konnte nicht abgerufen werden"         $lastBootTime = $null         Write-Host "Zeitpunkt des letzten Starts: Nicht verfügbar"     } else {         $lastBootTime = $osInfo.LastBootUpTime         Write-Host "Zeitpunkt des letzten Starts: $lastBootTime"     } } catch {     # CIM kann in manchen Umgebungen fehlschlagen – Fallback     try {         $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue).StartTime     } catch {         $lastBootTime = $null     }     if ($lastBootTime) { Write-Host "Zeitpunkt des letzten Starts: $lastBootTime" } else { Write-Host "Zeitpunkt des letzten Starts: Nicht verfügbar" } }

# 28. BaseBoardManufacturer # PS Version: 3.0 und höher (für 2.0 Get-WmiObject verwenden) | Admin: Nein | Systemanforderungen: Keine try {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) {         Write-Warning "Baseboardhersteller konnte nicht abgerufen werden"         $baseBoardManufacturer = "Unbekannt"     } else {         $baseBoardManufacturer = $baseBoard.Manufacturer     }     Write-Host "Baseboardhersteller: $baseBoardManufacturer" } catch {     # CIM kann fehlschlagen – Baseboard-Informationen sind ergänzend     $baseBoardManufacturer = "Unbekannt"     Write-Host "Baseboardhersteller: $baseBoardManufacturer" }

# 29. BaseBoardProduct # PS Version: 3.0 und höher (für 2.0 Get-WmiObject verwenden) | Admin: Nein | Systemanforderungen: Keine try {     $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop     if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) {         Write-Warning "Baseboardprodukt konnte nicht abgerufen werden"         $baseBoardProduct = "Unbekannt"     } else {         $baseBoardProduct = $baseBoard.Product     }     Write-Host "Baseboardprodukt: $baseBoardProduct" } catch {     # CIM kann fehlschlagen – Baseboard-Informationen sind ergänzend     $baseBoardProduct = "Unbekannt"     Write-Host "Baseboardprodukt: $baseBoardProduct" }

# 30. SecureBootTaskEnabled # PS Version: Alle | Admin: Nein | Systemanforderungen: Geplante Aufgabe vorhanden # Prüft, ob die geplante Aufgabe "Secure-Boot-Update" aktiviert ist $secureBootTaskEnabled = $null $secureBootTaskStatus = "Unbekannt" 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 = "Nicht gefunden"         $secureBootTaskEnabled = $false     }     if ($secureBootTaskEnabled -eq $false) {         Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Aktiviert: $secureBootTaskEnabled)" -ForegroundColor Yellow     } else {         Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Aktiviert: $secureBootTaskEnabled)" -ForegroundColor Green     } } catch {     $secureBootTaskStatus = "Fehler"     $secureBootTaskEnabled = $false     Write-Host "SecureBoot-Updatetask: Fehler bei der Überprüfung – $_" -ForegroundColor Red }

# 31. WinCS-Schlüsselstatus (F33E0C8E002 – Secure Boot-Zertifikataktualisierung) # PS-Version: Alle | Admin: Ja (für Abfrage) | Systemanforderungen: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Unbekannt" try {     # Überprüfe übliche Speicherorte für WinCsFlags.exe     $wincsFlagsPath = $null     $possiblePaths = @(         "$env:SystemRoot\System32\WinCsFlags.exe",         "$env:SystemRoot\SysWOW64\WinCsFlags.exe"     )     foreach ($p in $possiblePaths) {         if (Test-Path $p) {{ $wincsFlagsPath = $p; break }}     }          if ($wincsFlagsPath) {         # Schlüssel abfragen – erfordert Administratorrechte         $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1         $queryOutputStr = $queryOutput -join "`n"                  if ($LASTEXITCODE -eq 0) {             # Prüfe, ob der Schlüssel angewendet ist (Suche nach "Active Configuration" oder ähnlichem Indikator)             if ($queryOutputStr -match "Active Configuration.*:.*enabled" -or $queryOutputStr -match "Configuration.*applied") {                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Angewendet"                 Write-Host "WinCS Key F33E0C8E002: Angewendet" -ForegroundColor Green             } elseif ($queryOutputStr -match "not found|No configuration") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = "NichtAngewendet"                 Write-Host "WinCS Key F33E0C8E002: Nicht angewendet" -ForegroundColor Yellow             } else {                 # Schlüssel vorhanden – Ausgabe auf Status prüfen                 $wincsKeyApplied = $true                 $wincsKeyStatus = "Angewendet"                 Write-Host "WinCS Key F33E0C8E002: Angewendet" -ForegroundColor Green             }         } else {             # Prüfe auf spezifische Fehlermeldungen             if ($queryOutputStr -match "Access denied|administrator") {                 $wincsKeyStatus = "ZugriffVerweigert"                 Write-Host "WinCS Key F33E0C8E002: Zugriff verweigert (als Administrator ausführen)" -ForegroundColor DarkGray             } elseif ($queryOutputStr -match "not found|No configuration") {                 $wincsKeyApplied = $false                 $wincsKeyStatus = "NichtAngewendet"                 Write-Host "WinCS Key F33E0C8E002: Nicht angewendet" -ForegroundColor Yellow             } else {                 $wincsKeyStatus = "AbfrageFehlgeschlagen"                 Write-Host "WinCS Key F33E0C8E002: Abfrage fehlgeschlagen" -ForegroundColor Red             }         }     } else {         $wincsKeyStatus = "WinCsFlagsNichtGefunden"         Write-Host "WinCS Key F33E0C8E002: WinCsFlags.exe nicht gefunden" -ForegroundColor Gray     } } catch {     $wincsKeyStatus = "Fehler"     Write-Host "WinCS Key F33E0C8E002: Fehler bei der Überprüfung – $_" -ForegroundColor Red }

# ============================================================================= # Erkennung der Wartung – Statusausgabe und Exitcode # =============================================================================

# Statusobjekt aus allen gesammelten Bestandsdaten erstellen $status = [ordered]@{     UEFICA2023Status = $uefica2023Status     UEFICA2023Error = $uefica2023Error     UEFICA2023ErrorEvent = $uefica2023ErrorEvent     AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } else { $null }     AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } else { $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 = $confidence     SkipReasonKnownIssue = $skipReasonKnownIssue # KI_<number> aus SkipReason im BucketId-Ereignis     Event1801Count = $event1801Count     Event1808Count = $event1808Count     # Fehlerereignisse mit erfassten Details     Event1795Count = $event1795Count # Firmware hat Fehler zurückgegeben     Event1795ErrorCode = $event1795ErrorCode # Fehlercode von Firmware     Event1796Count = $event1796Count # Fehlercode protokolliert     Event1796ErrorCode = $event1796ErrorCode # Erfasster Fehlercode     Event1800Count = $event1800Count # Neustart erforderlich (KEIN Fehler)     RebootPending = $rebootPending # True, wenn Ereignis 1800 vorhanden     Event1802Count = $event1802Count # Bekanntes Firmwareproblem     KnownIssueId = $knownIssueId # KI_<number> aus SkipReason     Event1803Count = $event1803Count # Fehlendes KEK-Update     MissingKEK = $missingKEK # OEM muss PK-signierten KEK bereitstellen     OSVersion = $osVersion     LastBootTime = if ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } else { "$lastBootTime" }     BaseBoardManufacturer = $baseBoardManufacturer     BaseBoardProduct = $baseBoardProduct     SecureBootTaskEnabled = $secureBootTaskEnabled     SecureBootTaskStatus = $secureBootTaskStatus     WinCSKeyApplied = $wincsKeyApplied # True, wenn F33E0C8E002-Schlüssel angewendet     WinCSKeyStatus = $wincsKeyStatus # Angewendet, Nicht angewendet, WinCsFlagsNichtGefunden usw. }

# Ausgabe des Status – für die Datenaggregation $jsonOutput = $status | ConvertTo-Json -Compress

# Wenn OutputPath angegeben ist, speichern in Datei; sonst Ausgabe auf stdout if (-not [string]::IsNullOrEmpty($OutputPath)) {     # OutputPath prüfen – überspringen, wenn es wie eine Hilfefrage aussieht oder ungültige Zeichen enthält     if ($OutputPath -match '^[/\-]' -or $OutputPath -match '[<>:"|?*]') {         Write-Host "Ungültiger OutputPath angegeben, Ausgabe erfolgt auf stdout" -ForegroundColor Yellow         Write-Output $jsonOutput         if ($secureBootEnabled -and $uefica2023Status -eq "Updated") {{ exit 0 }} else {{ exit 1 }}     }          # Sicherstellen, dass der Ausgabeordner existiert     if (-not (Test-Path $OutputPath)) {         try {             New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null         } catch {             Write-Warning "Ausgabeordner konnte nicht erstellt werden: $OutputPath – $_"         }     }          # Speichern in HOSTNAME_latest.json     $outputFile = Join-Path $OutputPath "$($hostname)_latest.json"     try {         $jsonOutput | Out-File -FilePath $outputFile -Encoding UTF8 -Force         Write-Host "JSON gespeichert in: $outputFile" -ForegroundColor Green     } catch {         Write-Warning "Konnte nicht in Datei schreiben: $outputFile – $_"         # Fallback auf stdout         Write-Output $jsonOutput     } } else {     # Ursprüngliches Verhalten – Ausgabe auf stdout     Write-Output $jsonOutput }

# Exitcode: "Updated" ist der Erfolgswert laut Playbook if ($secureBootEnabled -and $uefica2023Status -eq "Updated") {     exit 0  # Ohne Probleme } else {     exit 1  # Mit Problemen }

Benötigen Sie weitere Hilfe?

Möchten Sie weitere Optionen?

Erkunden Sie die Abonnementvorteile, durchsuchen Sie Trainingskurse, erfahren Sie, wie Sie Ihr Gerät schützen und vieles mehr.