Emergency server help: get in touch

Secure Boot 2023 Certificate Check: PowerShell Script for Many PCs

Free read-only PowerShell script that checks Secure Boot, the 2023 Microsoft certificates in DB and KEK, UEFICA2023Status and events 1801/1808 on many Windows computers.

Version
1.0.0
Last updated
October 6, 2026
Language
PowerShell
Tested on
Run on 6 Oct 2026 on a Windows Server 2025 DC (build 26100.33438, Windows PowerShell 5.1) in our lab domain with a Windows 11 Pro member; syntax-checked with PowerShell 7.4.6 and PSScriptAnalyzer 1.25.
License
MIT
Pricing
Free

Short answer: run .\Get-SecureBootCertStatus.ps1 -ComputerName (Get-Content .\servers.txt) -CsvPath .\secureboot.csv from an elevated PowerShell. For each computer it checks that Secure Boot is on (Confirm-SecureBootUEFI), whether the 2023 Microsoft certificates are in DB and KEK (Get-SecureBootUEFI), and reads the servicing values Windows keeps for the update, mainly UEFICA2023Status (NotStarted, InProgress or Updated) under HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing. It changes nothing.

We ran this script on 6 October 2026 on a Windows Server 2025 Standard domain controller (build 26100.33438, September 2026 update, Windows PowerShell 5.1) and a Windows 11 Pro member PC in our lab domain contoso.com. The example output below is from that run; the lab domain is small and new, so your numbers will be bigger. It was also syntax-checked with PowerShell 7.4.6 and PSScriptAnalyzer 1.25.

What it does

Microsoft’s 2011 Secure Boot certificates expire during 2026 and are being replaced by 2023 certificates: Windows UEFI CA 2023, Microsoft UEFI CA 2023 and Microsoft Option ROM UEFI CA 2023 in the DB, and Microsoft Corporation KEK 2K CA 2023 in the KEK. Windows tracks its progress in the registry and in the System event log. Checking that by hand on one PC is easy; on 200 servers it is not. The script collects, per computer:

CheckSource
Secure Boot on?Confirm-SecureBootUEFI, falling back to ...\SecureBoot\State\UEFISecureBootEnabled
2023 certificates in DBGet-SecureBootUEFI db, bytes decoded as ASCII and searched for the certificate names
2023 KEK presentGet-SecureBootUEFI KEK, searched for “Microsoft Corporation KEK 2K CA 2023”
Update statusUEFICA2023Status, UEFICA2023Error, UEFICA2023ErrorEvent under ...\SecureBoot\Servicing
Rollout settingsAvailableUpdates (as hex), HighConfidenceOptOut, MicrosoftUpdateManagedOptIn under ...\SecureBoot; ConfidenceLevel under ...\Servicing
Latest eventNewest System log event 1801 (new certificates not yet applied) or 1808 (device has the new certificates), plus its BucketConfidenceLevel text
HardwareOEM manufacturer, model, firmware version and date from ...\Servicing\DeviceAttributes

The DB check is the method Microsoft uses in its boot manager guidance: [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI db).bytes) -match 'Windows UEFI CA 2023'. The Assessment column sums it up: Updated when UEFICA2023Status is Updated, Secure Boot off, Unreachable, or Action needed with what is missing (for example “KEK: KEK 2K CA 2023; Status: InProgress”).

Requirements

  • Windows PowerShell 5.1 or PowerShell 7, run as Administrator: Get-SecureBootUEFI needs elevation, and without it the DB/KEK columns stay empty.
  • UEFI firmware. On legacy BIOS systems Confirm-SecureBootUEFI fails and the row shows Secure Boot as unknown or off.
  • Windows updates from 11 November 2025 or later on each computer: Microsoft added the Servicing registry values in those updates. Older systems still get the DB/KEK and event checks.
  • For -ComputerName: PowerShell remoting (WinRM) enabled on the targets, and an account that is a local administrator there. Domain controllers and servers have remoting on by default since Windows Server 2012; client PCs usually need it enabled by Group Policy.

Download and first run

  1. Copy the script from the box on this page (or use the download button) and save it as C:\Scripts\Get-SecureBootCertStatus.ps1.
  2. If you downloaded the file, clear the “downloaded from the internet” mark so the execution policy lets it run: Unblock-File C:\Scripts\Get-SecureBootCertStatus.ps1.
  3. Read the built-in help, then run it once interactively and look at the result on screen before you export or schedule anything.
cd C:\Scripts
Get-Help .\Get-SecureBootCertStatus.ps1 -Full
# This computer
.\Get-SecureBootCertStatus.ps1

# A list of servers
.\Get-SecureBootCertStatus.ps1 -ComputerName (Get-Content C:\Scripts\servers.txt) -CsvPath C:\Reports\secureboot.csv

Options

ParameterWhat it doesDefault
-ComputerNameComputers to check through Invoke-CommandThis computer
-CredentialCredential for the remote computersCurrent user
-ThrottleLimitParallel remote connections (1 to 256)32
-CsvPathWrite the result to CSVScreen only
-PassThruSend the objects down the pipelineOff

Usage examples

# All servers in AD
.\Get-SecureBootCertStatus.ps1 -ComputerName (Get-ADComputer -Filter 'OperatingSystem -like "*Server*"').DNSHostName -CsvPath C:\Reports\secureboot.csv

# Only the ones that still need work
.\Get-SecureBootCertStatus.ps1 -ComputerName HV01,HV02,FS01 -PassThru | Where-Object Assessment -ne 'Updated'

# Count by status per hardware model
.\Get-SecureBootCertStatus.ps1 -ComputerName (Get-Content .\pcs.txt) -PassThru |
    Group-Object Model, UEFICA2023Status | Select-Object Count, Name

The Get-ADComputer example needs the ActiveDirectory module; see Install RSAT on Windows 11.

CSV columns

The example output further down is from our lab run. Columns:

ColumnMeaning
ComputerName, OSComputer name and OS caption
SecureBootEnabledTrue, False, or empty if it could not be read
AssessmentUpdated, Secure Boot off, Unreachable, or Action needed: …
DB_WindowsUEFICA2023, DB_MicrosoftUEFICA2023, DB_OptionROMUEFICA2023True if the certificate name is found in DB
KEK_2023True if Microsoft Corporation KEK 2K CA 2023 is in KEK
UEFICA2023Status, UEFICA2023Error, UEFICA2023ErrorEventServicing status; error code (0 on success) and the event ID Windows used to report an error
WindowsUEFICA2023CapableReference value (0, 1, 2); Microsoft says not to use it for status
AvailableUpdatesPending update bits, as hex (for example 0x5944 when all updates were requested)
HighConfidenceOptOut, MicrosoftUpdateManagedOptIn, ConfidenceLevelRollout opt-out/opt-in and the device’s bucket confidence
LastEventId, LastEventTime, EventBucketConfidenceNewest 1801 or 1808 event and its BucketConfidenceLevel line
Manufacturer, Model, FirmwareVersion, FirmwareReleaseDateFrom Servicing\DeviceAttributes
NotesWhy something could not be read (not elevated, no Servicing values, event log error)

Example output

Our lab DC is a KVM virtual machine with Secure Boot turned off, which is a common case on hosted VPS servers. The CSV row, as a list:

ComputerName       : WINSRV
OS                 : Microsoft Windows Server 2025 Standard
SecureBootEnabled  : False
Assessment         : Secure Boot off
UEFICA2023Status   : InProgress
UEFICA2023Error    : 2147946825
UEFICA2023ErrorEvent : 1796
AvailableUpdates   : 0x5944
ConfidenceLevel    : High Confidence
LastEventId        : 1801
Manufacturer       : QEMU
Model              : Standard PC (i440FX + PIIX, 1996)

Windows Update had already queued the certificate update (AvailableUpdates 0x5944), but every step failed with event 1796, “Secure Boot is not enabled on this machine”. On a machine like this the expiring certificates do not matter until you turn Secure Boot on; if you do, apply the update first.

Schedule it

Run it weekly during the rollout so you can watch devices move from NotStarted to Updated. The account needs local admin rights on every target, so use a dedicated account or a gMSA (see our gMSA guide).

$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
    -Argument '-NoProfile -ExecutionPolicy Bypass -Command "& C:\Scripts\Get-SecureBootCertStatus.ps1 -ComputerName (Get-Content C:\Scripts\servers.txt) -CsvPath C:\Reports\secureboot.csv"'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 7am
$principal = New-ScheduledTaskPrincipal -UserId 'CONTOSO\gmsa-sbcheck$' -LogonType Password -RunLevel Highest
Register-ScheduledTask -TaskName 'Secure Boot certificate check' -Action $action -Trigger $trigger -Principal $principal

This script only reports. To start the update on a device, Microsoft documents several routes for IT-managed devices: setting AvailableUpdates to 0x5944 and letting the Windows scheduled Secure Boot update task and normal restarts do the work, Group Policy, Intune, or the Windows Configuration System (WinCS). Test on a few devices per hardware model first and have BitLocker recovery keys at hand.

How it works

  1. A self-contained script block (no outside functions) runs locally, or on each computer through Invoke-Command -ComputerName ... -ThrottleLimit.
  2. It calls Confirm-SecureBootUEFI; if that fails, it reads UEFISecureBootEnabled under ...\SecureBoot\State.
  3. If Secure Boot is on, it reads the db and KEK variables with Get-SecureBootUEFI, decodes the bytes as ASCII and matches the certificate names.
  4. It reads the registry values with Get-ItemProperty; missing values become empty columns rather than errors.
  5. It reads the newest System event with ID 1801 or 1808 (Get-WinEvent -FilterHashtable @{LogName='System'; Id=1801,1808} -MaxEvents 1), the same event IDs Microsoft’s sample inventory script collects.
  6. Computers that do not answer get a row with Assessment “Unreachable” and the remoting error, so the CSV always has one row per name you passed.

Limitations

  • Name matching on the decoded bytes tells you a certificate with that name is present; it does not validate the certificate chain. It is the same check Microsoft shows.
  • Virtual machines have virtual firmware. Hyper-V Generation 2, VMware EFI and cloud VMs report their own DB/KEK; Generation 1 / BIOS VMs show Secure Boot off.
  • Updated is the goal, but a device can have the new DB certificates and still be InProgress until the boot manager is replaced after a restart.
  • Remoting must already work; the script does not enable WinRM.
  • Not yet run against live devices (see the note at the top).

Official documentation: Registry key updates for Secure Boot (IT-managed) · Secure Boot certificate updates: guidance for IT · Get-SecureBootUEFI · Sample Secure Boot inventory script

Related: Invalid Signature Detected Secure Boot Policy: Fix · Windows 11 Patch Tuesday September 2026 (KB5124008) and the KB5129195 out-of-band fix: what changed · Group Managed Service Accounts (gMSA): Complete Windows Server 2025 Guide · Install RSAT on Windows 11: 5 Methods, Including Offline · A basic RMM monitoring policy for small-business endpoints: disk, patching and antivirus

See also: Secure Boot Certificate Expiry 2026: Check and Update to 2023 CAs

The script

Get-SecureBootCertStatus.ps1Download
# Secure Boot 2023 Certificate Check: PowerShell Script for Many PCs (v1.0.0) - from srvScripts.com
# Source, docs and updates: https://srvscripts.com/scripts/secure-boot-cert-check/
# Copyright (c) 2026 srvScripts.com. MIT licence: if you copy, share or adapt this script, keep this notice and credit srvScripts.com.
<#
.SYNOPSIS
    Secure Boot 2023 certificate status for one or many Windows computers: Secure Boot state, whether the
    2023 Microsoft certificates are in DB and KEK, the servicing registry values Windows keeps for the
    certificate update, and the latest 1801/1808 event. Read-only. CSV output.

.DESCRIPTION
    Microsoft's 2011 Secure Boot certificates expire during 2026 and are being replaced by 2023
    certificates. For each computer this script collects:

      Secure Boot   Confirm-SecureBootUEFI (falls back to HKLM\...\SecureBoot\State\UEFISecureBootEnabled).
      DB / KEK      Get-SecureBootUEFI db / kek, decoded as ASCII and searched for the certificate names, the
                    method Microsoft uses in its boot manager guidance:
                      DB:  Windows UEFI CA 2023, Microsoft UEFI CA 2023, Microsoft Option ROM UEFI CA 2023
                      KEK: Microsoft Corporation KEK 2K CA 2023
      Registry      HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot:
                      AvailableUpdates, HighConfidenceOptOut, MicrosoftUpdateManagedOptIn
                    HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing:
                      UEFICA2023Status (NotStarted / InProgress / Updated), UEFICA2023Error,
                      UEFICA2023ErrorEvent, WindowsUEFICA2023Capable (reference only), ConfidenceLevel
                    ...\Servicing\DeviceAttributes: OEM manufacturer, model, firmware version and date.
                    These values exist on systems with Windows updates from 11 November 2025 or later.
      Events        Newest System log event 1801 (certificates not yet applied) or 1808 (device has the new
                    certificates), with the BucketConfidenceLevel text if the event carries it.

    The Assessment column is a summary: "Updated" when UEFICA2023Status is Updated, "Secure Boot off" when
    Secure Boot is disabled or not supported, otherwise "Action needed" (with what is missing).

    The script changes nothing. To start the update itself, follow Microsoft's guidance for IT-managed
    devices (AvailableUpdates = 0x5944 processed by Windows' scheduled Secure Boot update task, Group Policy,
    Intune or WinCS).

    Requirements: run elevated (Get-SecureBootUEFI needs administrator rights). For -ComputerName, PowerShell
    remoting (WinRM) must be enabled on the targets and your account must be an administrator there.

.PARAMETER ComputerName   Computers to check through Invoke-Command. Default: this computer only.
.PARAMETER Credential     Credential for the remote computers.
.PARAMETER ThrottleLimit  Maximum parallel remote connections (default 32).
.PARAMETER CsvPath        Write the result to this CSV file.
.PARAMETER PassThru       Output the objects to the pipeline.

.EXAMPLE  .\Get-SecureBootCertStatus.ps1
.EXAMPLE  .\Get-SecureBootCertStatus.ps1 -ComputerName (Get-Content .\servers.txt) -CsvPath .\secureboot.csv
.EXAMPLE  .\Get-SecureBootCertStatus.ps1 -ComputerName (Get-ADComputer -Filter 'OperatingSystem -like "*Server*"').DNSHostName -CsvPath C:\Reports\secureboot.csv
.EXAMPLE  .\Get-SecureBootCertStatus.ps1 -ComputerName HV01,HV02 -PassThru | Where-Object Assessment -ne 'Updated'

.NOTES
    Name:     Get-SecureBootCertStatus.ps1
    Purpose:  Read-only audit of the Secure Boot 2023 certificate update
    Source:   https://srvscripts.com/scripts/secure-boot-cert-check/
    License:  MIT
    Version:  1.0.0
    Requires: Windows PowerShell 5.1 or PowerShell 7 on Windows, Administrator; WinRM for remote computers.
#>
[CmdletBinding()]
param(
    [ValidateNotNullOrEmpty()]
    [string[]]$ComputerName,
    [System.Management.Automation.PSCredential]
    [System.Management.Automation.Credential()]
    $Credential = [System.Management.Automation.PSCredential]::Empty,
    [ValidateRange(1, 256)]
    [int]$ThrottleLimit = 32,
    [string]$CsvPath,
    [switch]$PassThru
)

Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'

function Write-Status([string]$Message) { Write-Information $Message -InformationAction Continue }

# Runs on each computer. Self-contained: no functions or variables from the outer script are used.
$probe = {
    $ErrorActionPreference = 'Stop'
    $sbKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot'
    $notes = [System.Collections.Generic.List[string]]::new()

    function Get-RegValue([string]$Path, [string]$Name) {
        try {
            $item = Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction Stop
            return $item.$Name
        } catch { return $null }
    }

    function Test-UefiVar([string]$Name, [string]$Pattern) {
        try {
            $var = Get-SecureBootUEFI -Name $Name -ErrorAction Stop
            return ([System.Text.Encoding]::ASCII.GetString($var.Bytes) -match [regex]::Escape($Pattern))
        } catch { return $null }
    }

    $secureBoot = $null
    try { $secureBoot = [bool](Confirm-SecureBootUEFI -ErrorAction Stop) }
    catch {
        $v = Get-RegValue "$sbKey\State" 'UEFISecureBootEnabled'
        if ($null -ne $v) { $secureBoot = ([int]$v -eq 1) }
        $notes.Add('Confirm-SecureBootUEFI failed (legacy BIOS, not elevated, or not supported)')
    }

    $dbWin = $null; $dbUefi = $null; $dbOprom = $null; $kek = $null
    if ($secureBoot) {
        $dbWin = Test-UefiVar 'db' 'Windows UEFI CA 2023'
        $dbUefi = Test-UefiVar 'db' 'Microsoft UEFI CA 2023'
        $dbOprom = Test-UefiVar 'db' 'Microsoft Option ROM UEFI CA 2023'
        $kek = Test-UefiVar 'KEK' 'Microsoft Corporation KEK 2K CA 2023'
        if ($null -eq $dbWin) { $notes.Add('Get-SecureBootUEFI could not read db/KEK (run elevated)') }
    }

    $avail = Get-RegValue $sbKey 'AvailableUpdates'
    $status = Get-RegValue "$sbKey\Servicing" 'UEFICA2023Status'
    $err = Get-RegValue "$sbKey\Servicing" 'UEFICA2023Error'
    $errEvent = Get-RegValue "$sbKey\Servicing" 'UEFICA2023ErrorEvent'
    $capable = Get-RegValue "$sbKey\Servicing" 'WindowsUEFICA2023Capable'
    $confidence = Get-RegValue "$sbKey\Servicing" 'ConfidenceLevel'
    $attr = "$sbKey\Servicing\DeviceAttributes"
    if ($null -eq $status) { $notes.Add('No UEFICA2023Status value (needs Windows updates from 11 Nov 2025 or later)') }

    $lastEventId = $null; $lastEventTime = $null; $bucketConfidence = $null
    try {
        $ev = Get-WinEvent -FilterHashtable @{ LogName = 'System'; Id = 1801, 1808 } -MaxEvents 1 -ErrorAction Stop
        if ($ev) {
            $lastEventId = $ev.Id; $lastEventTime = $ev.TimeCreated
            if ($ev.Message -match 'BucketConfidenceLevel:\s*(.+)') { $bucketConfidence = $Matches[1].Trim() }
        }
    } catch {
        if ($_.FullyQualifiedErrorId -notlike 'NoMatchingEventsFound*') { $notes.Add("Event log: $($_.Exception.Message)") }
    }

    $os = $null
    try { $os = (Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop).Caption } catch { $os = $null }

    $missing = @()
    if ($dbWin -eq $false) { $missing += 'DB: Windows UEFI CA 2023' }
    if ($kek -eq $false) { $missing += 'KEK: KEK 2K CA 2023' }
    if ($status -and $status -ne 'Updated') { $missing += "Status: $status" }
    $assessment = if ($secureBoot -eq $false) { 'Secure Boot off' }
    elseif ($null -eq $secureBoot) { 'Unknown (Secure Boot state not readable)' }
    elseif ($status -eq 'Updated') { 'Updated' }
    elseif ($missing.Count) { 'Action needed: ' + ($missing -join '; ') }
    else { 'Action needed: status unknown' }

    [pscustomobject]@{
        ComputerName              = $env:COMPUTERNAME
        OS                        = $os
        SecureBootEnabled         = $secureBoot
        Assessment                = $assessment
        DB_WindowsUEFICA2023      = $dbWin
        DB_MicrosoftUEFICA2023    = $dbUefi
        DB_OptionROMUEFICA2023    = $dbOprom
        KEK_2023                  = $kek
        UEFICA2023Status          = $status
        UEFICA2023Error           = $err
        UEFICA2023ErrorEvent      = $errEvent
        WindowsUEFICA2023Capable  = $capable
        AvailableUpdates          = $(if ($null -ne $avail) { '0x{0:X}' -f [int64]$avail } else { $null })
        HighConfidenceOptOut      = Get-RegValue $sbKey 'HighConfidenceOptOut'
        MicrosoftUpdateManagedOptIn = Get-RegValue $sbKey 'MicrosoftUpdateManagedOptIn'
        ConfidenceLevel           = $confidence
        LastEventId               = $lastEventId
        LastEventTime             = $lastEventTime
        EventBucketConfidence     = $bucketConfidence
        Manufacturer              = Get-RegValue $attr 'OEMManufacturerName'
        Model                     = Get-RegValue $attr 'OEMModelNumber'
        FirmwareVersion           = Get-RegValue $attr 'FirmwareVersion'
        FirmwareReleaseDate       = Get-RegValue $attr 'FirmwareReleaseDate'
        Notes                     = ($notes -join '; ')
    }
}

if ([System.Environment]::OSVersion.Platform -ne [System.PlatformID]::Win32NT -and -not $ComputerName) {
    throw 'Run this script on Windows, or use -ComputerName to query Windows computers remotely.'
}

$rows = [System.Collections.Generic.List[object]]::new()
if (-not $ComputerName) {
    $principal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Write-Warning 'Not elevated: Get-SecureBootUEFI and Confirm-SecureBootUEFI need administrator rights, so DB/KEK columns will be empty.'
    }
    $rows.Add((& $probe))
} else {
    $targets = @($ComputerName | ForEach-Object { $_.Trim() } | Where-Object { $_ } | Sort-Object -Unique)
    Write-Status ("Querying {0} computer(s)..." -f $targets.Count)
    $ic = @{ ComputerName = $targets; ScriptBlock = $probe; ThrottleLimit = $ThrottleLimit; ErrorAction = 'SilentlyContinue'; ErrorVariable = 'remoteErrors' }
    if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) { $ic.Credential = $Credential }
    $remoteErrors = $null
    $results = @(Invoke-Command @ic)
    foreach ($r in $results) {
        $rows.Add(($r | Select-Object -Property * -ExcludeProperty PSComputerName, RunspaceId, PSShowComputerName))
    }
    $answered = @($results | ForEach-Object { [string]$_.PSComputerName })
    foreach ($t in $targets) {
        if ($answered -notcontains $t) {
            $msg = @($remoteErrors | Where-Object { $_.TargetObject -eq $t -or "$($_.Exception.Message)" -like "*$t*" } | Select-Object -First 1)
            $rows.Add([pscustomobject]@{
                ComputerName = $t; OS = $null; SecureBootEnabled = $null
                Assessment = 'Unreachable'
                Notes = $(if ($msg) { $msg[0].Exception.Message } else { 'No result (WinRM, DNS or permissions)' })
            })
        }
    }
}

$out = @($rows | Sort-Object Assessment, ComputerName)
if ($CsvPath) {
    # Select explicit columns so rows for unreachable computers line up with the others.
    $cols = 'ComputerName', 'OS', 'SecureBootEnabled', 'Assessment', 'DB_WindowsUEFICA2023', 'DB_MicrosoftUEFICA2023', 'DB_OptionROMUEFICA2023',
    'KEK_2023', 'UEFICA2023Status', 'UEFICA2023Error', 'UEFICA2023ErrorEvent', 'WindowsUEFICA2023Capable', 'AvailableUpdates',
    'HighConfidenceOptOut', 'MicrosoftUpdateManagedOptIn', 'ConfidenceLevel', 'LastEventId', 'LastEventTime', 'EventBucketConfidence',
    'Manufacturer', 'Model', 'FirmwareVersion', 'FirmwareReleaseDate', 'Notes'
    $out | Select-Object -Property $cols | Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8
    Write-Status ("CSV written: {0} ({1} rows)" -f $CsvPath, $out.Count)
}
$summary = $out | Group-Object { ($_.Assessment -split ':')[0] } | ForEach-Object { "{0} {1}" -f $_.Count, $_.Name }
Write-Status ("Computers: {0}. {1}" -f $out.Count, ($summary -join ', '))

if ($PassThru) { return $out }
if (-not $CsvPath) {
    $out | Select-Object ComputerName, SecureBootEnabled, Assessment, UEFICA2023Status, LastEventId | Format-Table -AutoSize -Wrap
}
Version 1.0.0 · SHA-256 546b4f4fe5620c1e2217d52ba7329d0f47b0b11551d5bf29f7460e1969a254d8
Download and verify on Linux or macOS
curl -fsSL -o Get-SecureBootCertStatus.ps1 https://scr.srvscripts.com/secure-boot-cert-check/Get-SecureBootCertStatus.ps1 && curl -fsSL https://scr.srvscripts.com/secure-boot-cert-check/Get-SecureBootCertStatus.ps1.sha256 | sha256sum -c
Download and verify in Windows PowerShell
Invoke-WebRequest -Uri 'https://scr.srvscripts.com/secure-boot-cert-check/Get-SecureBootCertStatus.ps1' -OutFile 'Get-SecureBootCertStatus.ps1'; if ((Get-FileHash 'Get-SecureBootCertStatus.ps1' -Algorithm SHA256).Hash -eq '546B4F4FE5620C1E2217D52BA7329D0F47B0B11551D5BF29F7460E1969A254D8') { 'OK: the file is intact' } else { 'MISMATCH: do not run this file' }
Copy the whole line. In Windows PowerShell, curl and sha256sum are not the Linux tools, so use the PowerShell line there.
Also on GitHub: github.com/srvscripts/scripts

Frequently asked questions

How do I check if the Secure Boot 2023 certificates are installed?

In an elevated PowerShell run [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI db).bytes) -match ‘Windows UEFI CA 2023’. True means the certificate is in DB. This script runs that check and the KEK check on many computers.

What does UEFICA2023Status mean?

It is the Secure Boot certificate update state Windows keeps under HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing: NotStarted, InProgress or Updated.

What are events 1801 and 1808?

Event 1801 in the System log means the updated certificates have not been applied yet; 1808 means the device has the new Secure Boot certificates.

Why is UEFICA2023Status missing?

Microsoft added these registry values in Windows updates released on 11 November 2025 or later. Install current updates; until then rely on the DB/KEK and event columns.

Does the script install the new certificates?

No. It only reads. Use Microsoft’s documented routes (AvailableUpdates 0x5944, Group Policy, Intune or WinCS) to start the update.

Why are the DB and KEK columns empty?

Get-SecureBootUEFI needs an elevated session, and it only works on UEFI systems with Secure Boot. Run PowerShell as Administrator.

Changelog

  • 1.0.0 — First release.

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.