SVARBU Šis straipsnis su šiuo scenarijaus pavyzdžiu buvo panaikintas. Pradedant nuo "Windows" naujinimų, išleistų 2026 m. gegužės 12 d. ir vėliau, scenarijaus pavyzdys yra jūsų įrenginio aplanke %systemroot%\SecureBoot\ExampleRolloutScripts .
Nukopijuokite ir įklijuokite šį scenarijaus pavyzdį ir modifikuokite, jei reikia pagal savo aplinką:
<# . SANTRAUKA Diegia saugiosios įkrovos diegimo valdymo modulį kaip "Windows" suplanuotą užduotį.
.DESCRIPTION Sukuriama suplanuota užduotis, kuri nuolat fone paleidžia valdymo modulį.Užduotis vykdoma su apėjimo vykdymo strategija, todėl nerodomi jokie saugos raginimai. Organizatorius: - Apklausa dėl įrenginio atnaujinimų nurodytu intervalu - Automatiškai generuokite bangas ir įdiekite GPO - Tęskite, kol bus atnaujinti visi tinkami įrenginiai Stebėkite eigą naudodami Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath UNC kelias į JSON įrenginio duomenis (iš aptikimo GPO)
.PARAMETER ReportBasePath Vietinis ataskaitų ir valstijų failų kelias
.PARAMETER TargetOU OU GPO susiejimui (pasirinktinai – numatytoji domeno šaknis)
.PARAMETER PollIntervalMinutes Minutės tarp būsenos patikra. Numatytoji reikšmė: 30
.PARAMETER UseWinCS Naudokite "WinCS" ("Windows" konfigūracijos sistema) vietoj "AvailableUpdatesPolicy GPO".Kai įgalinta, įdiegia WinCsFlags.exe suplanuotą užduotį galiniams punktams, o ne registro GPO.
.PARAMETER WinCSKey "WinCS" kodas, skirtas saugiosios įkrovos konfigūracijai. Numatytoji reikšmė: F33E0C8E002
.PARAMETER ServiceAccount abonementą, kad galėtumėte vykdyti užduotį. Numatytoji reikšmė: SISTEMA Domeno operacijoms naudokite domeno administravimo tarnybos paskyrą.
.PARAMETER AllowListPath Kelias į failą, kuriame yra pagrindinių kompiuterių vardų, kad būtų LEIDŽIAMA įdiegti (tikslinis / bandomasis diegimas).Palaiko .txt (vienas pagrindinio kompiuterio vardas vienoje eilutėje) arba .csv (su stulpeliu Pagrindinio kompiuterio vardas/Kompiuterio vardas/Vardas).Kai nurodyta, į diegimą bus įtraukti TIK šie įrenginiai.
.PARAMETER AllowADGroup AD saugos grupės, apimančios kompiuterio paskyras, kurias reikia LEISTI, pavadinimas.Pvz.: "SecureBoot-Pilot-Computers"
.PARAMETER ExclusionListPath Kelias į failą, kuriame yra pagrindinių kompiuterių vardų, kurių NEREIKIA IŠLEISTI (VIP / vykdomieji įrenginiai).Palaiko .txt (vienas pagrindinio kompiuterio vardas vienoje eilutėje) arba .csv (su stulpeliu Pagrindinio kompiuterio vardas/Kompiuterio vardas/Vardas).
.PARAMETER ExcludeADGroup AD saugos grupės, apimančios kompiuterių paskyras, kurias reikia pašalinti, pavadinimas.Pvz.: "VIP-Computers"
.PARAMETER ScriptPath Kelias į orkestro scenarijų. Numatytasis parametras: tas pats aplankas kaip ir šis scenarijus.
.PARAMETER Uninstall Suplanuotos užduoties šalinimas
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -ServiceAccount "DOMAIN\svc_secureboot"
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"
.EXAMPLE # Diegti naudojant "WinCS" metodą vietoj "AvailableUpdatesPolicy" .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -Pašalinti #>
[CmdletBinding()] param( [Parameter(Mandatory = $false)] [eilutė]$AggregationInputPath, [Parameter(Mandatory = $false)] [eilutė]$ReportBasePath, [Parameter(Mandatory = $false)] [eilutė]$TargetOU, [Parameter(Mandatory = $false)] [int]$PollIntervalMinutes = 30, [Parameter(Mandatory = $false)] [switch]$UseWinCS, [Parameter(Mandatory = $false)] [eilutė]$WinCSKey = "F33E0C8E002", [Parameter(Mandatory = $false)] [eilutė]$ServiceAccount = "SISTEMA", [Parameter(Mandatory = $false)] [eilutė]$AllowListPath, [Parameter(Mandatory = $false)] [eilutė]$AllowADGroup, [Parameter(Mandatory = $false)] [eilutė]$ExclusionListPath, [Parameter(Mandatory = $false)] [eilutė]$ExcludeADGroup, [Parameter(Mandatory = $false)] [eilutė]$ScriptPath, [Parameter(Mandatory = $false)] [perjungti]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = "SecureBoot-Rollout-Orchestrator" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Diegimo ir stebėjimo pavyzdžiai"
# ================================================================== # DEPENDENCY VALIDATION# ==================================================================
function Test-ScriptDependencies { <# . SANTRAUKA Patikrina, ar yra visi būtini scenarijai.. APIBŪDINIMAS Tikrina, ar nėra būtinų scenarijaus priklausomybių, ir pateikia atsisiuntimo instrukcijas, jei jų nėra.#> param( [Parameter(Mandatory = $true)] [eilutė]$ScriptDirectory, [Parameter(Mandatory = $true)] [eilutė[]]$RequiredScripts ) $missingScripts = @() foreach ($script in $RequiredScripts) { $scriptPath = Join-Path $ScriptDirectory $script if (-not (Test-Path $scriptPath)) { $missingScripts += $script } } if ($missingScripts.Count -gt; 0) { Write-Host "" Write-Host ("=" * 70) -PriekinisSpalva Raudona Write-Host " TRŪKSTAMOS PRIKLAUSOMYBĖS" -ForeplaneColor Red Write-Host ("=" * 70) -PriekinisSpalva Raudona Write-Host "" Write-Host "Nerasta šių būtinų scenarijų:" -ForegroundColor Yellow foreach ($script in $missingScripts) { Write-Host " - $script" -PriekinisSpalva Balta } Write-Host "" Write-Host "Atsisiųskite naujausius scenarijus iš:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor White Write-Host " Pereiti į: '$DownloadSubPage'" -ForeplaneColor White Write-Host "" Write-Host "Išskleiskite visus scenarijus į tą patį katalogą ir vykdykite dar kartą". -ForeplaneColor Geltona Write-Host "" grįžti $false } Grįžties $true }
# Required scripts for orchestrator deployment $requiredScripts = @( "Start-SecureBootRolloutOrchestrator.ps1", "Aggregate-SecureBootData.ps1", "Deploy-GPO-SecureBootCollection.ps1", "Detect-SecureBootCertUpdateStatus.ps1", "Get-SecureBootRolloutStatus.ps1", "Enable-SecureBootUpdateTask.ps1" )
if (-not (Test-ScriptDependencies -ScriptDirectory $PSScriptRoot -RequiredScripts $requiredScripts)) { 1 išėjimas }
# ================================================================== # PAŠALINTI# ==================================================================
if ($Uninstall) { Write-Host "" Write-Host "Šalinama suplanuota užduotis: $TaskName" -ForegroundColor Yellow $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false Write-Host "Užduotis sėkmingai pašalinta". -PriekinisplanasSpalva Žalia } kitu atveju { Write-Host "Užduotis nerasta". -PriekinisSpalva Pilka } Išeiti 0 }
# ================================================================== # TIKRINIMO# ==================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host "ERROR: -AggregationInputPath ir -ReportBasePath yra būtini." -PriekinioplanoSpalva Raudona Write-Host "" Write-Host "Pavyzdys:" -ForegroundColor Yellow Write-Host ' .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"' 1 išėjimas }
# Find orchestrator script if (-not $ScriptPath) { $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }
if (-not (Test-Path $ScriptPath)) { Write-Host "KLAIDA: nerastas "Orchestrator" scenarijus: $ScriptPath" -ForegroundColor Red 1 išėjimas }
# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot "Aggregate-SecureBootData.ps1" if (-not (Test-Path $aggregateScript)) { Write-Host "ĮSPĖJIMAS: scenarijų kataloge nerasta Aggregate-SecureBootData.ps1" -ForegroundColor Yellow Write-Host " Orchestrator gali nepavykti, jei nepavyksta rasti šio scenarijaus." -ForeplaneColor Yellow }
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host " Secure Boot Rollout Orchestrator - Task Deployment" -ForegroundColor Cyan Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host ""
# For display, show relative paths (script names only) $displayScriptPath = Split-Path $ScriptPath -leaf
Write-Host "Configuration:" -ForegroundColor Yellow Write-Host " Užduoties pavadinimas: $TaskName" Write-Host " Orchestrator: $displayScriptPath" Write-Host " Įvesties kelias: $AggregationInputPath" Write-Host " Ataskaitos kelias: $ReportBasePath" Write-Host " Tikslinis OU: $(if ($TargetOU) { $TargetOU } else { '(domeno šaknis)' })" Write-Host " Apklausos intervalas: $PollIntervalMinutes minutės" Write-Host " Paslaugos paskyra: $ServiceAccount" Write-Host " Diegimo būdas: $(if ($UseWinCS) { "WinCS (WinCsFlags.exe)" } else { "AvailableUpdatesPolicy (GPO)" })" if ($UseWinCS) { Write-Host " WinCS raktas: $WinCSKey" } Write-Host ""
# ================================================================== # GPO APTIKIMAS – AUTOMATINIS DIEGIMAS, JEI TRŪKSTA# ==================================================================
$CollectionGPOName = "SecureBoot-EventCollection" $deployGpoScript = Join-Path $PSScriptRoot "Deploy-GPO-SecureBootCollection.ps1"
# Check if GroupPolicy module is available if (Get-Module -ListAvailable -Name GroupPolicy) { Import-Module GroupPolicy -ErrorAction SilentlyContinue Write-Host "Tikrinamas aptikimas GPO..." -ForegroundColor Yellow išbandykite { # Gaukite domeną iš AggregationInputPath (pvz., \\domain\share) $domainFromPath = if ($AggregationInputPath -match '^\\\\([^\\]+)\\') { $matches[1] } kitu atveju { $env:USERDNSDOMAIN } # Patikrinkite, ar yra GPO $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue if ($existingGpo) { Write-Host Aptikimo GPO rastas: $CollectionGPOName" -ForegroundColor Green } kitu atveju { Write-Host "" Write-Host ("=" * 70) -PriekinisSpalva Geltona Write-Host " APTIKIMAS GPO NERASTAS" -ForeplaneColor Yellow Write-Host ("=" * 70) -ForegroundColor Geltona Write-Host "" Write-Host "Aptikimo GPO "$CollectionGPOName" nerastas." -ForeplaneColor Yellow Write-Host "Šis GPO būtinas įrenginio būsenos duomenims rinkti". -Priekinioplanospalva Geltona Write-Host "" # Paklauskite vartotojo, ar jie nori įdiegti GPO dabar Write-Host "Ar norite įdiegti aptikimo GPO dabar? (Taip/N)" -ForegroundColor Cyan $response = skaitymo pagrindinis kompiuteris if ($response -match '^[Yy]') { Write-Host "" Write-Host "Pradedamas GPO diegimas..." -ForegroundColor Cyan Write-Host "" # GPO diegimo versijos parametrai $gpoParams = @{ DomainName = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1" } if ($TargetOU) { $gpoParams.OUPath = $TargetOU } kitu atveju { # Naudokite AutoDetectOU, kad leistumėte vartotojui pasirinkti $gpoParams.AutoDetectOU = $true } # Paleiskite GPO diegimo scenarijų & $deployGpoScript @gpoParams if ($LASTEXITCODE -ne 0) { Write-Host "Gali kilti GPO diegimo problemų. Peržiūrėkite aukščiau pateiktą išvestį." -ForeplaneColor Yellow Write-Host "Galite tęsti valdymo modulio diegimą arba paspauskite Ctrl+C, kad nutrauktumėte." -PriekinisSpalva Geltona Write-Host "" Read-Host "Tęskite paspausdami Enter" } kitu atveju { Write-Host "" Write-Host "Aptikimo GPO įdiegtas sėkmingai!" -ForeplaneColor Green Write-Host "" } } kitu atveju { Write-Host "" Write-Host "Praleidžiamas GPO diegimas. Valdymo modulis negaus įrenginio duomenų" – ForegroundColor Geltona Write-Host "kol aptikimo GPO nebus įdiegtas rankiniu būdu". -Priekinioplanospalva Geltona Write-Host "" Write-Host "Norėdami įdiegti aptikimo GPO vėliau, vykdykite:" -ForegroundColor Cyan Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath'" -AutoDetectOU" -ForegroundColor White Write-Host "" } } } gaudyti { Write-Host " Nepavyksta patikrinti GPO: $($_. Exception.Message)" -ForegroundColor Yellow Write-Host " Tęsiama su orkestruotojo dislokavimu..." -ForeplaneColor Gray } } kitu atveju { Write-Host " GroupPolicy module not available - skipping GPO check" -ForegroundColor Gray Write-Host " Įsitikinkite, kad aptikimo GPO yra įdiegtas atskirai." -Priekinis planasSpalva Pilka }
Write-Host ""
# ================================================================== # BUILD ARGUMENTS# ==================================================================
$arguments = @( "-NoProfile" "-ExecutionPolicy Bypass" "-Failas '"$ScriptPath'"" "-AggregationInputPath '"$AggregationInputPath'"" "-ReportBasePath '"$ReportBasePath'"" "-PollIntervalMinutes $PollIntervalMinutes" )
if ($TargetOU) { $arguments += "-TargetOU '"$TargetOU'"" }
if ($UseWinCS) { $arguments += "-UseWinCS" $arguments += "-WinCSKey '"$WinCSKey'"" }
if ($AllowListPath) { $arguments += "-AllowListPath '"$AllowListPath'"" }
if ($AllowADGroup) { $arguments += "-AllowADGroup '"$AllowADGroup'"" }
if ($ExclusionListPath) { $arguments += "-ExclusionListPath '"$ExclusionListPath'"" }
if ($ExcludeADGroup) { $arguments += "-ExcludeADGroup '"$ExcludeADGroup'"" }
$argumentString = $arguments -join " "
# Don't display raw arguments with full paths - it's confusing for published scripts # Užduotis naudos visą kelią viduje
# ================================================================== # SUPLANUOTOS UŽDUOTIES KŪRIMAS# ==================================================================
# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Write-Host "Užduotis jau yra. Atnaujinama..." -ForeplaneColor Geltona Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false }
# Create task action $action = New-ScheduledTaskAction -execute "powershell.exe" -argument $argumentString -WorkingDirectory $PSScriptRoot
# Create trigger - run once, immediately (orchestrator loops internally) $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date). AddMinutes(1)
# Create principal if ($ServiceAccount -eq "SYSTEM") { $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest } kitu atveju { # Normalizuoti vietinės paskyros formatą: COMPUTERNAME\User -> User # Register-ScheduledTask nepriima COMPUTERNAME\User arba .\User vietinėms paskyroms $taskUser = $ServiceAccount if ($ServiceAccount -match "^$([regex]::Escape($env:COMPUTERNAME))\\(.+)$") { $taskUser = $Matches[1] Write-Host " Pastaba: aptikta vietinė paskyra, užduočiai registruoti naudojama "$taskUser" -ForeplaneColor Gray }
# Prompt for password Write-Host "Įveskite $ServiceAccount slaptažodį" -ForegroundColor Yellow $cred = Get-Credential -UserName $taskUser -Message "Service account credentials for scheduled task" if (-not $cred) { Write-Host "Kredencialų įrašas atšauktas. Nutraukiama." -Priekinis planasSpalva Raudona 1 išėjimas } $principal = New-ScheduledTaskPrincipal -UserId $taskUser -LogonType Password -RunLevel Highest }
# Task settings $settings = New-ScheduledTaskSettingsSet ' -AllowStartIfOnBatteries ' -DontStopIfGoingOnBatteries ' -StartWhenAvailable ' -RunOnlyIfNetworkAvailable ' -RestartCount 3 ' -RestartInterval (naujas laiko intervalas -5 minutės) ' -ExecutionTimeLimit (New-TimeSpan -Days 30) # Leisti ilgai
# Register task išbandykite { if ($ServiceAccount -eq "SYSTEM") { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Saugiosios įkrovos sertifikato diegimas – automatinis GPO diegimas" } kitu atveju { # Naudokite New-ScheduledTask, kad įterptumėte pagrindinį (su RunLevel Highest) į užduoties objektą, # tada užsiregistruokite naudodami -InputObject + -User/-Password (atskirkite parametrų rinkinį nuo -Principal) $taskDefinition = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings $taskDefinition.Description = "Secure Boot Certificate Rollout - Automated GPO deployment" # Pastaba: Register-ScheduledTask reikalauja paprasto teksto slaptažodžio - nėra SecureString perkrovos $netCred = $cred. GetNetworkCredential() Register-ScheduledTask -TaskName $TaskName -InputObject $taskDefinition -User $taskUser -Password $netCred.Password -ErrorAction Stop $netCred = $null } Write-Host "Suplanuota užduotis sukurta sėkmingai!" -Priekinis planasSpalva Žalia } gaudyti { Write-Host "Nepavyko sukurti suplanuotos užduoties: $($_. Exception.Message)" -ForegroundColor Red 1 išėjimas }
# ================================================================== # SUKURTI BŪSENOS NUORODĄ# ==================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (test-path $statusScript) { Write-Host "" Write-Host "Norėdami patikrinti diegimo būseną, vykdykite:" -ForegroundColor Yellow Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'"" -ForegroundColor Cyan }
# ================================================================== # IŠVESTIES# ==================================================================
Write-Host "" Write-Host ("=" * 70) -PriekinisSpalva Žalia Write-Host " DIEGIMAS BAIGTAS" -PriekinisSpalva Žalia Write-Host ("=" * 70) -PriekinisSpalva Žalia Write-Host "" Write-Host "Orkestruotojas pradės veikti maždaug po 1 minutės." -Pirmas planasSpalva Balta Write-Host "" Write-Host "MONITORING:" -ForegroundColor Yellow Write-Host " Peržiūrėti užduoties būseną: Get-ScheduledTask -TaskName '$TaskName' | Pasirinkite valstiją" Write-Host " Peržiūrėti užduočių žurnalą: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyMMdd').log' -Tail 50" Write-Host Peržiūrėti diegimo būseną: Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json" Write-Host " Peržiūrėti ataskaitų sritį: Pradėti '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html'" Write-Host " Sparčioji būsena: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "MANAGEMENT:" -ForegroundColor Yellow Write-Host " Paleisti rankiniu būdu: Start-ScheduledTask -TaskName '$TaskName'" Write-Host " Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host " Pašalinti: .\Deploy-OrchestratorTask.ps1 -pašalinti" Write-Host ""