تاريخ النشر الأصلي: 17 نوفمبر 2025
معرف KB: 5072718
|
تغيير التاريخ |
تغيير الوصف |
|
24 فبراير 2026 |
|
|
22 فبراير 2026 |
|
|
13 فبراير 2026 |
|
نموذج البرنامج النصي لمجموعة بيانات مخزون التمهيد الآمن
انسخ هذا البرنامج النصي النموذجي والصقه وقم بتعديله حسب الحاجة لبيئتك: البرنامج النصي Sample Secure Boot Inventory Data Collection.
<# . خلاصه يكتشف حالة تحديث شهادة التمهيد الآمن للمراقبة على مستوى الأسطول.
. وصف يجمع برنامج الكشف النصي هذا حالة التمهيد الآمن، وقيم سجل تحديث الشهادة، ومعلومات الجهاز. إخراج سلسلة JSON للمراقبة وإعداد التقارير.
متوافق مع Intune المعالجات والمجموعة المستندة إلى عنصر نهج المجموعة وأدوات الإدارة الأخرى.لا توجد حاجة إلى برنامج نصي للمعالجة - هذا هو المراقبة فقط.
إنهاء 0 = "بدون مشكلة" (تم تحديث الشهادات) إنهاء 1 = "مع المشكلة" (الشهادات غير محدثة — إعلامية فقط)
. مسار إخراج المعلمة الاختياري. المسار إلى مجلد حيث سيتم حفظ ملف 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
يتم توفير البرنامج "كما هو"، دون ضمان من أي نوع، EXPRESS أو ضمنيا، بما في ذلك على سبيل المثال لا الحصر ضمانات قابلية المتاجرة، اللياقة البدنية لغرض معين وغير المتكررة. في أي حال من الأحوال يجب أن يتحمل المؤلفون أو أصحاب حقوق النشر مسؤولية أي مطالبة أو أضرار أو غيرها المسؤولية، سواء في إجراء العقد أو التقصير أو غير ذلك، الناشئة عن، خارج أو فيما يتعلق بالبرنامج أو الاستخدام أو التعاملات الأخرى في البرمجيات.#> param( [Parameter(إلزامي = $false)] [سلسلة]$OutputPath )
# Download URL: https://aka.ms/getsecureboot -> "عينات التوزيع والمراقبة" # ملاحظة: يعمل هذا البرنامج النصي على نقاط النهاية لجمع بيانات حالة التمهيد الآمن.
# 1. المضيف # إصدار PS: الكل | مسؤول: لا | متطلبات النظام: لا شيء جرب { $hostname = $env:COMPUTERNAME if ([string]::IsNullOrEmpty($hostname)) { Write-Warning "تعذر تحديد اسم المضيف" $hostname = "غير معروف" } Write-Host "اسم المضيف: $hostname" } التقاط { Write-Warning "خطأ في استرداد اسم المضيف: $_" $hostname = "خطأ" Write-Host "اسم المضيف: $hostname" }
# 2. وقت المجموعة # إصدار PS: الكل | مسؤول: لا | متطلبات النظام: لا شيء جرب { $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+ | مسؤول: قد يكون مطلوبا | متطلبات النظام: نظام قادر على 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: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop $highConfidenceOptOut = $regValue.HighConfidenceOptOut Write-Host "إلغاء الاشتراك عالي الثقة: $highConfidenceOptOut" } التقاط { # HighConfidenceOptOut اختياري - غير موجود على معظم الأنظمة $highConfidenceOptOut = $null Write-Host "إلغاء الاشتراك عالي الثقة: غير معين" }
# 4ب. MicrosoftUpdateManagedOptIn # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn Write-Host "الاشتراك المدار في Microsoft Update: $microsoftUpdateManagedOptIn" } التقاط { # MicrosoftUpdateManagedOptIn اختياري - غير موجود على معظم الأنظمة $microsoftUpdateManagedOptIn = $null Write-Host "الاشتراك المدار في Microsoft Update: غير معين" }
# 5. التحديثات المتوفرة # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 "التحديثات المتوفرة: $availableUpdatesHex" } آخر { Write-Host "متوفر التحديثات: غير متوفر" } } التقاط { Write-Warning "لم يتم العثور على مفتاح التسجيل AvailableUpdates أو تعذر الوصول إليه" $availableUpdates = $null Write-Host "التحديثات متوفر: غير متوفر" }
رقم 5 ب. AvailableUpdatesPolicy (القيمة الثابتة التي يتحكم فيها GPO) # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 "نهج التحديثات المتوفر: $availableUpdatesPolicyHex" } آخر { Write-Host "نهج التحديثات المتوفر: غير معين" } } التقاط { # AvailableUpdatesPolicy اختياري - يتم تعيينه فقط عند تطبيق عنصر نهج المجموعة $availableUpdatesPolicy = $null Write-Host "نهج التحديثات المتوفر: غير معين" }
# التسجيل: مفتاح الصيانة (3 قيم)
# 6. UEFICA2023Status # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 2023الخطأ = $null Write-Host "خطأ UEFI CA 2023: لا شيء" }
# 8. UEFICA2023ErrorEvent # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 "اسم الشركة المصنعة للشركة المصنعة للمعدات الأصلية: $oemManufacturerName" } التقاط { Write-Warning "لم يتم العثور على مفتاح التسجيل OEMManufacturerName أو تعذر الوصول إليه" $oemManufacturerName = $null Write-Host "اسم الشركة المصنعة للشركة المصنعة للمعدات الأصلية: غير متوفر" }
# 10. OEMModelSystemFamily # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 "عائلة نظام نموذج الشركة المصنعة للمعدات الأصلية: $oemModelSystemFamily" } التقاط { Write-Warning "لم يتم العثور على مفتاح التسجيل OEMModelSystemFamily أو تعذر الوصول إليه" $oemModelSystemFamily = $null Write-Host "عائلة نظام نموذج الشركة المصنعة للمعدات الأصلية: غير متوفر" }
# 11. OEMModelNumber # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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 "رقم نموذج الشركة المصنعة للمعدات الأصلية: $oemModelNumber" } التقاط { Write-Warning "لم يتم العثور على مفتاح التسجيل OEMModelNumber أو تعذر الوصول إليه" $oemModelNumber = $null Write-Host "رقم نموذج الشركة المصنعة للمعدات الأصلية: غير متوفر" }
# 12. إصدار البرنامج الثابت # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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. تحديث البرنامج الثابت # إصدار PS: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $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: الكل | مسؤول: لا | متطلبات النظام: لا شيء جرب { $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: الكل | مسؤول: قد يكون مطلوبا | متطلبات النظام: لا شيء جرب { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter # تحويل FILETIME إلى UTC DateTime — مخازن التسجيل كمخازن REG_BINARY (بايت[]) أو REG_QWORD (طويل) if ($null -ne $canAttemptUpdateAfter) { جرب { إذا ($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 المطابق (تحتاج الشركة المصنعة للمعدات الأصلية إلى توفير KEK موقع من PK) # إصدار PS: 3.0+ | مسؤول: قد تكون مطلوبة لسجل النظام | متطلبات النظام: لا شيء جرب { # الاستعلام عن جميع معرفات أحداث التمهيد الآمن ذات الصلة $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 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 "أحدث معرف حدث: غير متوفر" Write-Host "معرف المستودع: غير متوفر" Write-Host "الثقة: غير متوفرة" Write-Host "عدد الأحداث 1801: 0" Write-Host "عدد الأحداث 1808: 0" } آخر { # 16. LatestEventId $latestEvent = $events | Sort-Object TimeCreated -تنازلي | Select-Object -الأول 1 if ($null -eq $latestEvent) { Write-Warning "تعذر تحديد آخر حدث" $latestEventId = $null Write-Host "أحدث معرف حدث: غير متوفر" } آخر { $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]. Trim() Write-Host "معرف المستودع: $bucketId" } آخر { Write-Warning "لم يتم العثور على BucketId في رسالة الحدث" $bucketId = $null Write-Host "معرف المستودع: غير موجود في الحدث" } } آخر { Write-Warning "أحدث حدث أو رسالة فارغة، لا يمكن استخراج BucketId" $bucketId = $null Write-Host "معرف المستودع: غير متوفر" }
# 18. الثقة - مستخرجة من الحدث 1801/1808 if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) { if ($latestEvent.Message -match 'BucketConfidenceLevel:\s*(.+)') { $confidence = $matches[1]. Trim() Write-Host "الثقة: $confidence" } آخر { Write-Warning "لم يتم العثور على مستوى الثقة في رسالة الحدث" $confidence = $null Write-Host "الثقة: غير موجود في الحدث" } } آخر { Write-Warning "أحدث حدث أو رسالة فارغة، لا يمكن استخراج الثقة" $confidence = $null Write-Host "الثقة: غير متوفرة" }
# 18b. SkipReason - استخراج رقم KI_<> من SkipReason في نفس الحدث مثل BucketId # يلتقط هذا معرفات المشكلة المعروفة التي تظهر جنبا إلى جنب مع BucketId/Confidence (وليس الحدث 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. Event1801Count $event 1801Array = @($events | Where-Object {$_. المعرف -eq 1801}) $event 1801Count = $event 1801Array.Count Write-Host "عدد الأحداث 1801: $event 1801Count"
# 20. Event1808Count $event 1808Array = @($events | Where-Object {$_. المعرف -eq 1808}) $event 1808Count = $event 1808Array.Count Write-Host "عدد الأحداث 1808: $event 1808Count" # تهيئة متغيرات حدث الخطأ $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 # تحقق فقط من أحداث الخطأ إذا لم يكتمل التحديث # تخطي تحليل الأخطاء إذا: 1808 هو أحدث حدث أو UEFICA2023Status هو "محدث" $updateComplete = ($latestEventId -eq 1808) -أو ($uefica 2023Status -eq "Updated") إذا (-ليس $updateComplete) { Write-Host "التحديث غير مكتمل - التحقق من أحداث الخطأ..." -ForegroundColor Yellow # 21. Event1795 - خطأ في البرنامج الثابت (رمز خطأ الالتقاط) $event 1795Array = @($events | Where-Object {$_. المعرف -eq 1795}) $event 1795Count = $event 1795Array.Count إذا ($event 1795Count -gt 0) { $latestEvent 1795 = $event 1795Array | Sort-Object TimeCreated -تنازلي | Select-Object -الأول 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" $(if ($event 1795ErrorCode) { "Code: $event 1795ErrorCode" }) } # 22. Event1796 - رمز الخطأ المسجل (رمز خطأ الالتقاط) $event 1796Array = @($events | Where-Object {$_. المعرف -eq 1796}) $event 1796Count = $event 1796Array.Count if ($event 1796Count -gt 0) { $latestEvent 1796 = $event 1796Array | Sort-Object TimeCreated -تنازلي | Select-Object -الأول 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" $(if ($event 1796ErrorCode) { "Code: $event 1796ErrorCode" }) } # 23. Event1800 - إعادة التشغيل مطلوبة (ليس خطأ - سيستمر التحديث بعد إعادة التشغيل) $event 1800Array = @($events | Where-Object {$_. المعرف -eq 1800}) $event 1800Count = $event 1800Array.Count $rebootPending = $event 1800Count -gt 0 if ($rebootPending) { Write-Host "الحدث 1800 (إعادة التشغيل معلق): سيستمر التحديث بعد إعادة التشغيل" -ForegroundColor Cyan } # 24. Event1802 - مشكلة معروفة في البرنامج الثابت (التقاط رقم KI_<> من SkipReason) $event 1802Array = @($events | Where-Object {$_. المعرف -eq 1802}) $event 1802Count = $event 1802Array.Count if ($event 1802Count -gt 0) { $latestEvent 1802 = $event 1802Array | Sort-Object TimeCreated -تنازلي | Select-Object -الأول 1 if ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)') { $knownIssueId = $matches[1] } Write-Host عدد "الحدث 1802 (مشكلة البرامج الثابتة المعروفة): $event 1802Count" $(if ($knownIssueId) { "KI: $knownIssueId" }) } # 25. Event1803 - تحديث KEK مفقود (تحتاج الشركة المصنعة للمعدات الأصلية إلى توفير KEK موقع من PK) $event 1803Array = @($events | Where-Object {$_. المعرف -eq 1803}) $event 1803Count = $event 1803Array.Count $missingKEK = $event 1803Count -gt 0 if ($missingKEK) { Write-Host "الحدث 1803 (مفقود KEK): تحتاج الشركة المصنعة للمعدات الأصلية إلى توفير PK موقع KEK" -ForegroundColor Yellow } } آخر { Write-Host "Update complete (Event 1808 أو Status=Updated) - تخطي تحليل الأخطاء" -ForegroundColor Green } } } التقاط { Write-Warning "خطأ في استرداد سجلات الأحداث. قد يتطلب امتيازات المسؤول: $_" $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 "أحدث معرف حدث: خطأ" Write-Host "معرف المستودع: خطأ" Write-Host "الثقة: خطأ" Write-Host "عدد الأحداث 1801: 0" Write-Host "عدد الأحداث 1808: 0" }
# استعلامات WMI/CIM (5 قيم)
# 26. OSVersion # إصدار PS: 3.0+ (استخدم Get-WmiObject ل 2.0) | مسؤول: لا | متطلبات النظام: لا شيء جرب { $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) | مسؤول: لا | متطلبات النظام: لا شيء جرب { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop إذا ($null -eq $osInfo -أو $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 } إذا ($lastBootTime) { Write-Host "وقت التمهيد الأخير: $lastBootTime" } آخر { Write-Host "وقت التمهيد الأخير: غير متوفر" } }
# 28. BaseBoardManufacturer # إصدار PS: 3.0+ (استخدم Get-WmiObject ل 2.0) | مسؤول: لا | متطلبات النظام: لا شيء جرب { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) { Write-Warning "تعذر استرداد الشركة المصنعة لللوحة الأساسية" $baseBoardManufacturer = "غير معروف" } آخر { $baseBoardManufacturer = $baseBoard.الشركة المصنعة } Write-Host "الشركة المصنعة لللوحة الأساسية: $baseBoardManufacturer" } التقاط { # CIM قد تفشل - معلومات اللوحة الأساسية تكميلية $baseBoardManufacturer = "غير معروف" Write-Host "الشركة المصنعة لللوحة الأساسية: $baseBoardManufacturer" }
# 29. BaseBoardProduct # إصدار PS: 3.0+ (استخدم Get-WmiObject ل 2.0) | مسؤول: لا | متطلبات النظام: لا شيء جرب { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) { Write-Warning "تعذر استرداد منتج اللوحة الأساسية" $baseBoardProduct = "غير معروف" } آخر { $baseBoardProduct = $baseBoard.Product } Write-Host "Baseboard Product: $baseBoardProduct" } التقاط { # CIM قد تفشل - معلومات اللوحة الأساسية تكميلية $baseBoardProduct = "غير معروف" Write-Host "Baseboard Product: $baseBoardProduct" }
# 30. SecureBootTaskEnabled # إصدار PS: الكل | مسؤول: لا | متطلبات النظام: توجد مهمة مجدولة # التحقق مما إذا كانت المهمة المجدولة Secure-Boot-Update ممكنة $secureBootTaskEnabled = $null $secureBootTaskStatus = "غير معروف" جرب { $taskOutput = schtasks.exe /Query /TN "\Microsoft\Windows\PI\Secure-Boot-Update" /FO CSV 2>&1 إذا ($LASTEXITCODE -eq 0) { $taskData = $taskOutput | ConvertFrom-Csv إذا ($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 Yellow } آخر { Write-Host "مهمة تحديث SecureBoot: $secureBootTaskStatus (ممكن: $secureBootTaskEnabled)" -ForegroundColor Green } } التقاط { $secureBootTaskStatus = "خطأ" $secureBootTaskEnabled = $false Write-Host "مهمة تحديث SecureBoot: تدقيق الأخطاء - $_" -ForegroundColor Red }
# 31. حالة مفتاح WinCS (F33E0C8E002 - تحديث شهادة التمهيد الآمن) # إصدار PS: الكل | مسؤول: نعم (للاستعلام) | متطلبات النظام: 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 } } إذا ($wincsFlagsPath) { # Query specific key - يتطلب حقوق المسؤول $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1 $queryOutputStr = $queryOutput -join "'n" if ($LASTEXITCODE -eq 0) { # تحقق مما إذا تم تطبيق المفتاح (ابحث عن "التكوين النشط" أو مؤشر مشابه) إذا ($queryOutputStr -match "Active Configuration.*:.*enabled" -أو $queryOutputStr -match "Configuration.*applied") { $wincsKeyApplied = $true $wincsKeyStatus = "مطبق" Write-Host "مفتاح WinCS F33E0C8E002: Applied" -ForegroundColor Green } elseif ($queryOutputStr -match "not found|لا يوجد تكوين") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "مفتاح WinCS F33E0C8E002: غير مطبق" -ForegroundColor Yellow } آخر { # المفتاح موجود - تحقق من الإخراج للحالة $wincsKeyApplied = $true $wincsKeyStatus = "مطبق" Write-Host "مفتاح WinCS F33E0C8E002: مطبق" -ForegroundColor Green } } آخر { # تحقق من وجود رسائل خطأ محددة إذا ($queryOutputStr -match "تم رفض الوصول|المسؤول") { $wincsKeyStatus = "AccessDenied" Write-Host "مفتاح WinCS F33E0C8E002: تم رفض الوصول (تشغيل كمسؤول)" -ForegroundColor DarkGray } elseif ($queryOutputStr -match "not found|لا يوجد تكوين") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "مفتاح WinCS F33E0C8E002: غير مطبق" -ForegroundColor أصفر } آخر { $wincsKeyStatus = "QueryFailed" Write-Host "F33E0C8E002 مفتاح WinCS: فشل الاستعلام" -ForegroundColor Red } } } آخر { $wincsKeyStatus = "WinCsFlagsNotFound" Write-Host "F33E0C8E002 مفتاح WinCS: لم يتم العثور على WinCsFlags.exe" -ForegroundColor Gray } } التقاط { $wincsKeyStatus = "خطأ" Write-Host "مفتاح WinCS F33E0C8E002: تدقيق الأخطاء - $_" -ForegroundColor Red }
# ============================================================================= # الكشف عن المعالجة - إخراج الحالة & التعليمات البرمجية للخروج # =============================================================================
# إنشاء كائن حالة من جميع بيانات المخزون التي تم جمعها $status = [ordered]@{ UEFICA2023Status = $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 CollectionTime = if ($collectionTime -is [datetime]) { $collectionTime.ToString("o") } else { "$collectionTime" } SecureBootEnabled = $secureBootEnabled HighConfidenceOptOut = $highConfidenceOptOut MicrosoftUpdateManagedOptIn = $microsoftUpdateManagedOptIn OEMManufacturerName = $oemManufacturerName OEMModelSystemFamily = $oemModelSystemFamily OEMModelNumber = $oemModelNumber إصدار البرنامج الثابت = $firmwareVersion FirmwareReleaseDate = $firmwareReleaseDate OSArchitecture = $osArchitecture CanAttemptUpdateAfter = if ($canAttemptUpdateAfter -is [datetime]) { $canAttemptUpdateAfter.ToString("o") } else { "$canAttemptUpdateAfter" } LatestEventId = $latestEventId معرف المستودع = $bucketId الثقة = $confidence SkipReasonKnownIssue = $skipReasonKnownIssue # KI_<رقم> من SkipReason في حدث BucketId Event1801Count = $event 1801Count Event1808Count = $event 1808Count # أحداث الخطأ مع التفاصيل الملتقطة حدث1795Count = خطأ $event 1795Count # البرنامج الثابت الذي تم إرجاعه Event1795ErrorCode = $event 1795ErrorCode # رمز الخطأ من البرنامج الثابت Event1796Count = $event 1796Count # رمز الخطأ المسجل Event1796ErrorCode = $event 1796ErrorCode # رمز الخطأ الملتقط Event1800Count = $event 1800Count # Reboot مطلوبة (ليس خطأ) إعادة التشغيل معلق = $rebootPending # True إذا كان الحدث 1800 موجودا Event1802Count = $event 1802Count # مشكلة البرامج الثابتة المعروفة KnownIssueId = $knownIssueId # KI_<رقم> من SkipReason Event1803Count = $event 1803Count # Missing KEK update MissingKEK = $missingKEK # OEM يحتاج إلى توفير KEK موقع من PK 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 - تخطي إذا كان يبدو وكأنه طلب مساعدة أو يحتوي على حرف غير صالح إذا ($OutputPath -match '^[/\-]' -أو $OutputPath -match '[<>:"|؟ *]') { Write-Host "تم تحديد OutputPath غير صالح، الإخراج إلى stdout" -ForegroundColor Yellow Write-Output $jsonOutput if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") { exit 0 } else { exit 1 } } # تأكد من وجود مجلد الإخراج if (-not (test-Path $OutputPath)) { جرب { New-Item -ItemType Directory -Path $OutputPath -Force | خارج فارغة } التقاط { Write-Warning "تعذر إنشاء مجلد الإخراج: $OutputPath - $_" } } # حفظ إلى HOSTNAME_latest.json $outputFile = Join-Path $OutputPath "$($hostname)_latest.json" جرب { $jsonOutput | Out-File -FilePath $outputFile -ترميز UTF8 -Force Write-Host "حفظ JSON إلى: $outputFile" -ForegroundColor Green } التقاط { Write-Warning "تعذر الكتابة إلى ملف: $outputFile - $_" # العودة إلى stdout Write-Output $jsonOutput } } آخر { # السلوك الأصلي - الإخراج إلى stdout Write-Output $jsonOutput }
# Exit code: "Updated" هي قيمة النجاح لكل دليل المبادئ if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") { إنهاء 0 # بدون مشكلة } آخر { الخروج 1 # مع المشكلة }