Ngày phát hành ban đầu: Ngày 17 tháng 11 năm 2025
ID KB: 5072718
QUAN TRỌNG Bài viết này có chứa các kịch bản mẫu đã bị gỡ bỏ. Bắt đầu với các bản cập nhật Windows được phát hành vào và sau ngày 12 tháng 5 năm 2026, tập lệnh mẫu nằm trong thư mục %systemroot%\SecureBoot\ExampleRolloutScripts trên thiết bị của bạn.
Tập lệnh Thu thập Dữ liệu Kiểm kê Khởi động An toàn Mẫu
Sao chép và dán tập lệnh mẫu này và sửa đổi khi cần thiết cho môi trường của bạn: Tập lệnh Thu thập dữ liệu kiểm kê khởi động an toàn mẫu.
<# . TÓM TẮT Phát hiện trạng thái cập nhật chứng chỉ Khởi động An toàn để giám sát trên toàn đội tàu.
. MÔ TẢ Tập lệnh phát hiện này thu thập trạng thái Khởi động An toàn, giá trị đăng ký cập nhật chứng chỉ, và thông tin thiết bị. Nó xuất ra một chuỗi JSON để theo dõi và báo cáo.
Tương thích với Intune, bộ sưu tập dựa trên GPO và các công cụ quản lý khác.Không có kịch bản khắc phục là cần thiết - đây là chỉ giám sát.
Exit 0 = "Without issue" (chứng chỉ được cập nhật) Exit 1 = "Có sự cố" (chứng chỉ không được cập nhật — chỉ thông tin)
. PARAMETER OutputPath Tùy chọn. Đường dẫn đến thư mục lưu tệp JSON.Nếu được cung cấp, hãy HOSTNAME_latest.json vào thư mục này.Nếu không được cung cấp, đầu ra JSON để stdout (hành vi ban đầu).
. VÍ DỤ # Đầu ra cho stdout (phát Intune/SCCM hiện) .\Detect-SecureBootCertUpdateStatus.ps1
. VÍ DỤ # Lưu vào chia sẻ mạng (Triển khai GPO) .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"
. GHI CHÚ Đường dẫn đăng ký trên https://aka.ms/securebootplaybook: HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR NGỤ Ý, BAO GỒM NHƯNG KHÔNG GIỚI HẠN Ở CÁC BẢO HÀNH VỀ KHẢ NĂNG BÁN ĐƯỢC, SỰ HỢP LÝ CHO MỘT MỤC ĐÍCH CỤ THỂ VÀ KHÔNG VI PHẠM. TRONG BẤT KỲ TRƯỜNG HỢP NÀO, TÁC GIẢ HOẶC CHỦ SỞ HỮU BẢN QUYỀN PHẢI CHỊU TRÁCH NHIỆM VỀ MỌI KHIẾU NẠI, THIỆT HẠI HOẶC CÁC TRÁCH NHIỆM PHÁP LÝ, CHO DÙ LÀ TRONG MỘT HÀNH ĐỘNG HỢP ĐỒNG, TRA TẤN HAY CÁCH KHÁC, PHÁT SINH TỪ, HOẶC LIÊN QUAN ĐẾN PHẦN MỀM HOẶC VIỆC SỬ DỤNG HAY CÁC GIAO DỊCH KHÁC TRONG PHẦN MỀM.#> param( [Parameter(Mandatory = $false)] [chuỗi]$OutputPath )
# Tải xuống URL: https://aka.ms/getsecureboot -> "Triển khai và Giám sát Mẫu" # Lưu ý: Tập lệnh này chạy trên các điểm cuối để thu thập dữ liệu trạng thái Khởi động An toàn.
# 1. Hostname # PS Phiên bản: Tất cả | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $hostname = $env:COMPUTERNAME if ([string]::IsNullOrEmpty($hostname)) { Write-Warning "Không thể xác định tên máy chủ" $hostname = "Không xác định" } Write-Host "Hostname: $hostname" } bắt { Write-Warning "Lỗi khi truy xuất tên máy chủ: $_" $hostname = "Lỗi" Write-Host "Hostname: $hostname" }
# 2. CollectionTime # PS Phiên bản: Tất cả | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $collectionTime = Get-Date if ($null -eq $collectionTime) { Write-Warning "Không thể truy xuất ngày/giờ hiện tại" $collectionTime = "Không xác định" } Write-Host "Thời gian Thu thập: $collectionTime" } bắt { Write-Warning "Lỗi khi truy xuất ngày/giờ: $_" $collectionTime = "Lỗi" Write-Host "Thời gian thu thập: $collectionTime" }
# Registry: Khóa Chính Khởi động An toàn (3 giá trị)
# 3. SecureBootEnabled # PS Phiên bản: 3.0+ | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Hệ thống có khả năng khởi động UEFI/Secure hãy thử { $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop Write-Host "Đã bật Khởi động An toàn: $secureBootEnabled" } bắt { Write-Warning "Không thể xác định trạng thái Khởi động An toàn qua lệnh ghép ngắn: $_" # Thử bản dự phòng đăng ký hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled Write-Host "Đã bật Khởi động An toàn: $secureBootEnabled" } bắt { Write-Warning "Không thể xác định trạng thái Khởi động An toàn thông qua sổ đăng ký. Hệ thống có thể không hỗ trợ Khởi động UEFI/An toàn." $secureBootEnabled = $null Write-Host "Đã bật Khởi động An toàn: Không Khả dụng" } }
# 4. HighConfidenceOptOut # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop $highConfidenceOptOut = $regValue.HighConfidenceOptOut Write-Host "Lựa chọn không tham gia tin cậy cao: $highConfidenceOptOut" } bắt { # HighConfidenceOptOut là tùy chọn - không có mặt trên hầu hết các hệ thống $highConfidenceOptOut = $null Write-Host "Chọn không tham gia có độ tin cậy cao: Chưa đặt" }
# 4b. MicrosoftUpdateManagedOptIn # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn Write-Host "Lựa chọn tham gia được Quản lý microsoft Update: $microsoftUpdateManagedOptIn" } bắt { # MicrosoftUpdateManagedOptIn là tùy chọn - không có trên hầu hết các hệ thống $microsoftUpdateManagedOptIn = $null Write-Host "Lựa chọn được Quản lý của Microsoft Update: Không Đặt" }
# 5. AvailableUpdates # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop $availableUpdates = $regValue.AvailableUpdates if ($null -ne $availableUpdates) { # Chuyển đổi thành định dạng thập lục phân $availableUpdatesHex = "0x{0:X}" -f $availableUpdates Write-Host "Có sẵn Cập nhật: $availableUpdatesHex" } người khác { Write-Host "Sẵn có Cập nhật: Không Sẵn dùng" } } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký AvailableUpdates" $availableUpdates = $null Write-Host "Sẵn có Cập nhật: Không Sẵn dùng" }
# 5b. AvailableUpdatesPolicy (Giá trị liên tục được kiểm soát bởi GPO) # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy if ($null -ne $availableUpdatesPolicy) { # Chuyển đổi thành định dạng thập lục phân $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy Write-Host "Chính sách Cập nhật dụng: $availableUpdatesPolicyHex" } người khác { Write-Host "Chính sách Khả Cập nhật: Chưa Đặt" } } bắt { # AvailableUpdatesPolicy là tùy chọn - chỉ đặt khi GPO được áp dụng $availableUpdatesPolicy = $null Write-Host "Chính sách Cập nhật dụng: Chưa Đặt" }
# Registry: Khóa Dịch vụ (3 giá trị)
# 6. UEFICA2023Status # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop $uefica 2023Status = $regValue.UEFICA2023Status Write-Host "Trạng thái Windows UEFI CA 2023: $uefica 2023Status" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa sổ đăng ký Trạng thái Windows UEFI CA 2023" $uefica 2023Status = $null Write-Host "Trạng thái Windows UEFI CA 2023: Không Khả dụng" }
# 7. UEFICA2023Error # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop $uefica 2023Error = $regValue.UEFICA2023Error Write-Host "Lỗi UEFI CA 2023: $uefica 2023Error" } bắt { # UEFICA2023Error chỉ tồn tại nếu có lỗi - sự vắng mặt là tốt $uefica 2023Error = $null Write-Host "Lỗi UEFI CA 2023: Không có" }
# 8. UEFICA2023ErrorEvent # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent Write-Host "Sự kiện Lỗi UEFI CA 2023: $uefica 2023ErrorEvent" } bắt { $uefica 2023ErrorEvent = $null Write-Host "Sự kiện Lỗi UEFI CA 2023: Không Sẵn dùng" }
# Registry: Thuộc tính Thiết bị (7 giá trị: 9-15)
# 9. OEMManufacturerName # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $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 trống" $oemManufacturerName = "Không xác định" } Write-Host "Tên Nhà sản xuất OEM: $oemManufacturerName" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký OEMManufacturerName" $oemManufacturerName = $null Write-Host "Tên Nhà sản xuất OEM: Không Khả dụng" }
# 10. OEMModelSystemFamily # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $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 là trống" $oemModelSystemFamily = "Không xác định" } Write-Host "Dòng Hệ thống Mô hình OEM: $oemModelSystemFamily" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký OEMModelSystemFamily" $oemModelSystemFamily = $null Write-Host "Dòng Hệ thống Mô hình OEM: Không Khả dụng" }
# 11. OEMModelNumber # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelNumber -ErrorAction Stop $oemModelNumber = $regValue.OEMModelNumber if ([string]::IsNullOrEmpty($oemModelNumber)) { Write-Warning "OEMModelNumber là trống" $oemModelNumber = "Không xác định" } Write-Host "Số Kiểu OEM: $oemModelNumber" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký OEMModelNumber" $oemModelNumber = $null Write-Host "Số Kiểu OEM: Không Khả dụng" }
# 12. Phiên bản Vi chương trình # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareVersion -ErrorAction Stop $firmwareVersion = $regValue.FirmwareVersion if ([string]::IsNullOrEmpty($firmwareVersion)) { Write-Warning "FirmwareVersion bị trống" $firmwareVersion = "Không xác định" } Write-Host "Phiên bản Vi chương trình: $firmwareVersion" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký FirmwareVersion" $firmwareVersion = $null Write-Host "Phiên bản Vi chương trình: Không Khả dụng" }
# 13. FirmwareReleaseDate # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $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 bị trống" $firmwareReleaseDate = "Không xác định" } Write-Host "Ngày Phát hành Vi chương trình: $firmwareReleaseDate" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký FirmwareReleaseDate" $firmwareReleaseDate = $null Write-Host "Ngày Phát hành Vi chương trình: Không Khả dụng" }
# 14. OsArchitecture # PS Phiên bản: Tất cả | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $osArchitecture = $env:PROCESSOR_ARCHITECTURE if ([string]::IsNullOrEmpty($osArchitecture)) { # Thử bản dự phòng đăng ký $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 không thể xác định được" $osArchitecture = "Không xác định" } Write-Host "Kiến trúc HĐH: $osArchitecture" } bắt { Write-Warning "Lỗi truy xuất OSArchitecture: $_" $osArchitecture = "Không xác định" Write-Host "Kiến trúc HĐH: $osArchitecture" }
# 15. CanAttemptUpdateAfter (FILETIME) # PS Phiên bản: Tất cả | Quản trị: Có thể được yêu cầu | Yêu cầu Hệ thống: Không có hãy thử { $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) { hãy thử { if ($canAttemptUpdateAfter -is [byte[]]) { $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter, 0) $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime). ToUniversalTime() } elseif ($canAttemptUpdateAfter -is [long]) { $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter). ToUniversalTime() } } bắt { Write-Warning "Không thể chuyển đổi CanAttemptUpdateAfter FILETIME thành DateTime" } } Write-Host "Có thể Thử Cập nhật Sau: $canAttemptUpdateAfter" } bắt { Write-Warning "Không tìm thấy hoặc không thể truy nhập khóa đăng ký CanAttemptUpdateAfter" $canAttemptUpdateAfter = $null Write-Host "Có thể Thử Cập nhật Sau: Không Khả dụng" }
# Nhật ký Sự kiện: Nhật ký Hệ thống (10 giá trị: 16-25)
# 16-25. Truy vấn Nhật ký Sự kiện # ID sự kiện: # 1801 - Cập nhật được khởi tạo, yêu cầu khởi động lại # 1808 - Đã cập nhật thành công # 1795 - Phần mềm trả về lỗi (nắm bắt mã lỗi) # 1796 - Lỗi được ghi nhật ký với mã lỗi (mã chụp) # 1800 - Cần khởi động lại (KHÔNG phải lỗi - bản cập nhật sẽ tiếp tục sau khi khởi động lại) # 1802 - Bản cập nhật bị chặn sự cố vi chương trình đã biết (KI_<số> từ SkipReason) # 1803 - Không tìm thấy bản cập nhật KEK phù hợp (OEM cần cung cấp KEK đã ký PK) # PS Phiên bản: 3.0+ | Quản trị: Có thể được yêu cầu đối với Nhật ký hệ thống | Yêu cầu Hệ thống: Không có hãy thử { # Truy vấn tất cả ID sự kiện Khởi động An toàn liên quan $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808) $events = @(Get-WinEvent -FilterHashtable @{LogName='System'; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)
nếu ($events. Đếm -eq 0) { Write-Warning "Không tìm thấy sự kiện Khởi động An toàn trong Nhật ký hệ thống" $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 "ID Sự kiện Mới nhất: Không Sẵn dùng" Write-Host "Bucket ID: Not Available" Write-Host "Tin cậy: Không Sẵn dùng" Write-Host "Số sự kiện 1801: 0" Write-Host "Số sự kiện 1808: 0" } người khác { # 16. LatestEventId $latestEvent = $events | Sort-Object tạo thời gian -Giảm dần | Select-Object -1 đầu tiên if ($null -eq $latestEvent) { Write-Warning "Không thể xác định sự kiện mới nhất" $latestEventId = $null Write-Host "ID Sự kiện Mới nhất: Không Sẵn dùng" } người khác { $latestEventId = $latestEvent.Id Write-Host "ID Sự kiện Mới nhất: $latestEventId" }
# 17. BucketID - Trích xuất từ sự kiện 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" } người khác { Write-Warning "BucketId không tìm thấy trong thông báo sự kiện" $bucketId = $null Write-Host "Bucket ID: Not Found in Event" } } người khác { Write-Warning "Sự kiện hoặc thư mới nhất là null, không thể trích xuất BucketId" $bucketId = $null Write-Host "Bucket ID: Not Available" }
# 18. Confidence - Trích xuất từ sự kiện 1801/1808 if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) { if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') { $confidence = $matches[1]. Trim() Write-Host "Confidence: $confidence" } người khác { Write-Warning "Không tìm thấy mức tin cậy trong thông báo sự kiện" $confidence = $null Write-Host "Confidence: Not Found in Event" } } người khác { Write-Warning "Sự kiện hoặc thư mới nhất là null, không thể trích xuất Tin cậy" $confidence = $null Write-Host "Tin cậy: Không Sẵn dùng" }
# 18b. SkipReason - Trích KI_<số> từ SkipReason trong cùng một sự kiện với BucketId # Thao tác này ghi lại các ID Sự cố Đã biết xuất hiện cùng với BucketId/Confidence (không chỉ sự kiện 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. Sự kiện1801Count $event 1801Array = @($events | Where-Object {$_. Id -eq 1801}) $event 1801Count = $event 1801Array.Count Write-Host "Số lượng Sự kiện 1801: $event 1801Count"
# 20. Sự kiện1808Count $event 1808Array = @($events | Where-Object {$_. Id -eq 1808}) $event 1808Count = $event 1808Array.Count Write-Host "Số lượng Sự kiện 1808: $event 1808Count" # Initialize error event variables $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 # Chỉ kiểm tra các sự kiện lỗi nếu chưa hoàn tất cập nhật # Bỏ qua phân tích lỗi nếu: 1808 là sự kiện mới nhất HOẶC UEFICA2023Status là "Cập nhật" $updateComplete = ($latestEventId -eq 1808) -or ($uefica 2023Status -eq "Đã cập nhật") if (-not $updateComplete) { Write-Host "Cập nhật chưa hoàn tất - kiểm tra sự kiện lỗi..." -ForegroundColor Yellow # 21. Sự kiện1795 - Lỗi Vi chương trình (ghi lại mã lỗi) $event 1795Array = @($events | Where-Object {$_. Id -eq 1795}) $event 1795Count = $event 1795Array.Count if ($event 1795Count -gt 0) { $latestEvent 1795 = $event 1795Array | Sort-Object Tạo Thời gian -Giảm dần | Select-Object -1 đầu tiên 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 "Sự kiện 1795 (Lỗi Vi chương trình) Count: $event 1795Count" $(if ($event 1795ErrorCode) { "Code: $event 1795ErrorCode" }) } # 22. Sự kiện1796 - Mã Lỗi được Ghi nhật ký (ghi lại mã lỗi) $event 1796Array = @($events | Where-Object {$_. Id -eq 1796}) $event 1796Count = $event 1796Array.Count nếu ($event 1796Count -gt 0) { $latestEvent 1796 = $event 1796Array | Sort-Object Tạo Thời gian -Giảm dần | Select-Object -1 đầu tiên 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. Sự kiện1800 - Cần khởi động lại (KHÔNG phải lỗi - bản cập nhật sẽ tiếp tục sau khi khởi động lại) $event 1800Array = @($events | Where-Object {$_. Id -eq 1800}) $event 1800Count = $event 1800Array.Count $rebootPending = $event 1800Count -gt 0 if ($rebootPending) { Write-Host "Sự kiện 1800 (Đang chờ khởi động lại): Bản cập nhật sẽ tiếp tục sau khi khởi động lại" -ForegroundColor Cyan } # 24. Sự kiện1802 - Sự cố Vi chương trình đã biết (KI_<số> từ SkipReason) $event 1802Array = @($events | Where-Object {$_. Id -eq 1802}) $event 1802Count = $event 1802Array.Count if ($event 1802Count -gt 0) { $latestEvent 1802 = $event 1802Array | Sort-Object Tạo Thời gian -Giảm dần | Select-Object -1 đầu tiên if ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)') { $knownIssueId = $matches[1] } Write-Host "Sự kiện 1802 (Sự cố Đã biết về Vi chương trình) Count: $event 1802Count" $(if ($knownIssueId) { "KI: $knownIssueId" }) } # 25. Event1803 - Thiếu Bản cập nhật KEK (OEM cần phải cung cấp KEK đã ký PK) $event 1803Array = @($events | Where-Object {$_. Id -eq 1803}) $event 1803Count = $event 1803Array.Count $missingKEK = $event 1803Count -gt 0 nếu ($missingKEK) { Write-Host "Sự kiện 1803 (Thiếu KEK): OEM cần phải cung cấp PK đã ký KEK" -ForegroundColor Yellow } } người khác { Write-Host "Cập nhật hoàn tất (Sự kiện 1808 hoặc Trạng thái=Đã cập nhật) - bỏ qua phân tích lỗi" -ForegroundColor Green } } } bắt { Write-Warning "Lỗi khi truy xuất nhật ký sự kiện. Có thể yêu cầu đặc quyền của người quản trị: $_" $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 "ID Sự kiện Mới nhất: Lỗi" Write-Host "Bucket ID: Error" Write-Host "Confidence: Error" Write-Host "Số sự kiện 1801: 0" Write-Host "Số sự kiện 1808: 0" }
# Truy vấn WMI/CIM (5 giá trị)
# 26. HĐHVersion # PS Phiên bản: 3.0+ (sử Get-WmiObject cho 2.0) | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -or [string]::IsNullOrEmpty($osInfo.Version)) { Write-Warning "Không thể truy xuất phiên bản HĐH" $osVersion = "Không xác định" } người khác { $osVersion = $osInfo.Phiên bản } Write-Host "Phiên bản HĐH: $osVersion" } bắt { # CIM có thể không hoạt động trong một số môi trường - sử dụng dự phòng $osVersion = [System.Environment]::OSVersion.Version.ToString() if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" } Write-Host "Phiên bản HĐH: $osVersion" }
# 27. LastBootTime # PS Phiên bản: 3.0+ (sử Get-WmiObject cho 2.0) | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -or $null -eq $osInfo.LastBootUpTime) { Write-Warning "Không thể truy xuất lần khởi động gần nhất" $lastBootTime = $null Write-Host "Thời gian Khởi động Lần cuối: Không Khả dụng" } người khác { $lastBootTime = $osInfo.LastBootUpTime Write-Host "Thời gian Khởi động Lần cuối: $lastBootTime" } } bắt { # CIM có thể không hoạt động trong một số môi trường - sử dụng dự phòng hãy thử { $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue). Thời gian Bắt đầu } bắt { $lastBootTime = $null } if ($lastBootTime) { Write-Host "Thời gian Khởi động Lần cuối: $lastBootTime" } khác { Write-Host "Thời gian Khởi động Cuối cùng: Không Khả dụng" } }
# 28. BaseBoardManufacturer # PS Phiên bản: 3.0+ (sử Get-WmiObject cho 2.0) | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) { Write-Warning "Không thể truy xuất nhà sản xuất baseboard" $baseBoardManufacturer = "Không xác định" } người khác { $baseBoardManufacturer = $baseBoard.Nhà sản xuất } Write-Host "Nhà sản xuất Bảng cơ sở: $baseBoardManufacturer" } bắt { # CIM có thể không thành công - thông tin bảng cơ sở là bổ sung $baseBoardManufacturer = "Không xác định" Write-Host "Nhà sản xuất Bảng cơ sở: $baseBoardManufacturer" }
# 29. BaseBoardProduct # PS Phiên bản: 3.0+ (sử Get-WmiObject cho 2.0) | Quản trị: Không | Yêu cầu Hệ thống: Không có hãy thử { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) { Write-Warning "Không thể truy xuất sản phẩm baseboard" $baseBoardProduct = "Không xác định" } người khác { $baseBoardProduct = $baseBoard.Product } Write-Host "Sản phẩm Bảng cơ sở: $baseBoardProduct" } bắt { # CIM có thể không thành công - thông tin bảng cơ sở là bổ sung $baseBoardProduct = "Không xác định" Write-Host "Sản phẩm Bảng cơ sở: $baseBoardProduct" }
# 30. SecureBootTaskEnabled # PS Phiên bản: Tất cả | Quản trị: Không | Yêu cầu Hệ thống: Tồn tại Tác vụ đã lên lịch # Kiểm tra xem tác vụ đã lên lịch Khởi động An toàn có được bật hay không $secureBootTaskEnabled = $null $secureBootTaskStatus = "Không xác định" hãy thử { $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.Trạng thái $secureBootTaskEnabled = ($taskData.Trạng thái -eq 'Sẵn sàng' -hoặc $taskData.Trạng thái -eq 'Đang chạy') } } người khác { $secureBootTaskStatus = "NotFound" $secureBootTaskEnabled = $false } if ($secureBootTaskEnabled -eq $false) { Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Enabled: $secureBootTaskEnabled)" -ForegroundColor Yellow } người khác { Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Enabled: $secureBootTaskEnabled)" -ForegroundColor Green } } bắt { $secureBootTaskStatus = "Lỗi" $secureBootTaskEnabled = $false Write-Host "Tác vụ Cập nhật SecureBoot: Kiểm tra lỗi - $_" -ForegroundColor Red }
# 31. Trạng thái Khóa WinCS (Bản F33E0C8E002 - Cập nhật Chứng chỉ Khởi động An toàn) # PS Phiên bản: Tất cả | Quản trị: Có (đối với truy vấn) | Yêu cầu Hệ thống: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Không xác định" hãy thử { # Kiểm tra các vị trí phổ biến để tìm 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) { # Khóa cụ thể của truy vấn - yêu cầu quyền quản trị $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1 $queryOutputStr = $queryOutput -join "'n" if ($LASTEXITCODE -eq 0) { # Kiểm tra xem khóa có được áp dụng hay không (tìm kiếm "Cấu hình Hiện hoạt" hoặc chỉ báo tương tự) nếu (đối $queryOutputStr "Cấu hình Hiện hoạt.*:.*enabled" -hoặc $queryOutputStr "Configuration.*applied") { $wincsKeyApplied = $true $wincsKeyStatus = "Đã áp dụng" Write-Host "Phím WinCS F33E0C8E002: Đã áp dụng" -ForegroundColor Green } elseif ($queryOutputStr -match "not found|Không có cấu hình") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "WinCS Key F33E0C8E002: Not Applied" -ForegroundColor Yellow } người khác { # Key exists - check output for state $wincsKeyApplied = $true $wincsKeyStatus = "Đã áp dụng" Write-Host "WinCS Key F33E0C8E002: Applied" -ForegroundColor Green } } người khác { # Kiểm tra thông báo lỗi cụ thể if ($queryOutputStr "Access denied|administrator") { $wincsKeyStatus = "AccessDenied" Write-Host "WinCS Key F33E0C8E002: Access denied (run as admin)" -ForegroundColor DarkGray } elseif ($queryOutputStr -match "not found|Không có cấu hình") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "Phím WinCS F33E0C8E002: Chưa Áp dụng" -ForegroundColor Yellow } người khác { $wincsKeyStatus = "Truy vấn Không thành công" Write-Host "Phím WinCS F33E0C8E002: Truy vấn không thành công" -ForegroundColor Red } } } người khác { $wincsKeyStatus = "WinCsFlagsNotFound" Write-Host "Phím WinCS F33E0C8E002: WinCsFlags.exe tìm thấy" -ForegroundColor Gray } } bắt { $wincsKeyStatus = "Lỗi" Write-Host "Phím WinCS F33E0C8E002: Kiểm tra lỗi - $_" -ForegroundColor Red }
# ============================================================================= # Remediation Detection - Status Output & Exit Code # =============================================================================
# Xây dựng đối tượng trạng thái từ tất cả dữ liệu kiểm kê được thu thập $status = [ordered]@{ UEFICA2023Status = $uefica 2023Status UEFICA2023Error = $uefica 2023Error UEFICA2023ErrorEvent = $uefica 2023ErrorEvent AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } khác { $null } AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } khác { $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_<số> từ SkipReason trong sự kiện BucketId Sự kiện1801Count = $event 1801Count Event1808Count = $event 1808Count # Sự kiện lỗi với chi tiết đã chụp Event1795Count = $event 1795Count # Firmware đã trả về lỗi Event1795ErrorCode = $event 1795ErrorCode # Mã lỗi từ vi chương trình Event1796Count = $event 1796Count # Mã lỗi được ghi nhật ký Event1796ErrorCode = $event 1796ErrorCode # Mã lỗi đã ghi lại Event1800Count = $event 1800Count # Reboot needed (NOT an error) RebootPending = $rebootPending # True nếu Sự kiện 1800 hiện diện Sự kiện1802Count = $event 1802Count # Sự cố vi chương trình đã biết KnownIssueId = $knownIssueId # KI_<số> từ SkipReason Event1803Count = $event 1803Count # Thiếu bản cập nhật KEK MissingKEK = $missingKEK # OEM cần phải cung cấp KEK đã ký PK OSVersion = $osVersion LastBootTime = if ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } else { "$lastBootTime" } BaseBoardManufacturer = $baseBoardManufacturer BaseBoardProduct = $baseBoardProduct SecureBootTaskEnabled = $secureBootTaskEnabled SecureBootTaskStatus = $secureBootTaskStatus WinCSKeyApplied = $wincsKeyApplied # True nếu F33E0C8E002 phím được áp dụng WinCSKeyStatus = $wincsKeyStatus # Applied, NotApplied, WinCsFlagsNotFound, v.v. }
# Đầu ra trạng thái - Để tổng hợp dữ liệu $jsonOutput = $status | ConvertTo-Json -Nén
# Nếu OutputPath được cung cấp, hãy lưu vào tệp; nếu không đầu ra thành stdout if (-not [string]::IsNullOrEmpty($OutputPath)) { # Xác thực OutputPath - bỏ qua nếu có vẻ như yêu cầu trợ giúp hoặc có ký tự không hợp lệ if ($OutputPath -match '^[/\-]' -hoặc $OutputPath -match '[<>:"|? *]') { Write-Host "Invalid OutputPath specified, out out outdout" -ForegroundColor Yellow Write-Output $jsonOutput if ($secureBootEnabled -and $uefica 2023Status -eq "Đã cập nhật") { exit 0 } khác { exit 1 } } # Đảm bảo thư mục đầu ra tồn tại if (-not (Test-Path $OutputPath)) { hãy thử { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } bắt { Write-Warning "Không thể tạo thư mục kết quả: $OutputPath - $_" } } # Lưu vào HOSTNAME_latest.json $outputFile = Join-Path $OutputPath "$($hostname)_latest.json" hãy thử { $jsonOutput | Out-File -FilePath $outputFile -Encoding UTF8 -Force Write-Host "JSON đã lưu vào: $outputFile" -ForegroundColor Green } bắt { Write-Warning "Không thể viết vào tệp: $outputFile - $_" # Quay lại với chú thích Write-Output $jsonOutput } } người khác { # Hành vi ban đầu - đầu ra cho stdout Write-Output $jsonOutput }
# Exit code: "Đã cập nhật" là giá trị thành công cho mỗi sách giải trí if ($secureBootEnabled -and $uefica 2023Status -eq "Đã cập nhật") { exit 0 # Without issue } người khác { thoát 1 # Với sự cố }
|
Thay đổi ngày |
Thay đổi mô tả |
|
Ngày 13 tháng 5 năm 2026 |
|
|
Ngày 24 tháng 2 năm 2026 |
|
|
Ngày 22 tháng 2 năm 2026 |
|
|
Ngày 13 tháng 2 năm 2026 |
|