วันที่เผยแพร่ต้นฉบับ: วันที่ 17 พฤศจิกายน 2568
KB ID: 5072718
|
เปลี่ยนวันที่ |
เปลี่ยนคําอธิบาย |
|
วันที่ 24 กุมภาพันธ์ 2569 |
|
|
วันที่ 22 กุมภาพันธ์ 2569 |
|
|
วันที่ 13 กุมภาพันธ์ 2569 |
|
ตัวอย่างสคริปต์การเก็บรวบรวมข้อมูลการบูตแบบปลอดภัย
คัดลอกและวางสคริปต์ตัวอย่างนี้และปรับเปลี่ยนตามที่จําเป็นสําหรับสภาพแวดล้อมของคุณ: สคริปต์การเก็บรวบรวมข้อมูลสินค้าคงคลัง Secure Boot ตัวอย่าง
<# . คําพ้องความหมาย ตรวจหาสถานะการอัปเดตใบรับรองการบูตแบบปลอดภัยสําหรับการตรวจสอบทั่วทั้งกลุ่ม
. คำ อธิบาย สคริปต์การตรวจสอบนี้จะเก็บรวบรวมค่ารีจิสทรีการอัปเดตใบรับรอง และสถานะการบูตแบบปลอดภัย และข้อมูลอุปกรณ์ มันออกสตริง JSON สําหรับการตรวจสอบและการรายงาน
สามารถใช้ร่วมกับการแก้ไข Intune การรวบรวมตาม GPO และเครื่องมือการจัดการอื่นๆไม่จําเป็นต้องใช้สคริปต์การแก้ไข เนื่องจากเป็นการตรวจสอบเท่านั้น
Exit 0 = "ไม่มีปัญหา" (อัปเดตใบรับรอง) Exit 1 = "มีปัญหา" (ใบรับรองที่ไม่ได้อัปเดต — ให้ข้อมูลเท่านั้น)
. PARAMETER OutputPath เสริม เส้นทางไปยังโฟลเดอร์ที่จะบันทึกไฟล์ JSONถ้าระบุไว้ จะบันทึก HOSTNAME_latest.json ลงในโฟลเดอร์นี้ถ้าไม่ได้ระบุไว้ ให้เอาท์พุต JSON เป็น stdout (ลักษณะการทํางานเดิม)
. ตัว อย่าง เช่น # เอาท์พุทเป็น stdout (การตรวจจับ Intune/SCCM) .\Detect-SecureBootCertUpdateStatus.ps1
. ตัว อย่าง เช่น # บันทึกไปยังการแชร์เครือข่าย (การปรับใช้ GPO) .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"
. หมาย เหตุ เส้นทางรีจิสทรีต่อ https://aka.ms/securebootplaybook: HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing
ซอฟต์แวร์นี้ให้ไว้ "ตามที่เป็น" โดยไม่มีการรับประกันใดๆ ไม่ว่าโดยชัดแจ้งหรือ โดยนัยแล้ว รวมถึงแต่ไม่จํากัดเพียงการรับประกันความสามารถในเชิงพาณิชย์ ความเหมาะสมสําหรับวัตถุประสงค์เฉพาะและการไม่ละเมิด ไม่ว่าในกรณีใด ผู้เขียนหรือเจ้าของลิขสิทธิ์ต้องรับผิดชอบต่อการเรียกร้องค่าเสียหายหรืออื่น ๆ ความรับผิด ไม่ว่าจะเป็นการกระทําของสัญญา การละเมิด หรืออื่นๆ ที่เกิดขึ้นจาก ไม่หรือเกี่ยวข้องกับซอฟต์แวร์หรือการใช้งานหรือการติดต่ออื่นๆ ใน ซอฟต์แวร์ #> param( [พารามิเตอร์(บังคับ = $false)] [string]$OutputPath )
# ดาวน์โหลด URL: https://aka.ms/getsecureboot -> "ตัวอย่างการปรับใช้และการตรวจสอบ" # หมายเหตุ: สคริปต์นี้ทํางานบนจุดสิ้นสุดเพื่อรวบรวมข้อมูลสถานะการบูตแบบปลอดภัย
# 1. HostName # เวอร์ชัน PS: ทั้งหมด | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $hostname = $env:COMPUTERNAME if ([string]::IsNullOrEmpty($hostname)) { Write-Warning "ไม่สามารถระบุ Hostname ได้" $hostname = "ไม่รู้จัก" } Write-Host "Hostname: $hostname" } จับ { Write-Warning "เกิดข้อผิดพลาดในการดึงข้อมูลชื่อโฮสต์: $_" $hostname = "ข้อผิดพลาด" Write-Host "Hostname: $hostname" }
# 2. เวลาในการรวบรวม # เวอร์ชัน PS: ทั้งหมด | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $collectionTime = Get-Date if ($null -eq $collectionTime) { Write-Warning "ไม่สามารถเรียกข้อมูลวันที่/เวลาปัจจุบันได้" $collectionTime = "ไม่รู้จัก" } Write-Host "เวลาในการเก็บ: $collectionTime" } จับ { Write-Warning "ข้อผิดพลาดในการดึงข้อมูลวันที่/เวลา: $_" $collectionTime = "ข้อผิดพลาด" Write-Host "เวลาในคอลเลกชัน: $collectionTime" }
# รีจิสทรี: คีย์หลักของการบูตแบบปลอดภัย (3 ค่า)
# 3. SecureBootEnabled # PS เวอร์ชัน: 3.0+ | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ระบบที่รองรับ UEFI/Secure Boot ลอง { $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop Write-Host "เปิดใช้งานการบูตแบบปลอดภัย: $secureBootEnabled" } จับ { Write-Warning "ไม่สามารถตรวจสอบสถานะการบูตแบบปลอดภัยผ่าน cmdlet: $_" # ลองใช้การย้อนกลับของรีจิสทรี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled Write-Host "เปิดใช้งานการบูตแบบปลอดภัย: $secureBootEnabled" } จับ { Write-Warning "ไม่สามารถระบุสถานะการบูตแบบปลอดภัยผ่านรีจิสทรีได้ ระบบอาจไม่สนับสนุน UEFI/Secure Boot" $secureBootEnabled = $null Write-Host "เปิดใช้งานการบูตแบบปลอดภัย: ไม่พร้อมใช้งาน" } }
# 4. HighConfidenceOptOut # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop $highConfidenceOptOut = $regValue.HighConfidenceOptOut Write-Host "เลือกไม่รับความเชื่อมั่นสูง: $highConfidenceOptOut" } จับ { # HighConfidenceOptOut เป็นตัวเลือก - ไม่มีอยู่ในระบบส่วนใหญ่ $highConfidenceOptOut = $null Write-Host "เลือกไม่รับความเชื่อมั่นสูง: ไม่ได้ตั้งค่า" }
# 4b. MicrosoftUpdateManagedOptIn # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn Write-Host "Microsoft Update Managed Opt in: $microsoftUpdateManagedOptIn" } จับ { # MicrosoftUpdateManagedOptIn เป็นตัวเลือก - ไม่มีอยู่ในระบบส่วนใหญ่ $microsoftUpdateManagedOptIn = $null Write-Host "Microsoft Update Managed Opt in: Not Set" }
# 5. AvailableUpdates # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop $availableUpdates = $regValue.AvailableUpdates if ($null -ne $availableUpdates) { # แปลงเป็นรูปแบบเลขฐานสิบหก $availableUpdatesHex = "0x{0:X}" -f $availableUpdates Write-Host "Updates ที่พร้อมใช้งาน: $availableUpdatesHex" } อื่น { Write-Host "Updates ที่พร้อมใช้งาน: ไม่พร้อมใช้งาน" } } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ AvailableUpdates หรือไม่สามารถเข้าถึงได้" $availableUpdates = $null Write-Host "Updates ที่พร้อมใช้งาน: ไม่พร้อมใช้งาน" }
# 5b. AvailableUpdatesPolicy (ค่าถาวรที่ควบคุมโดย GPO) # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy if ($null -ne $availableUpdatesPolicy) { # แปลงเป็นรูปแบบเลขฐานสิบหก $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy Write-Host "นโยบาย Updates ที่พร้อมใช้งาน: $availableUpdatesPolicyHex" } อื่น { Write-Host "นโยบาย Updates ที่พร้อมใช้งาน: ไม่ได้กําหนด" } } จับ { # AvailableUpdatesPolicy เป็นตัวเลือก - ตั้งค่าเฉพาะเมื่อมีการใช้ GPO $availableUpdatesPolicy = $null Write-Host "นโยบาย Updates ที่พร้อมใช้งาน: ไม่ได้กําหนด" }
# รีจิสทรี: คีย์การให้บริการ (3 ค่า)
# 6. UEFICA2023Status # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop $uefica 2023Status = $regValue.UEFICA2023Status Write-Host "สถานะ Windows UEFI CA 2023: $uefica 2023Status" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์สถานะ Windows UEFI CA 2023 หรือไม่สามารถเข้าถึงได้" $uefica 2023Status = $null Write-Host "สถานะ Windows UEFI CA 2023: ไม่พร้อมใช้งาน" }
# 7. UEFICA2023Error # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop $uefica 2023Error = $regValue.UEFICA2023Error Write-Host "ข้อผิดพลาด UEFI CA 2023: $uefica 2023Error" } จับ { # UEFICA2023Error จะมีอยู่ก็ต่อเมื่อมีข้อผิดพลาด - การขาดงานเป็นสิ่งที่ดี $uefica 2023Error = $null Write-Host "ข้อผิดพลาด UEFI CA 2023: ไม่มี" }
# 8. UEFICA2023ErrorEvent # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent Write-Host "เหตุการณ์ข้อผิดพลาด UEFI CA 2023: $uefica 2023ErrorEvent" } จับ { $uefica 2023ErrorEvent = $null Write-Host "เหตุการณ์ข้อผิดพลาด UEFI CA 2023: ไม่พร้อมใช้งาน" }
# รีจิสทรี: แอตทริบิวต์ของอุปกรณ์ (7 ค่า: 9-15)
# 9. OEMManufacturerName # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $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 ว่างเปล่า" $oemManufacturerName = "ไม่รู้จัก" } Write-Host "ชื่อผู้ผลิต OEM: $oemManufacturerName" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ OEMManufacturerName หรือไม่สามารถเข้าถึงได้" $oemManufacturerName = $null Write-Host "ชื่อผู้ผลิต OEM: ไม่พร้อมใช้งาน" }
# 10. OEMModelSystemFamily # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $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 ว่างเปล่า" $oemModelSystemFamily = "ไม่รู้จัก" } Write-Host "ตระกูลระบบรุ่น OEM: $oemModelSystemFamily" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ OEMModelSystemFamily หรือไม่สามารถเข้าถึงได้" $oemModelSystemFamily = $null Write-Host "ตระกูลระบบรุ่น OEM: ไม่พร้อมใช้งาน" }
# 11. OEMModelNumber # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $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 ว่างเปล่า" $oemModelNumber = "ไม่รู้จัก" } Write-Host "หมายเลขรุ่น OEM: $oemModelNumber" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ OEMModelNumber หรือไม่สามารถเข้าถึงได้" $oemModelNumber = $null Write-Host "หมายเลขรุ่น OEM: ไม่พร้อมใช้งาน" }
# 12. FirmwareVersion # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $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 ว่างเปล่า" $firmwareVersion = "ไม่รู้จัก" } Write-Host "เวอร์ชันเฟิร์มแวร์: $firmwareVersion" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ FirmwareVersion หรือไม่สามารถเข้าถึงได้" $firmwareVersion = $null Write-Host "เวอร์ชันเฟิร์มแวร์: ไม่พร้อมใช้งาน" }
# 13. FirmwareReleaseDate # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $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 ว่างเปล่า" $firmwareReleaseDate = "ไม่รู้จัก" } Write-Host "วันที่เผยแพร่เฟิร์มแวร์: $firmwareReleaseDate" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ FirmwareReleaseDate หรือไม่สามารถเข้าถึงได้" $firmwareReleaseDate = $null Write-Host "วันที่เผยแพร่เฟิร์มแวร์: ไม่พร้อมใช้งาน" }
# 14. OSArchitecture # เวอร์ชัน PS: ทั้งหมด | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $osArchitecture = $env:PROCESSOR_ARCHITECTURE if ([string]::IsNullOrEmpty($osArchitecture)) { # ลองใช้การย้อนกลับของรีจิสทรี $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 ได้" $osArchitecture = "ไม่รู้จัก" } Write-Host "สถาปัตยกรรมของระบบปฏิบัติการ: $osArchitecture" } จับ { Write-Warning "ข้อผิดพลาดในการเรียก OSArchitecture: $_" $osArchitecture = "ไม่รู้จัก" Write-Host "สถาปัตยกรรมของระบบปฏิบัติการ: $osArchitecture" }
# 15. CanAttemptUpdateAfter (FILETIME) # เวอร์ชัน PS: ทั้งหมด | Admin: อาจจําเป็นต้องมี | ความต้องการของระบบ: ไม่มี ลอง { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter # Convert FILETIME เป็น UTC DateTime — รีจิสทรีสโตร์เป็น REG_BINARY (byte[]) หรือ REG_QWORD (long) if ($null -ne $canAttemptUpdateAfter) { ลอง { if ($canAttemptUpdateAfter -is [byte[]]) { $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter, 0) $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime) ToUniversalTime() } elseif ($canAttemptUpdateAfter -is [long]) { $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter) ToUniversalTime() } } จับ { Write-Warning "ไม่สามารถแปลง CanAttemptUpdateAfter FILETIME เป็น DateTime" ได้ } } Write-Host "สามารถลองอัปเดตได้หลังจาก: $canAttemptUpdateAfter" } จับ { Write-Warning "ไม่พบรีจิสทรีคีย์ CanAttemptUpdateAfter หรือไม่สามารถเข้าถึงได้" $canAttemptUpdateAfter = $null Write-Host "สามารถลองอัปเดตหลังจาก: ไม่พร้อมใช้งาน" }
# บันทึกเหตุการณ์: บันทึกของระบบ (10 ค่า: 16-25)
# 16-25. คิวรีบันทึกเหตุการณ์ # รหัสเหตุการณ์: # 1801 - การอัปเดตเริ่มต้นแล้ว จําเป็นต้องเริ่มต้นระบบใหม่ # 1808 - การอัปเดตเสร็จสมบูรณ์ # 1795 - ข้อผิดพลาดเฟิร์มแวร์ส่งกลับ (รหัสข้อผิดพลาดการจับภาพ) # 1796 - บันทึกข้อผิดพลาดด้วยรหัสข้อผิดพลาด (รหัสการจับภาพ) # 1800 - จําเป็นต้องเริ่มต้นระบบใหม่ (ไม่ใช่ข้อผิดพลาด - การอัปเดตจะดําเนินการต่อหลังจากเริ่มต้นระบบใหม่) # 1802 - ปัญหาเฟิร์มแวร์ที่ทราบแล้วถูกบล็อกการอัปเดต (จับภาพหมายเลข KI_<> จาก SkipReason) # 1803 - ไม่พบการอัปเดต KEK ที่ตรงกัน (OEM จําเป็นต้องจัดหา PK ที่ลงนามใน KEK) # PS เวอร์ชัน: 3.0+ | Admin: อาจจําเป็นสําหรับบันทึกของระบบ | Windows 10 ความต้องการของระบบ: ไม่มี ลอง { # สอบถามรหัสเหตุการณ์การบูตแบบปลอดภัยที่เกี่ยวข้องทั้งหมด $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808) $events = @(Get-WinEvent -FilterHashtable @{LogName='System'; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)
ถ้า ($events Count -eq 0) { Write-Warning "ไม่พบเหตุการณ์การบูตแบบปลอดภัยในบันทึกของระบบ" $latestEventId = $null $bucketId = $null $confidence = $null $skipReasonKnownIssue = $null $event 1801 บัญชี = 0 $event 1808 จํานวน = 0 $event 1795 จํานวน = 0 $event 1795ErrorCode = $null $event 1796 จํานวน = 0 $event 1796ErrorCode = $null $event 1800 จํานวน = 0 $rebootPending = $false $event 1802 จํานวน = 0 $knownIssueId = $null $event 1803 จํานวน = 0 $missingKEK = $false Write-Host "ID เหตุการณ์ล่าสุด: ไม่พร้อมใช้งาน" Write-Host "Bucket ID: ไม่พร้อมใช้งาน" Write-Host "ความเชื่อมั่น: ไม่พร้อมใช้งาน" Write-Host "จํานวนเหตุการณ์ 1801: 0" Write-Host "จํานวนเหตุการณ์ 1808: 0" } อื่น { # 16. LatestEventId $latestEvent = $events | Sort-Object TimeCreated -จากมากไปหาน้อย | TimeCreated | TimeCreated Select-Object -First 1 if ($null -eq $latestEvent) { Write-Warning "ไม่สามารถระบุเหตุการณ์ล่าสุดได้" $latestEventId = $null Write-Host "ID เหตุการณ์ล่าสุด: ไม่พร้อมใช้งาน" } อื่น { $latestEventId = $latestEvent.Id Write-Host "รหัสเหตุการณ์ล่าสุด: $latestEventId" }
# 17. BucketID - แยกจากเหตุการณ์ 1801/1808 if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) { if ($latestEvent.Message -match 'BucketId:\s*(.+)') { $bucketId = $matches[1] ตัดแต่ง() Write-Host "Bucket ID: $bucketId" } อื่น { Write-Warning "ไม่พบ BucketId ในข้อความเหตุการณ์" $bucketId = $null Write-Host "Bucket ID: ไม่พบในเหตุการณ์" } } อื่น { Write-Warning "เหตุการณ์หรือข้อความล่าสุดเป็น Null ไม่สามารถแยก BucketId" $bucketId = $null Write-Host "Bucket ID: ไม่พร้อมใช้งาน" }
# 18. Confidence - Extracted from Event 1801/1808 if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) { if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') { $confidence = $matches[1] ตัดแต่ง() Write-Host "ความเชื่อมั่น: $confidence" } อื่น { Write-Warning "ไม่พบระดับความเชื่อมั่นในข้อความเหตุการณ์" $confidence = $null Write-Host "ความเชื่อมั่น: ไม่พบในเหตุการณ์" } } อื่น { Write-Warning "เหตุการณ์หรือข้อความล่าสุดเป็น null ไม่สามารถแยกความเชื่อมั่น" $confidence = $null Write-Host "ความเชื่อมั่น: ไม่พร้อมใช้งาน" }
# 18b SkipReason - แยกหมายเลข KI_<> จาก SkipReason ในเหตุการณ์เดียวกันกับ BucketId # รหัสปัญหาที่ทราบที่ปรากฏควบคู่ไปกับ BucketId/Confidence (ไม่ใช่แค่ Event 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: $skipReasonKnownIssue" -ForegroundColor สีเหลือง } }
# 19. เหตุการณ์ 1801 บัญชี $event 1801Array = @($events | Where-Object {$_. Id -eq 1801}) $event 1801 นับ = $event 1801Array.Count Write-Host "จํานวนเหตุการณ์ 1801: $event 1801 นับจํานวน"
# 20. Event1808Count $event 1808Array = @($events | Where-Object {$_. Id -eq 1808}) $event 1808 นับ = $event 1808Array.Count Write-Host "จํานวนเหตุการณ์ 1808: $event 1808 นับจํานวน" # เริ่มต้นตัวแปรเหตุการณ์ข้อผิดพลาด $event 1795 จํานวน = 0 $event 1795ErrorCode = $null $event 1796 จํานวน = 0 $event 1796ErrorCode = $null $event 1800 จํานวน = 0 $rebootPending = $false $event 1802 จํานวน = 0 $knownIssueId = $null $event 1803 จํานวน = 0 $missingKEK = $false # ตรวจหาเหตุการณ์ข้อผิดพลาดเท่านั้น ถ้าการอัปเดตไม่เสร็จสมบูรณ์ # ข้ามการวิเคราะห์ข้อผิดพลาด ถ้า: 1808 เป็นเหตุการณ์ล่าสุด หรือ UEFICA2023Status เป็น "อัปเดต" $updateComplete = ($latestEventId -eq 1808) -or ($uefica 2023Status -eq "อัปเดต") if (-not $updateComplete) { Write-Host "การอัปเดตไม่เสร็จสมบูรณ์ - การตรวจสอบหาเหตุการณ์ข้อผิดพลาด..." -ForegroundColor Yellow # 21. เหตุการณ์ 1795 - ข้อผิดพลาดของเฟิร์มแวร์ (รหัสข้อผิดพลาดการจับภาพ) $event 1795Array = @($events | Where-Object {$_. Id -eq 1795}) $event 1795 นับ = $event 1795Array.Count if ($event 1795Count -gt 0) { $latestEvent 1795 = $event 1795Array | Sort-Object TimeCreated -จากมากไปหาน้อย | TimeCreated | TimeCreated Select-Object -First 1 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 "เหตุการณ์ 1795 (ข้อผิดพลาดของเฟิร์มแวร์) จํานวน: $event 1795Count" $(ถ้า ($event 1795ErrorCode) { "รหัส: $event 1795ErrorCode" }) } # 22. เหตุการณ์ 1796 - บันทึกรหัสข้อผิดพลาด (รหัสข้อผิดพลาดการจับภาพ) $event 1796Array = @($events | Where-Object {$_. Id -eq 1796}) $event 1796 นับ = $event 1796Array.Count if ($event 1796Count -gt 0) { $latestEvent 1796 = $event 1796Array | Sort-Object TimeCreated -จากมากไปหาน้อย | TimeCreated | TimeCreated Select-Object -First 1 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 "เหตุการณ์ 1796 (บันทึกข้อผิดพลาด) จํานวน: $event 1796Count" $(ถ้า ($event 1796ErrorCode) { "โค้ด: $event 1796ErrorCode" }) } # 23. Event1800 - ต้องการการเริ่มต้นระบบใหม่ (ไม่ใช่ข้อผิดพลาด - การอัปเดตจะดําเนินการต่อหลังจากเริ่มต้นระบบใหม่) $event 1800Array = @($events | Where-Object {$_. Id -eq 1800}) $event 1800 นับ = $event 1800Array.Count $rebootPending = $event 1800 จํานวน -gt 0 if ($rebootPending) { Write-Host "เหตุการณ์ 1800 (รอเริ่มต้นระบบใหม่อยู่): การอัปเดตจะดําเนินการหลังจากเริ่มระบบใหม่" -ForegroundColor Cyan } # 24. Event1802 - ปัญหาเฟิร์มแวร์ที่ทราบแล้ว (จับภาพหมายเลข KI_<> จาก SkipReason) $event 1802Array = @($events | Where-Object {$_. Id -eq 1802}) $event 1802 นับ = $event 1802Array.Count if ($event 1802Count -gt 0) { $latestEvent 1802 = $event 1802Array | Sort-Object TimeCreated -จากมากไปหาน้อย | TimeCreated | TimeCreated Select-Object -First 1 if ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)') { $knownIssueId = $matches[1] } Write-Host จํานวน "เหตุการณ์ 1802 (ปัญหาเฟิร์มแวร์ที่ทราบแล้ว): $event 1802 นับ" $(ถ้า ($knownIssueId) { "KI: $knownIssueId" }) } # 25. Event1803 - ไม่มีการอัปเดต KEK (OEM ต้องจัดหา PK ที่ลงนามใน KEK) $event 1803Array = @($events | Where-Object {$_. Id -eq 1803}) $event 1803 นับ = $event 1803Array.Count $missingKEK = $event 1803Count -gt 0 if ($missingKEK) { Write-Host "Event 1803 (Missing KEK): OEM ต้องจัดหา PK ที่ลงนามใน KEK" -ForegroundColor Yellow } } อื่น { Write-Host "อัปเดตเสร็จสมบูรณ์ (เหตุการณ์ 1808 หรือ Status=Update) - ข้ามการวิเคราะห์ข้อผิดพลาด" -ForegroundColor Green } } } จับ { Write-Warning "ข้อผิดพลาดในการเรียกบันทึกเหตุการณ์ อาจต้องการสิทธิ์ระดับผู้ดูแลระบบ: $_" $latestEventId = $null $bucketId = $null $confidence = $null $skipReasonKnownIssue = $null $event 1801 บัญชี = 0 $event 1808 จํานวน = 0 $event 1795 จํานวน = 0 $event 1795ErrorCode = $null $event 1796 จํานวน = 0 $event 1796ErrorCode = $null $event 1800 จํานวน = 0 $rebootPending = $false $event 1802 จํานวน = 0 $knownIssueId = $null $event 1803 บัญชี = 0 $missingKEK = $false Write-Host "รหัสเหตุการณ์ล่าสุด: ข้อผิดพลาด" Write-Host "Bucket ID: ข้อผิดพลาด" Write-Host "ความเชื่อมั่น: ข้อผิดพลาด" Write-Host "จํานวนเหตุการณ์ 1801: 0" Write-Host "จํานวนเหตุการณ์ 1808: 0" }
# คิวรี WMI/CIM (5 ค่า)
# 26. OSVersion # PS เวอร์ชัน: 3.0+ (ใช้ Get-WmiObject สําหรับ 2.0) | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -or [string]::IsNullOrEmpty($osInfo.Version)) { Write-Warning "ไม่สามารถเรียกข้อมูลเวอร์ชันของระบบปฏิบัติการได้" $osVersion = "ไม่รู้จัก" } อื่น { $osVersion = $osInfo.Version } Write-Host "เวอร์ชันของระบบปฏิบัติการ: $osVersion" } จับ { # CIM อาจล้มเหลวในบางสภาพแวดล้อม - ใช้การย้อนกลับ $osVersion = [System.Environment]::OSVersion.Version.ToString() if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" } Write-Host "เวอร์ชันของระบบปฏิบัติการ: $osVersion" }
# 27. LastBootTime # PS เวอร์ชัน: 3.0+ (ใช้ Get-WmiObject สําหรับ 2.0) | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -or $null -eq $osInfo.LastBootUpTime) { Write-Warning "ไม่สามารถเรียกข้อมูลเวลาเริ่มระบบล่าสุด" $lastBootTime = $null Write-Host "เวลาเริ่มต้นระบบครั้งล่าสุด: ไม่พร้อมใช้งาน" } อื่น { $lastBootTime = $osInfo.LastBootUpTime Write-Host "เวลาเริ่มต้นระบบครั้งล่าสุด: $lastBootTime" } } จับ { # CIM อาจล้มเหลวในบางสภาพแวดล้อม - ใช้การย้อนกลับ ลอง { $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue) เวลาเริ่มต้น } จับ { $lastBootTime = $null } if ($lastBootTime) { Write-Host "เวลาเริ่มต้นระบบครั้งล่าสุด: $lastBootTime" } } อื่น { Write-Host "เวลาเริ่มต้นระบบครั้งล่าสุด: ไม่พร้อมใช้งาน" } }
# 28. BaseBoardManufacturer # PS เวอร์ชัน: 3.0+ (ใช้ Get-WmiObject สําหรับ 2.0) | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) { Write-Warning "ไม่สามารถเรียกข้อมูลผู้ผลิต Baseboard ได้" $baseBoardManufacturer = "ไม่รู้จัก" } อื่น { $baseBoardManufacturer = $baseBoard.Manufacturer } Write-Host "ผู้ผลิตฐาน: $baseBoardManufacturer" } จับ { # CIM อาจล้มเหลว - ข้อมูลฐานเป็นข้อมูลเพิ่มเติม $baseBoardManufacturer = "ไม่รู้จัก" Write-Host "ผู้ผลิตฐาน: $baseBoardManufacturer" }
# 29. BaseBoardProduct # PS เวอร์ชัน: 3.0+ (ใช้ Get-WmiObject สําหรับ 2.0) | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: ไม่มี ลอง { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) { Write-Warning "ไม่สามารถเรียกข้อมูลผลิตภัณฑ์ Baseboard ได้" $baseBoardProduct = "ไม่รู้จัก" } อื่น { $baseBoardProduct = $baseBoard.Product } Write-Host "ผลิตภัณฑ์ Baseboard: $baseBoardProduct" } จับ { # CIM อาจล้มเหลว - ข้อมูลฐานเป็นข้อมูลเพิ่มเติม $baseBoardProduct = "ไม่รู้จัก" Write-Host "ผลิตภัณฑ์ Baseboard: $baseBoardProduct" }
# 30. SecureBootTaskEnabled # เวอร์ชัน PS: ทั้งหมด | Admin: ไม่ใช่ | '|1' ความต้องการของระบบ: มีงานที่กําหนดเวลาไว้แล้ว # ตรวจสอบว่ามีการเปิดใช้งานงานที่กําหนดเวลาการอัปเดต Secure-Boot-Update หรือไม่ $secureBootTaskEnabled = $null $secureBootTaskStatus = "ไม่รู้จัก" ลอง { $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') } } อื่น { $secureBootTaskStatus = "NotFound" $secureBootTaskEnabled = $false } if ($secureBootTaskEnabled -eq $false) { Write-Host "งานการอัปเดต SecureBoot: $secureBootTaskStatus (เปิดใช้งาน: $secureBootTaskEnabled)" -ForegroundColor สีเหลือง } อื่น { Write-Host "งานการอัปเดต SecureBoot: $secureBootTaskStatus (เปิดใช้งาน: $secureBootTaskEnabled)" -ForegroundColor Green } } จับ { $secureBootTaskStatus = "ข้อผิดพลาด" $secureBootTaskEnabled = $false Write-Host "งานการอัปเดต SecureBoot: การตรวจสอบข้อผิดพลาด - $_" -ForegroundColor Red }
# 31. สถานะคีย์ WinCS (F33E0C8E002 - การอัปเดตใบรับรองการบูตแบบปลอดภัย) # เวอร์ชัน PS: ทั้งหมด | Admin: ใช่ (สําหรับแบบสอบถาม) | ความต้องการของระบบ: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "ไม่รู้จัก" ลอง { # ตรวจสอบตําแหน่งทั่วไปสําหรับ WinCsFlags.exe $wincsFlagsPath = $null $possiblePaths = @( "$env:SystemRoot\System32\WinCsFlags.exe", "$env:SystemRoot\SysWOW64\WinCsFlags.exe" ) foreach ($p ใน $possiblePaths) { if (Test-Path $p) { $wincsFlagsPath = $p; break } } if ($wincsFlagsPath) { # คีย์เฉพาะคิวรี - จําเป็นต้องมีสิทธิ์ของผู้ดูแลระบบ $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1 $queryOutputStr = $queryOutput -join "'n" if ($LASTEXITCODE -eq 0) { # ตรวจสอบว่ามีการนําคีย์ไปใช้หรือไม่ (ค้นหา "การกําหนดค่าแบบแอ็กทีฟ" หรือตัวบ่งชี้ที่คล้ายกัน) if ($queryOutputStr -match "Active Configuration.*:.*enabled" -or $queryOutputStr -match "Configuration.*applied") { $wincsKeyApplied = $true $wincsKeyStatus = "นําไปใช้" Write-Host "แป้น WinCS F33E0C8E002: นําไปใช้" -สีพื้นหน้าสีเขียว } elseif ($queryOutputStr -match "ไม่พบ|ไม่มีการกําหนดค่า") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "แป้น WinCS F33E0C8E002: ไม่ได้นําไปใช้" -สีพื้นหน้า สีเหลือง } อื่น { # มีคีย์อยู่ - ตรวจสอบผลลัพธ์สําหรับสถานะ $wincsKeyApplied = $true $wincsKeyStatus = "นําไปใช้" Write-Host "แป้น WinCS F33E0C8E002: นําไปใช้" -สีพื้นหน้าสีเขียว } } อื่น { # ตรวจหาข้อความแสดงข้อผิดพลาดที่เฉพาะเจาะจง if ($queryOutputStr -match "Access denied|administrator") { $wincsKeyStatus = "AccessDenied" Write-Host "คีย์ WinCS F33E0C8E002: การเข้าถึงถูกปฏิเสธ (เรียกใช้ในฐานะผู้ดูแลระบบ)" -ForegroundColor DarkGray } elseif ($queryOutputStr -match "ไม่พบ|ไม่มีการกําหนดค่า") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "แป้น WinCS F33E0C8E002: ไม่ได้นําไปใช้" -สีพื้นหน้า สีเหลือง } อื่น { $wincsKeyStatus = "QueryFailed" Write-Host "แป้น WinCS F33E0C8E002: คิวรีล้มเหลว" -ForegroundColor Red } } } อื่น { $wincsKeyStatus = "WinCsFlagsNotFound" Write-Host "แป้น WinCS F33E0C8E002: ไม่พบ WinCsFlags.exe" -ForegroundColor Gray } } จับ { $wincsKeyStatus = "ข้อผิดพลาด" Write-Host "แป้น WinCS F33E0C8E002: การตรวจสอบข้อผิดพลาด - $_" -ForegroundColor Red }
# ============================================================================= #Remediation Detection - Status Output & Exit Code # =============================================================================
# สร้างวัตถุสถานะจากข้อมูลสินค้าคงคลังที่รวบรวมทั้งหมด $status = [ordered]@{ สถิติ UEFICA2023 = $uefica 2023Status UEFICA2023Error = $uefica 2023Error UEFICA2023ErrorEvent = $uefica 2023ErrorEvent 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_<หมายเลข> จาก SkipReason ในเหตุการณ์ BucketId Event1801Count = $event 1801Count Event1808Count = $event 1808Count # เหตุการณ์ข้อผิดพลาดที่มีรายละเอียดที่จับภาพไว้ Event1795Count = $event 1795Count # ข้อผิดพลาดที่ส่งคืนเฟิร์มแวร์ Event1795ErrorCode = $event 1795ErrorCode # รหัสข้อผิดพลาดจากเฟิร์มแวร์ Event1796Count = $event 1796Count # บันทึกรหัสข้อผิดพลาด Event1796ErrorCode = $event 1796ErrorCode # จับรหัสข้อผิดพลาด Event1800Count = $event 1800Count # จําเป็นต้องเริ่มต้นระบบใหม่ (ไม่ใช่ข้อผิดพลาด) เริ่มต้นระบบใหม่ที่ค้างอยู่ = $rebootPending # True ถ้ามีเหตุการณ์ 1800 Event1802Count = $event 1802Count # ปัญหาเฟิร์มแวร์ที่ทราบ KnownIssueId = $knownIssueId # KI_<หมายเลข> จาก SkipReason Event1803Count = $event 1803Count #Missing KEK update MissingKEK = $missingKEK # OEM จําเป็นต้องจัดหา PK ที่ลงนามใน KEK OSVersion = $osVersion LastBootTime = if ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } else { "$lastBootTime" } BaseBoardManufacturer = $baseBoardManufacturer BaseBoardProduct = $baseBoardProduct SecureBootTaskEnabled = $secureBootTaskEnabled SecureBootTaskStatus = $secureBootTaskStatus WinCSKeyApplied = $wincsKeyApplied # True ถ้านําคีย์ F33E0C8E002 ไปใช้ WinCSKeyStatus = $wincsKeyStatus # Applied, NotApplied, WinCsFlagsNotFound เป็นต้น }
# แสดงสถานะ - สําหรับการรวมข้อมูล $jsonOutput = $status | ConvertTo-Json -บีบอัด
# ถ้ามี OutputPath ให้บันทึกไปยังไฟล์ มิฉะนั้น ให้แสดงผลเป็น stdout if (-not [string]::IsNullOrEmpty($OutputPath)) { # ตรวจสอบ OutputPath - ข้ามถ้าดูเหมือนคําขอวิธีใช้หรือมีอักขระที่ไม่ถูกต้อง if ($OutputPath -match '^[/\-]' -or $OutputPath -match '[<>:"|? *]') { Write-Host "ระบุ OutputPath ไม่ถูกต้อง แสดงเป็น stdout" -ForegroundColor สีเหลือง Write-Output $jsonOutput if ($secureBootEnabled -and $uefica 2023Status -eq "อัปเดต") { exit 0 } อื่น { exit 1 } } # ตรวจสอบให้แน่ใจว่ามีโฟลเดอร์ผลลัพธ์อยู่ if (-not (Test-Path $OutputPath)) { ลอง { New-Item -ItemType Directory -Path $OutputPath -Force | '|1' Out-Null } จับ { Write-Warning "ไม่สามารถสร้างโฟลเดอร์ผลลัพธ์ได้: $OutputPath - $_" } } # บันทึกไปยัง HOSTNAME_latest.json $outputFile = Join-Path $OutputPath "$($hostname)_latest.json" ลอง { $jsonOutput | Out-File -FilePath $outputFile -Encoding UTF8 -Force Write-Host "JSON บันทึกไปยัง: $outputFile" -ForegroundColor Green } จับ { Write-Warning "ไม่สามารถเขียนไปยังไฟล์: $outputFile - $_" # ถอยกลับไปเป็น stdout Write-Output $jsonOutput } } อื่น { # ลักษณะการทํางานเดิม - ผลลัพธ์เป็น stdout Write-Output $jsonOutput }
# Exit Code: "อัปเดต" คือมูลค่าความสําเร็จต่อหนังสือเล่น if ($secureBootEnabled -and $uefica 2023Status -eq "อัปเดต") { exit 0 # ไม่มีปัญหา } อื่น { exit 1 # With issue }