Kopioi ja liitä tämä esimerkkikomentosarja ja muokkaa sitä tarpeen mukaan ympäristössäsi:
<# . SYNOPSIS Tunnistaa suojatun käynnistyksen varmenteen päivityksen tilan koko kalustoa kattavaa valvontaa varten.
.DESCRIPTION Tämä tunnistuskomentosarja kerää suojatun käynnistyksen tilan, varmenteen päivityksen rekisteriarvot, ja laitteen tiedot. Se lähettää JSON-merkkijonon seurantaa ja raportointia varten.
Compatible with Intune Remediations, GPO-based collection, and other management tools. Korjauskomentosarjaa ei tarvita– tämä on vain seurantaa.
Exit 0 = "Without issue" (certificates updated) Exit 1 = "With issue" (varmenteet eivät päivity – vain tiedoksi)
.PARAMETER OutputPath Valinnainen. Polku kansioon, johon JSON-tiedosto tallennetaan.Jos tämä on annettu, HOSTNAME_latest.json tallennetaan tähän kansioon.Jos sitä ei anneta, tulostetaan JSON stdout-muotoon (alkuperäinen toiminta).
.EXAMPLE # Lähtö stdout(Intune/SCCM tunnistus) .\Detect-SecureBootCertUpdateStatus.ps1
.EXAMPLE # Tallenna jaettuun verkkoresurssiin (ryhmäkäytäntöobjektin käyttöönotto) .\Detect-SecureBootCertUpdateStatus.ps1 -OutputPath "\\server\SecureBootLogs$"
.NOTES Rekisteripolut https://aka.ms/securebootplaybook kohti: HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR OLETETTU, MUKAAN LUKIEN MUUN MUASSA TAKUUT SOVELTUVUUDESTA KAUPANKÄYNNIN KOHTEEKSI, SOVELTUVUUS TIETTYYN TARKOITUKSEEN JA LOUKKAAMATTOMAAN. EI MISSÄÄN TAPAUKSESSA SAA TEKIJÄT TAI TEKIJÄNOIKEUKSIEN HALTIJAT OVAT VASTUUSSA KAIKISTA VAATEISTA, VAHINGOISTA TAI MUISTA VASTUU, RIIPPUMATTA SIITÄ, ONKO KYSEESSÄ SOPIMUS, VAHINGONKORVAUS TAI MUU, OHJELMISTOSTA TAI SEN KÄYTÖSTÄ TAI MUUSTA TOIMINNASTA OHJELMISTO.#> param( [Parameter(Mandatory = $false)] [merkkijono]$OutputPath )
# Download URL: https://aka.ms/getsecureboot -> "Deployment and Monitoring Samples" # Huomautus: Tämä komentosarja suoritetaan päätepisteissä suojatun käynnistyksen tilatietojen keräämiseksi.
# 1. HostName # PS-versio: Kaikki | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $hostname = $env:COMPUTERNAME if ([string]::IsNullOrEmpty($hostname)) { Write-Warning "Isäntänimeä ei voitu määrittää" $hostname = "Tuntematon" } Write-Host "Isäntänimi: $hostname" } saalis { Write-Warning "Virhe haettaessa isäntänimeä: $_" $hostname = "Virhe" Write-Host "Isäntänimi: $hostname" }
# 2. CollectionTime # PS-versio: Kaikki | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $collectionTime = Get-Date if ($null -eq $collectionTime) { Write-Warning "Nykyistä päivämäärää/kellonaikaa ei voitu noutaa" $collectionTime = "Tuntematon" } Write-Host "Kokoelma-aika: $collectionTime" } saalis { Write-Warning "Virhe haettaessa päivämäärää ja kellonaikaa: $_" $collectionTime = "Virhe" Write-Host "Keräysaika: $collectionTime" }
# Registry: Secure Boot Main Key (3 values)
# 3. SecureBootEnabled # PS-versio: 3.0+ | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: UEFI/Secure Boot capable system kokeile { $secureBootEnabled = Confirm-SecureBootUEFI -ErrorAction Stop Write-Host "Suojattu käynnistys käytössä: $secureBootEnabled" } saalis { Write-Warning "Suojatun käynnistyksen tilaa ei voi määrittää cmdlet-komennolla: $_" # Kokeile rekisterin varaystä kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name UEFISecureBootEnabled -ErrorAction Stop $secureBootEnabled = [bool]$regValue.UEFISecureBootEnabled Write-Host "Suojattu käynnistys käytössä: $secureBootEnabled" } saalis { Write-Warning "Suojatun käynnistyksen tilaa ei voi määrittää rekisterin kautta. Järjestelmä ei ehkä tue UEFI/Secure Boot -käynnistystä." $secureBootEnabled = $null Write-Host "Suojattu käynnistys käytössä: ei käytettävissä" } }
# 4. HighConfidenceOptOut # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name HighConfidenceOptOut -ErrorAction Stop $highConfidenceOptOut = $regValue.HighConfidenceOptOut Write-Host "High Confidence Opt Out: $highConfidenceOptOut" } saalis { # HighConfidenceOptOut on valinnainen – ei ole useimmissa järjestelmissä $highConfidenceOptOut = $null Write-Host "High Confidence Opt Out: Not Set" }
# 4b. MicrosoftUpdateManagedOptIn # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name MicrosoftUpdateManagedOptIn -ErrorAction Stop $microsoftUpdateManagedOptIn = $regValue.MicrosoftUpdateManagedOptIn Write-Host "Microsoft Update Managed Opt In: $microsoftUpdateManagedOptIn" } saalis { # MicrosoftUpdateManagedOptIn on valinnainen – ei ole useimmissa järjestelmissä $microsoftUpdateManagedOptIn = $null Write-Host "Microsoft Update Managed Opt In: Not Set" }
# 5. AvailableUpdates # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdates -ErrorAction Stop $availableUpdates = $regValue.AvailableUpdates jos ($null -ne $availableUpdates) { # Muunna heksadesimaalimuotoon $availableUpdatesHex = "0x{0:X}" -f $availableUpdates Write-Host "Käytettävissä olevat Päivitykset: $availableUpdatesHex" } muu { Write-Host "Käytettävissä olevat Päivitykset: ei käytettävissä" } } saalis { Write-Warning "AvailableUpdates registry key not found or inaccessible" $availableUpdates = $null Write-Host "Käytettävissä Päivitykset: ei käytettävissä" }
# 5b. AvailableUpdatesPolicy (GPO-controlled persistent value) # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot" -Name AvailableUpdatesPolicy -ErrorAction Stop $availableUpdatesPolicy = $regValue.AvailableUpdatesPolicy jos ($null -ne $availableUpdatesPolicy) { # Muunna heksadesimaalimuotoon $availableUpdatesPolicyHex = "0x{0:X}" -f $availableUpdatesPolicy Write-Host Käytettävissä Päivitykset käytäntö: $availableUpdatesPolicyHex } muu { Write-Host "Käytettävissä Päivitykset käytäntö: ei määritetty" } } saalis { # AvailableUpdatesPolicy on valinnainen – määritetty vain silloin, kun ryhmäkäytäntöobjektia käytetään $availableUpdatesPolicy = $null Write-Host "Käytettävissä Päivitykset käytäntö: ei määritetty" }
# Registry: Servicing Key (3 values)
# 6. UEFICA2023Status # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Status -ErrorAction Stop $uefica 2023Status = $regValue.UEFICA2023Status Write-Host "Windows UEFI CA 2023 Status: $uefica 2023Status" } saalis { Write-Warning "Windows UEFI CA 2023 Status registry key not found or inaccessible" $uefica 2023Status = $null Write-Host "Windows UEFI CA 2023 Status: Not Available" }
# 7. UEFICA2023Error # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023Error -ErrorAction Stop $uefica 2023Virhe = $regValue.UEFICA2023Virhe Write-Host "UEFI CA 2023 -virhe: $uefica 2023Virhe" } saalis { # UEFICA2023Virhe on olemassa vain, jos tapahtui virhe - poissaolo on hyvä $uefica 2023Virhe = $null Write-Host "UEFI CA 2023 Error: None" }
# 8. UEFICA2023ErrorEvent # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing" -Name UEFICA2023ErrorEvent -ErrorAction Stop $uefica 2023ErrorEvent = $regValue.UEFICA2023ErrorEvent Write-Host "UEFI CA 2023 -virhetapahtuma: $uefica 2023ErrorEvent" } saalis { $uefica 2023ErrorEvent = $null Write-Host "UEFI CA 2023 Error Event: Not Available" }
# Registry: Device Attributes (7 values: 9-15)
# 9. OEMManufacturerName # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $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 is empty" $oemManufacturerName = "Tuntematon" } Write-Host "OEM-valmistajan nimi: $oemManufacturerName" } saalis { Write-Warning "OEMManufacturerName registry key not found or inaccessible" $oemManufacturerName = $null Write-Host "OEM Manufacturer Name: Not Available" }
# 10. OEMModelSystemFamily # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelSystemFamily -ErrorAction Stop $oemModelSystemFamily = $regValue.OEMModelSystemFamily if ([string]::IsNullOrEmpty($oemModelSystemFamily)) { Write-Warning "OEMModelSystemFamily is empty" $oemModelSystemFamily = "Tuntematon" } Write-Host "OEM Model System Family: $oemModelSystemFamily" } saalis { Write-Warning "OEMModelSystemFamily registry key not found or inaccessible" $oemModelSystemFamily = $null Write-Host "OEM Model System Family: Not Available" }
# 11. OEMModelNumber # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OEMModelNumber -ErrorAction Stop $oemModelNumber = $regValue.OEMModelNumber if ([string]::IsNullOrEmpty($oemModelNumber)) { Write-Warning "OEMModelNumber is empty" $oemModelNumber = "Tuntematon" } Write-Host "OEM Model Number: $oemModelNumber" } saalis { Write-Warning "OEMModelNumber registry key not found or inaccessible" $oemModelNumber = $null Write-Host "OEM Model Number: Not Available" }
# 12. FirmwareVersion # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name FirmwareVersion -ErrorAction Stop $firmwareVersion = $regValue.FirmwareVersion if ([string]::IsNullOrEmpty($firmwareVersion)) { Write-Warning "Laiteohjelmiston versio on tyhjä" $firmwareVersion = "Tuntematon" } Write-Host "Laiteohjelmistoversio: $firmwareVersion" } saalis { Write-Warning "FirmwareVersion-rekisteriavainta ei löydy tai ei ole käytettävissä" $firmwareVersion = $null Write-Host "Laiteohjelmistoversio: ei saatavilla" }
# 13. FirmwareReleaseDate # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $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 is empty" $firmwareReleaseDate = "Tuntematon" } Write-Host "Laiteohjelmiston julkaisupäivä: $firmwareReleaseDate" } saalis { Write-Warning "FirmwareReleaseDate registry key not found or inaccessible" $firmwareReleaseDate = $null Write-Host "Laiteohjelmiston julkaisupäivä: ei saatavilla" }
# 14. OSArchitecture # PS-versio: Kaikki | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $osArchitecture = $env:PROCESSOR_ARCHITECTURE if ([string]::IsNullOrEmpty($osArchitecture)) { # Kokeile rekisterin varaystä $regValue = Get-ItemProperty -Polku "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name OSArchitecture -ErrorAction Stop $osArchitecture = $regValue.OSArchitecture } if ([string]::IsNullOrEmpty($osArchitecture)) { Write-Warning "OSArchitecturea ei voitu määrittää" $osArchitecture = "Tuntematon" } Write-Host käyttöjärjestelmän arkkitehtuuri: $osArchitecture } saalis { Write-Warning "Virhe osarkkitentuurin noutamisessa: $_" $osArchitecture = "Tuntematon" Write-Host käyttöjärjestelmäarkkitehtuuri: $osArchitecture }
# 15. CanAttemptUpdateAfter (FILETIME) # PS-versio: Kaikki | Hallinta: Saatetaan tarvita | Järjestelmävaatimukset: Ei mitään kokeile { $regValue = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\Servicing\DeviceAttributes" -Name CanAttemptUpdateAfter -ErrorAction Stop $canAttemptUpdateAfter = $regValue.CanAttemptUpdateAfter # Muunna FILETIME UTC DateTimeksi – rekisterisäilöt ovat REG_BINARY (tavu[]) tai REG_QWORD (pitkä) jos ($null -ne $canAttemptUpdateAfter) { kokeile { jos ($canAttemptUpdateAfter -is [tavu[]]) { $fileTime = [BitConverter]::ToInt64($canAttemptUpdateAfter, 0) $canAttemptUpdateAfter = [DateTime]::FromFileTime($fileTime). ToUniversalTime() } elseif ($canAttemptUpdateAfter -is [long]) { $canAttemptUpdateAfter = [DateTime]::FromFileTime($canAttemptUpdateAfter). ToUniversalTime() } } saalis { Write-Warning "CanAttemptUpdatea ei voitu muuntaaTiedostonajan jälkeen DateTimeksi" } } Write-Host "Can attempt Update After: $canAttemptUpdateAfter" } saalis { Write-Warning "CanAttemptUpdateAfter registry key not found or inaccessible" $canAttemptUpdateAfter = $null Write-Host "Can attempt Update After: Not Available" }
# Event Logs: System Log (10 values: 16-25)
# 16-25. Event Log queries # Tapahtumatunnukset: # 1801 - Päivitys aloitettu, uudelleenkäynnistys vaaditaan # 1808 - Päivitys onnistui # 1795 - Laiteohjelmiston palauttama virhe (sieppausvirhekoodi) # 1796 - Virhe kirjattu virhekoodilla (sieppauskoodi) # 1800 - Tarvitaan uudelleenkäynnistys (EI virhettä - päivitys jatkuu uudelleenkäynnistyksen jälkeen) # 1802 - Tunnettu laiteohjelmisto-ongelma estetty päivitys (sieppaa KI_<numero> SkipReasonista) # 1803 - Vastaavaa KEK-päivitystä ei löydy (alkuperäisen laitevalmistajan on toimitettava PK-allekirjoitettu KEK) # PS-versio: 3.0+ | Hallinta: Järjestelmäloki saattaa edellyttää | Järjestelmävaatimukset: Ei mitään kokeile { # Kysely kaikista asianmukaisista suojatun käynnistyksen tapahtumatunnuksista $allEventIds = @(1795, 1796, 1800, 1801, 1802, 1803, 1808) $events = @(Get-WinEvent -FilterHashtable @{LogName='System'; ID=$allEventIds} -MaxEvents 50 -ErrorAction Stop)
if ($events.Count -eq 0) { Write-Warning "Järjestelmälokista ei löytynyt suojatun käynnistyksen tapahtumia" $latestEventId = $null $bucketId = $null $confidence = $null $skipReasonKnownIssue = $null $event 1801Laske = 0 $event 1808Laske = 0 $event 1795Laske = 0 $event 1795Virhekoodi = $null $event 1796Laske = 0 $event 1796ErrorCode = $null $event 1800Laske = 0 $rebootPending = $false $event 1802Laske = 0 $knownIssueId = $null $event 1803Laske = 0 $missingKEK = $false Write-Host "Viimeisin tapahtumatunnus: ei käytettävissä" Write-Host "Säilön tunnus: ei käytettävissä" Write-Host "Luottamus: ei käytettävissä" Write-Host "Tapahtuman 1801 määrä: 0" Write-Host "Tapahtuma 1808 Määrä: 0" } muu { # 16. LatestEventId $latestEvent = $events | Sort-Object TimeCreated -Descending | Select-Object -Ensimmäinen 1 jos ($null -eq $latestEvent) { Write-Warning "Viimeisintä tapahtumaa ei voitu määrittää" $latestEventId = $null Write-Host "Viimeisin tapahtumatunnus: ei käytettävissä" } muu { $latestEventId = latestEvent.Id $ Write-Host "Viimeisin tapahtumatunnus: $latestEventId" }
# 17. BucketID - Extracted from Event 1801/1808 if ($null -ne $latestEvent -and $null -ne $latestEvent.Message) { if ($latestEvent.Message -match 'BucketId:\s*(.+)') { $bucketId = $matches[1]. Rajaa() Write-Host "Säilön tunnus: $bucketId" } muu { Write-Warning "BucketId not found in event message" $bucketId = $null Write-Host "Säilön tunnus: ei löydy tapahtumasta" } } muu { Write-Warning "Viimeisin tapahtuma tai viesti on tyhjäarvo, ei voi poimia BucketId". $bucketId = $null Write-Host "Säilön tunnus: ei käytettävissä" }
# 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]. Rajaa() Write-Host "Luottamus: $confidence" } muu { Write-Warning "Luottamustasoa ei löydy tapahtumaviestistä" $confidence = $null Write-Host "Luottamus: ei löydy tapahtumasta" } } muu { Write-Warning "Viimeisin tapahtuma tai viesti on tyhjäarvo, luottamusväliä ei voi poimia" $confidence = $null Write-Host "Luottamus: ei käytettävissä" }
# 18b. SkipReason - Extract KI_<number> from SkipReason in the same event as BucketId # Tämä tallentaa Tunnetut ongelmatunnukset, jotka näkyvät BucketId/Confidence -toiminnon rinnalla (ei vain tapahtuma 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 {$_. Tunnus -eq 1801}) $event 1801Laske = $event 1801Array.Count Write-Host "Tapahtuman 1801 määrä: $event 1801Laske"
# 20. Event1808Count $event 1808Array = @($events | Where-Object {$_. Tunnus -eq 1808}) $event 1808Laske = $event 1808Array.Count Write-Host "Tapahtuman 1808 määrä: $event 1808Laske" # Initialize error event variables $event 1795Laske = 0 $event 1795Virhekoodi = $null $event 1796Laske = 0 $event 1796ErrorCode = $null $event 1800Laske = 0 $rebootPending = $false $event 1802Laske = 0 $knownIssueId = $null $event 1803Laske = 0 $missingKEK = $false # Tarkista virhetapahtumat vain, jos päivitys ei ole valmis # Ohita virheanalyysi, jos: 1808 on uusin tapahtuma TAI UEFICA2023Status on "Päivitetty" $updateComplete = ($latestEventId -eq 1808) -tai ($uefica 2023Status -eq "Päivitetty") jos (ei $updateComplete) { Write-Host "Update not complete - checking for error events..." -ForegroundColor Yellow # 21. Tapahtuma1795 – Laiteohjelmistovirhe (sieppausvirhekoodi) $event 1795Array = @($events | Where-Object {$_. Tunnus -eq 1795}) $event 1795Laske = $event 1795Array.Count jos ($event 1795Laske -gt 0) { $latestEvent 1795 = $event 1795Array | Sort-Object TimeCreated -Descending | Select-Object -Ensimmäinen 1 if ($latestEvent 1795.Message -match '(?:error|code|status)[:\s]*(?:0x)?( [0-9A-Fa-f]{8}|[0-9A-Fa-f]+)') { $event 1795Virhekoodi = $matches[1] } Write-Host "Event 1795 (Firmware Error) Count: $event 1795Count" $(if ($event 1795ErrorCode) { "Code: $event 1795ErrorCode" }) } # 22. Tapahtuma1796 – Virhekoodi kirjattu (sieppausvirhekoodi) $event 1796Array = @($events | Where-Object {$_. Tunnus -eq 1796}) $event 1796Laske = $event 1796Array.Count jos ($event 1796Laske -gt 0) { $latestEvent 1796 = $event 1796Array | Sort-Object TimeCreated -Descending | Select-Object -Ensimmäinen 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 "Event 1796 (Error Logged) Count: $event 1796Count" $(if ($event 1796ErrorCode) { "Code: $event 1796ErrorCode" }) } # 23. Event1800 - Reboot Needed (NOT an error - update will will proceed after reboot) $event 1800Array = @($events | Where-Object {$_. Tunnus -eq 1800}) $event 1800Laske = $event 1800Array.Count $rebootPending = $event 1800Laske -gt 0 jos ($rebootPending) { Write-Host "Tapahtuma 1800 (Uudelleenkäynnistys odottaa): Päivitys jatkuu uudelleenkäynnistyksen jälkeen" -ForegroundColor Cyan } # 24. Event1802 – Tunnettu laiteohjelmisto-ongelma (sieppaa KI_<numero> SkipReasonista) $event 1802Array = @($events | Where-Object {$_. Tunnus -eq 1802}) $event 1802Laske = $event 1802Array.Count jos ($event 1802Laske -gt 0) { $latestEvent 1802 = $event 1802Array | Sort-Object TimeCreated -Descending | Select-Object -Ensimmäinen 1 jos ($latestEvent 1802.Message -match 'SkipReason:\s*(KI_\d+)') { $knownIssueId = $matches[1] } Write-Host "Tapahtuma 1802 (tunnettu laiteohjelmistoongelma) Määrä: $event 1802Laske" $(jos ($knownIssueId) { "KI: $knownIssueId" }) } # 25. Event1803 – Puuttuva KEK-päivitys (alkuperäisen laitevalmistajan on toimitettava PK-allekirjoitettu KEK) $event 1803Array = @($events | Where-Object {$_. Tunnus -eq 1803}) $event 1803Laske = $event 1803Array.Count $missingKEK = $event 1803Laske -gt 0 jos ($missingKEK) { Write-Host "Event 1803 (Missing KEK): OEM needs to supply PK signed KEK" -ForegroundColor Yellow } } muu { Write-Host "Päivitys valmis (tapahtuma 1808 tai Tila=Päivitetty) - ohitusvirheanalyysi" -EtualallaColor Green } } } saalis { Write-Warning "Virhe noudettaessa tapahtumalokeja. Voi edellyttää järjestelmänvalvojan oikeuksia: $_" $latestEventId = $null $bucketId = $null $confidence = $null $skipReasonKnownIssue = $null $event 1801Laske = 0 $event 1808Laske = 0 $event 1795Laske = 0 $event 1795ErrorCode = $null $event 1796Laske = 0 $event 1796ErrorCode = $null $event 1800Laske = 0 $rebootPending = $false $event 1802Laske = 0 $knownIssueId = $null $event 1803Laske = 0 $missingKEK = $false Write-Host "Viimeisin tapahtumatunnus: virhe" Write-Host "Säilön tunnus: virhe" Write-Host "Luottamus: virhe" Write-Host "Tapahtuman 1801 määrä: 0" Write-Host "Tapahtuma 1808 Määrä: 0" }
# WMI/CIM Queries (5 values)
# 26. OSVersion # PS-versio: 3.0+ (käytä Get-WmiObject 2.0:lle) | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop if ($null -eq $osInfo -or [string]::IsNullOrEmpty($osInfo.Version)) { Write-Warning "Käyttöjärjestelmän versiota ei voitu noutaa" $osVersion = "Tuntematon" } muu { $osVersion = $osInfo.Versio } Write-Host käyttöjärjestelmän versio: $osVersion } saalis { # CIM voi epäonnistua joissakin ympäristöissä – käytä vara-toimintoa $osVersion = [System.Environment]::OSVersion.Version.ToString() if ([string]::IsNullOrEmpty($osVersion)) { $osVersion = "Unknown" } Write-Host käyttöjärjestelmän versio: $osVersion }
# 27. LastBootTime # PS-versio: 3.0+ (käytä Get-WmiObject 2.0:lle) | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop jos ($null -eq $osInfo -tai $null -eq $osInfo.LastBootUpTime) { Write-Warning "Viimeisintä käynnistysaikaa ei voitu noutaa" $lastBootTime = $null Write-Host "Viimeinen käynnistysaika: ei käytettävissä" } muu { $lastBootTime = $osInfo.LastBootUpTime Write-Host "Viimeinen käynnistysaika: $lastBootTime" } } saalis { # CIM voi epäonnistua joissakin ympäristöissä – käytä vara-toimintoa kokeile { $lastBootTime = (Get-Process -Id 0 -ErrorAction SilentlyContinue). StartTime } saalis { $lastBootTime = $null } if ($lastBootTime) { Write-Host "Last Boot Time: $lastBootTime" } muu { Write-Host "Last Boot Time: Not Available" } }
# 28. BaseBoardManufacturer # PS-versio: 3.0+ (käytä Get-WmiObject 2.0:lle) | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Manufacturer)) { Write-Warning "Peruslevyn valmistajaa ei voitu noutaa" $baseBoardManufacturer = "Tuntematon" } muu { $baseBoardManufacturer = $baseBoard.Manufacturer } Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" } saalis { # CIM voi epäonnistua - perustaulun tiedot ovat täydentäviä $baseBoardManufacturer = "Tuntematon" Write-Host "Baseboard Manufacturer: $baseBoardManufacturer" }
# 29. BaseBoardProduct # PS-versio: 3.0+ (käytä Get-WmiObject 2.0:lle) | Hallinta: Ei | Järjestelmävaatimukset: Ei mitään kokeile { $baseBoard = Get-CimInstance Win32_BaseBoard -ErrorAction Stop if ($null -eq $baseBoard -or [string]::IsNullOrEmpty($baseBoard.Product)) { Write-Warning "Peruslevytuotetta ei voitu noutaa" $baseBoardProduct = "Tuntematon" } muu { $baseBoardProduct = $baseBoard.Product } Write-Host "Baseboard Product: $baseBoardProduct" } saalis { # CIM voi epäonnistua - perustaulun tiedot ovat täydentäviä $baseBoardProduct = "Tuntematon" Write-Host "Baseboard Product: $baseBoardProduct" }
# 30. SecureBootTaskEnabled # PS-versio: Kaikki | Hallinta: Ei | Järjestelmävaatimukset: Ajoitettu tehtävä on olemassa # Tarkistaa, onko ajoitettu Secure-Boot-Update -tehtävä käytössä $secureBootTaskEnabled = $null $secureBootTaskStatus = "Tuntematon" kokeile { $taskOutput = schtasks.exe /Query /TN "\Microsoft\Windows\PI\Secure-Boot-Update" /FO CSV 2>&1 jos ($LASTEXITCODE -eq 0) { $taskData = $taskOutput | ConvertFrom-Csv jos ($taskData) { $secureBootTaskStatus = $taskData.Status $secureBootTaskEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running') } } muu { $secureBootTaskStatus = "NotFound" $secureBootTaskEnabled = $false } jos ($secureBootTaskEnabled -eq $false) { Write-Host "SecureBoot Update Task: $secureBootTaskStatus (Käytössä: $secureBootTaskEnabled)" -EtualallaColor Keltainen } muu { Write-Host "SecureBoot-päivitystehtävä: $secureBootTaskStatus (käytössä: $secureBootTaskEnabled)" -EdustaVäri vihreä } } saalis { $secureBootTaskStatus = "Virhe" $secureBootTaskEnabled = $false Write-Host "SecureBoot Update Task: Error checking - $_" -ForegroundColor Red }
# 31. WinCS Key Status (F33E0C8E002 - Secure Boot Certificate Update) # PS-versio: Kaikki | Hallinta: Kyllä (kyselyä varten) | Järjestelmävaatimukset: WinCsFlags.exe $wincsKeyApplied = $null $wincsKeyStatus = "Tuntematon" kokeile { # Tarkista WinCsFlags.exe yleiset sijainnit $wincsFlagsPath = $null $possiblePaths = @( "$env:SystemRoot\System32\WinCsFlags.exe", "$env:SystemRoot\SysWOW64\WinCsFlags.exe" ) foreach ($p in $possiblePaths) { if (Test-Path $p) { $wincsFlagsPath = $p; break } } jos ($wincsFlagsPath) { # Kyselykohtainen avain – edellyttää järjestelmänvalvojan oikeuksia $queryOutput = & $wincsFlagsPath /query --key F33E0C8E002 2>&1 $queryOutputStr = $queryOutput -join "'n" jos ($LASTEXITCODE -eq 0) { # Tarkista, onko avain käytössä (etsi Active Configuration tai vastaava ilmaisin) jos ($queryOutputStr -match "Active Configuration.*:.*enabled" -or $queryOutputStr -match "Configuration.*applied") { $wincsKeyApplied = $true $wincsKeyStatus = "Käytetty" Write-Host "WinCS Key F33E0C8E002: Applied" -ForegroundColor Green } elseif ($queryOutputStr -match "not found|Ei kokoonpanoa") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "WinCS Key F33E0C8E002: Not Applied" -ForegroundColor Yellow } muu { # Avain on olemassa - tarkista tulos tilan mukaan $wincsKeyApplied = $true $wincsKeyStatus = "Käytetty" Write-Host "WinCS Key F33E0C8E002: Applied" -ForegroundColor Green } } muu { # Tarkista tietyt virhesanomat jos ($queryOutputStr -match "Käyttö estetty|järjestelmänvalvoja") { $wincsKeyStatus = "Käyttö estetty" Write-Host "WinCS Key F33E0C8E002: Access denied (suorita järjestelmänvalvojana)" -ForegroundColor DarkGray } elseif ($queryOutputStr -match "not found|Ei kokoonpanoa") { $wincsKeyApplied = $false $wincsKeyStatus = "NotApplied" Write-Host "WinCS Key F33E0C8E002: Not Applied" -ForegroundColor Yellow } muu { $wincsKeyStatus = "Kysely epäonnistui" Write-Host "WinCS-näppäin F33E0C8E002: kysely epäonnistui" -Edustaväri Punainen } } } muu { $wincsKeyStatus = "WinCsFlagsNotFound" Write-Host "WinCS Key F33E0C8E002: WinCsFlags.exe not found" -ForegroundColor Gray } } saalis { $wincsKeyStatus = "Virhe" Write-Host "WinCS Key F33E0C8E002: Error checking - $_" -ForegroundColor Red }
# ============================================================================= # Korjauksen tunnistus – tilalähtö & lopetuskoodi # =============================================================================
# Build status object from all collected inventory data $status = [ordered]@{ UEFICA2023Status = $uefica 2023Status UEFICA2023Error = $uefica 2023Virhe UEFICA2023ErrorEvent = $uefica 2023ErrorEvent AvailableUpdates = if ($null -ne $availableUpdates) { $availableUpdatesHex } else { $null } AvailableUpdatesPolicy = if ($null -ne $availableUpdatesPolicy) { $availableUpdatesPolicyHex } muu { $null } Hostname = $hostname CollectionTime = if ($collectionTime -is [datetime]) { $collectionTime.ToString("o") } muu { "$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") } muu { "$canAttemptUpdateAfter" } LatestEventId = $latestEventId BucketId = $bucketId Luottamus = $confidence SkipReasonKnownIssue = $skipReasonKnownIssue # KI_<numero> SkipReason in BucketId -tapahtumasta Event1801Count = $event 1801Count Event1808Count = $event 1808Laske # Virhetapahtumat, joissa on tallennettuja tietoja Event1795Count = $event 1795Count # Laiteohjelmisto palautettu -virhe Event1795ErrorCode = $event 1795ErrorCode # Virhekoodi laiteohjelmistosta Tapahtuma1796Laske = $event 1796Laske # Virhekoodi kirjattu Event1796ErrorCode = $event 1796ErrorCode # Siepattu virhekoodi Event1800Count = $event 1800Count # Reboot needed (NOT an error) RebootPending = $rebootPending # True if Event 1800 present Event1802Count = $event 1802Laske # Tunnettu laiteohjelmisto-ongelma KnownIssueId = $knownIssueId # KI_<luku> SkipReasonista Event1803Count = $event 1803Count # Missing KEK update MissingKEK = $missingKEK # OEM needs to supply PK signed KEK OSVersion = $osVersion LastBootTime = jos ($lastBootTime -is [datetime]) { $lastBootTime.ToString("o") } muu { "$lastBootTime" } BaseBoardManufacturer = $baseBoardManufacturer BaseBoardProduct = $baseBoardProduct SecureBootTaskEnabled = $secureBootTaskEnabled SecureBootTaskStatus = $secureBootTaskStatus WinCSKeyApplied = $wincsKeyApplied # True, jos F33E0C8E002-näppäintä käytetään WinCSKeyStatus = $wincsKeyStatus # Applied, NotApplied, WinCsFlagsNotFound jne. }
# Output the status - For data aggregation $jsonOutput = $status | ConvertTo-Json -Compress
# If OutputPath provided, save to file; otherwise output to stdout if (-not [string]::IsNullOrEmpty($OutputPath)) { # Validate OutputPath - ohita, jos se näyttää ohjepyynnöltä tai siinä on virheellisiä merkkejä jos ($OutputPath -match '^[/\-]' -tai $OutputPath -match '[<>:"|? *]') { Write-Host "Virheellinen OutputPath määritetty, tuloste stdout:ksi" -EdustaVäri Keltainen Write-Output $jsonOutput jos ($secureBootEnabled -and $uefica 2023Status -eq "Päivitetty") { exit 0 } muu { exit 1 } } # Varmista, että kohdekansio on olemassa if (-not (Test-Path $OutputPath)) { kokeile { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } saalis { Write-Warning "Tulostuskansiota ei voitu luoda: $OutputPath - $_" } } # Tallenna HOSTNAME_latest.json $outputFile = Join-Path $OutputPath $($hostname)_latest.json kokeile { $jsonOutput | Out-File -FilePath $outputFile -Encoding UTF8 -Force Write-Host "JSON tallennettu kohteeseen: $outputFile" -ForegroundColor Green } saalis { Write-Warning "Tiedostoon ei voitu kirjoittaa: $outputFile - $_" Palaa stdoutiin Write-Output $jsonOutput } } muu { # Alkuperäinen toiminta – tuloste stdoutiin Write-Output $jsonOutput }
# Exit code: "Updated" is the success value per the playbook if ($secureBootEnabled -and $uefica 2023Status -eq "Updated") { exit 0 # Ilman ongelmia } muu { exit 1 # With issue }