Problem mit Microsoft Secure Boot Zertifikaten
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 Codes0 = OK / aktuell / nicht betroffen1 = Aktualisierung läuft oder Neustart erforderlich2 = Fehler / technische Prüfung erforderlich
Skript
$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