ScriptBib

Problem mit Microsoft Secure Boot Zertifikaten

Prüft und aktualisiert die Microsoft Secure-Boot-Zertifikate für Windows-Clients und Windows-Server. Erkennt, ob das System aktuell ist, eine Aktualisierung gestartet wurde oder ein Neustart erforderlich ist.
🆔 ID 0002 🏷 Version 1 📅 22.06.2026 15:55 👤 p.schulder@networks.de

Beschreibung

Das Skript prüft den Status der Microsoft Secure-Boot-CA-2023-Zertifikatsaktualisierung auf Windows-Systemen mit aktiviertem Secure Boot. Ist die Aktualisierung bereits abgeschlossen, wird eine OK-Meldung ausgegeben.

 

Wenn die Zertifikate noch nicht aktualisiert sind, setzt das Skript den von Microsoft vorgesehenen Aktualisierungstrigger und startet, sofern vorhanden, den Windows-Task zur Secure-Boot-Aktualisierung. Dadurch wird die Zertifikatsaktualisierung automatisch angestoßen.

 

Das Skript erkennt außerdem typische Zwischenzustände wie „Aktualisierung läuft“ oder „Neustart erforderlich“ und gibt diese kundenfreundlich aus. Technische Details wie Aktualisierungsstatus, Ereignis-ID oder Fehlercode werden ergänzend angezeigt, damit eine weitere Analyse möglich ist.

 

Das Skript muss mit Administratorrechten ausgeführt werden. Systeme ohne aktiviertes Secure Boot oder ohne relevante Secure-Boot-Umgebung werden als nicht betroffen gemeldet.

 

Exit Codes
0 = OK / aktuell / nicht betroffen
1 = Aktualisierung läuft oder Neustart erforderlich
2 = Fehler / technische Prüfung erforderlich

Skript

⬇ Skript herunterladen
$ErrorActionPreference = "Stop"

$ExitCode = 2
$Result   = "Fehler"
$Message  = "Die Secure Boot Zertifikate konnten nicht automatisch aktualisiert werden."
$Action   = "Eine technische Prüfung ist erforderlich."
$Details  = @()

$SecureBootKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot"
$ServicingKey  = "$SecureBootKey\Servicing"
$TaskPath      = "\Microsoft\Windows\PI\"
$TaskName      = "Secure-Boot-Update"

function Set-Result {
    param(
        [int]$Code,
        [string]$NewResult,
        [string]$NewMessage,
        [string]$NewAction
    )

    $script:ExitCode = $Code
    $script:Result   = $NewResult
    $script:Message  = $NewMessage
    $script:Action   = $NewAction
}

function Get-ServicingData {
    if (Test-Path $ServicingKey) {
        return Get-ItemProperty -Path $ServicingKey
    }
    return $null
}

function Test-SecureBootError {
    param($ErrorCode)

    if ($null -eq $ErrorCode) {
        return $false
    }

    try {
        return ([uint32]$ErrorCode -ne 0)
    }
    catch {
        return $true
    }
}

function Test-RebootRequired {
    param(
        [string]$Status,
        $ErrorCode,
        $ErrorReason,
        $ErrorEvent
    )

    if ($Status -ne "InProgress") {
        return $false
    }

    if ($ErrorReason -eq "RebootRequired") {
        return $true
    }

    if ($null -ne $ErrorCode) {
        try {
            if ([uint32]$ErrorCode -eq 2147942750) {
                return $true
            }
        }
        catch {}
    }

    if ($null -ne $ErrorEvent) {
        try {
            if ([uint32]$ErrorEvent -eq 1800) {
                return $true
            }
        }
        catch {}
    }

    return $false
}

function Add-Details {
    param($Status, $ErrorCode, $ErrorReason, $ErrorEvent)

    $script:Details = @()

    $script:Details += "Secure Boot: Aktiv"

    if ($Status) {
        $script:Details += "Aktualisierungsstatus: $Status"
    }

    if ($ErrorReason) {
        if ($ErrorReason -eq "RebootRequired") {
            $script:Details += "Erforderliche Maßnahme: Neustart des Systems erforderlich"
        }
        else {
            $script:Details += "Hinweis: $ErrorReason"
        }
    }

    if ($ErrorEvent) {
        $script:Details += "Ereignis-ID: $ErrorEvent"
    }

    if ($ErrorCode -and -not (Test-RebootRequired $Status $ErrorCode $ErrorReason $ErrorEvent)) {
        $script:Details += "Fehlercode: $ErrorCode"
    }
}

try {
    $Identity  = [Security.Principal.WindowsIdentity]::GetCurrent()
    $Principal = New-Object Security.Principal.WindowsPrincipal($Identity)
    $IsAdmin   = $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

    if (-not $IsAdmin) {
        Set-Result `
            2 `
            "Fehler" `
            "Die Secure Boot Zertifikate konnten nicht geprüft oder aktualisiert werden." `
            "Bitte führen Sie die Prüfung mit Administratorrechten aus."
    }
    else {
        try {
            $SecureBootEnabled = Confirm-SecureBootUEFI
        }
        catch {
            $SecureBootEnabled = $false
        }

        if (-not $SecureBootEnabled) {
            Set-Result `
                0 `
                "OK" `
                "Für dieses System ist keine Secure Boot Zertifikatsaktualisierung erforderlich." `
                "Es ist keine Aktion erforderlich."
        }
        else {
            $Data = Get-ServicingData

            $Status      = $Data.UEFICA2023Status
            $ErrorCode   = $Data.UEFICA2023Error
            $ErrorReason = $Data.BootMgrLastUpdateErrorReason
            $ErrorEvent  = $Data.UEFICA2023ErrorEvent

            if ($Status -eq "Updated") {
                Set-Result `
                    0 `
                    "OK" `
                    "Die Secure Boot Zertifikate sind aktuell." `
                    "Es ist keine Aktion erforderlich."
            }
            elseif (Test-RebootRequired $Status $ErrorCode $ErrorReason $ErrorEvent) {
                Set-Result `
                    1 `
                    "Neustart erforderlich" `
                    "Die Secure Boot Zertifikate werden aktualisiert." `
                    "Bitte starten Sie das System neu, damit die Aktualisierung abgeschlossen werden kann."

                Add-Details $Status $ErrorCode $ErrorReason $ErrorEvent
            }
            elseif (Test-SecureBootError $ErrorCode) {
                Set-Result `
                    2 `
                    "Fehler" `
                    "Die Secure Boot Zertifikate konnten nicht automatisch aktualisiert werden." `
                    "Eine technische Prüfung ist erforderlich."

                Add-Details $Status $ErrorCode $ErrorReason $ErrorEvent
            }
            else {
                New-ItemProperty `
                    -Path $SecureBootKey `
                    -Name "AvailableUpdates" `
                    -PropertyType DWord `
                    -Value 0x5944 `
                    -Force | Out-Null

                $Task = Get-ScheduledTask `
                    -TaskPath $TaskPath `
                    -TaskName $TaskName `
                    -ErrorAction SilentlyContinue

                if ($Task) {
                    if ($Task.State -eq "Disabled") {
                        Enable-ScheduledTask `
                            -TaskPath $TaskPath `
                            -TaskName $TaskName | Out-Null
                    }

                    Start-ScheduledTask `
                        -TaskPath $TaskPath `
                        -TaskName $TaskName | Out-Null
                }

                Start-Sleep -Seconds 15

                $Data = Get-ServicingData

                $Status      = $Data.UEFICA2023Status
                $ErrorCode   = $Data.UEFICA2023Error
                $ErrorReason = $Data.BootMgrLastUpdateErrorReason
                $ErrorEvent  = $Data.UEFICA2023ErrorEvent

                if ($Status -eq "Updated") {
                    Set-Result `
                        0 `
                        "OK" `
                        "Die Secure Boot Zertifikate sind aktuell." `
                        "Es ist keine Aktion erforderlich."
                }
                elseif (Test-RebootRequired $Status $ErrorCode $ErrorReason $ErrorEvent) {
                    Set-Result `
                        1 `
                        "Neustart erforderlich" `
                        "Die Secure Boot Zertifikate werden aktualisiert." `
                        "Bitte starten Sie das System neu, damit die Aktualisierung abgeschlossen werden kann."

                    Add-Details $Status $ErrorCode $ErrorReason $ErrorEvent
                }
                elseif (Test-SecureBootError $ErrorCode) {
                    Set-Result `
                        2 `
                        "Fehler" `
                        "Die Secure Boot Zertifikate konnten nicht automatisch aktualisiert werden." `
                        "Eine technische Prüfung ist erforderlich."

                    Add-Details $Status $ErrorCode $ErrorReason $ErrorEvent
                }
                else {
                    Set-Result `
                        1 `
                        "Aktualisierung läuft" `
                        "Die Secure Boot Zertifikate werden aktualisiert." `
                        "Die Aktualisierung wurde gestartet. Ein Neustart kann später erforderlich sein."

                    Add-Details $Status $ErrorCode $ErrorReason $ErrorEvent
                }
            }
        }
    }
}
catch {
    Set-Result `
        2 `
        "Fehler" `
        "Die Secure Boot Zertifikate konnten nicht automatisch aktualisiert werden." `
        "Eine technische Prüfung ist erforderlich."

    $Details = @("Technische Meldung: $($_.Exception.Message)")
}

Write-Output "----------------------------------------"
Write-Output "Secure Boot Zertifikatsprüfung"
Write-Output "----------------------------------------"
Write-Output ""
Write-Output "Ergebnis : $Result"
Write-Output ""
Write-Output "Meldung  : $Message"
Write-Output ""
Write-Output "Aktion   : $Action"

if ($Details.Count -gt 0) {
    Write-Output ""
    Write-Output "Details:"
    foreach ($Detail in $Details) {
        Write-Output " - $Detail"
    }
}

Write-Output ""
Write-Output "----------------------------------------"

exit $ExitCode