VAŽNO Ovaj članak koji sadrži ovu oglednu skriptu povučen je iz upotrebe. Počevši od ažuriranja sustava Windows objavljenih 12. svibnja 2026. i kasnije, ogledna skripta nalazi se u mapi %systemroot%\SecureBoot\ExampleRolloutScripts na vašem uređaju .
Kopirajte i zalijepite ovu oglednu skriptu te je izmijenite po potrebi za svoje okruženje:
<# . SINOPSIS Implementira orkestrator sigurnog pokretanja kao zakazani zadatak sustava Windows.
.DESCRIPTION Stvara zakazani zadatak koji orkestratora kontinuirano izvodi u pozadini.Zadatak se pokreće uz pravilo zaobilaska izvršavanja, tako da se ne prikazuju sigurnosni upiti. Orkestrator će: - Anketa za ažuriranja uređaja u navedenom intervalu - Automatski generirajte valove i implementirajte GPO-ove - Nastavi dok se ne ažuriraju svi uređaji koji ispunjavaju uvjete Pratite napredak pomoću: Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath UNC put do podataka JSON uređaja (iz otkrivanja GPO-a)
.PARAMETER ReportBasePath Lokalni put za izvješća i datoteke stanja
.PARAMETER TargetOU OU za povezivanje GPO-ova (neobavezno – zadano je korijen domene)
.PARAMETER PollIntervalMinutes Minute između provjera statusa. Zadano: 30
.PARAMETER UseWinCS Koristite WinCS (konfiguracijski sustav sustava Windows) umjesto AvailableUpdatesPolicy GPO.Kada je omogućeno, zakazani zadatak implementira WinCsFlags.exe na krajnje točke, a ne u pravilnik grupe registra.
.PARAMETER WinCSKey WinCS ključ za konfiguraciju sigurnog pokretanja. Zadano: F33E0C8E002
.PARAMETER ServiceAccount za pokretanje zadatka. Zadano: SUSTAV Za operacije s domenom koristite račun servisa za administratore domene.
.PARAMETER AllowListPath Put do datoteke koja sadrži nazive glavnog računala koji će se OMOGUĆITI za uvođenje (ciljano/pilot-uvođenje).Podržava .txt (jedan naziv glavnog računala po retku) ili .csv (sa stupcem NazivGlavnog računala/NazivRačunala/Naziv).Kada je navedeno, SAMO će ovi uređaji biti uključeni u implementaciju.
.PARAMETER AllowADGroup Naziv sigurnosne grupe servisa AD koja sadrži računalne račune za ALLOW.Primjer: "SecureBoot-Pilot-Computers"
.PARAMETER ExclusionListPath Put do datoteke koja sadrži nazive glavnog računala koje treba IZUZETI iz implementacije (VIP/izvršni uređaji).Podržava .txt (jedan naziv glavnog računala po retku) ili .csv (sa stupcem NazivGlavnog računala/NazivRačunala/Naziv).
.PARAMETER ExcludeADGroup Naziv sigurnosne grupe servisa AD koja sadrži račune računala koje treba izuzeti.Primjer: "VIP-Computers"
.PARAMETER ScriptPath Put do skripte orkestratora. Zadano: Ista mapa kao i ova skripta.
.PARAMETER Uninstall Uklanjanje zakazanog zadatka
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -ServiceAccount "DOMENA\svc_secureboot"
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"
.EXAMPLE # Implementacija pomoću WinCS metode umjesto AvailableUpdatesPolicy .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 – Uninstall #>
[CmdletBinding()] param( [Parameter(Mandatory = $false)] [niz]$AggregationInputPath, [Parameter(Mandatory = $false)] [niz]$ReportBasePath, [Parameter(Mandatory = $false)] [niz]$TargetOU, [Parameter(Mandatory = $false)] [int]$PollIntervalMinutes = 30, [Parameter(Mandatory = $false)] [prekidač]$UseWinCS, [Parameter(Mandatory = $false)] [niz]$WinCSKey = "F33E0C8E002", [Parameter(Mandatory = $false)] [string]$ServiceAccount = "SYSTEM", [Parameter(Mandatory = $false)] [niz]$AllowListPath, [Parameter(Mandatory = $false)] [niz]$AllowADGroup, [Parameter(Mandatory = $false)] [niz]$ExclusionListPath, [Parameter(Mandatory = $false)] [niz]$ExcludeADGroup, [Parameter(Mandatory = $false)] [niz]$ScriptPath, [Parameter(Mandatory = $false)] [prekidač]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = "SecureBoot-Rollout-Orchestrator" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Deployment and monitoring samples"
# ================================================================== # PROVJERA VALJANOSTI ZAVISNOSTI# ==================================================================
function Test-ScriptDependencies { <# . SINOPSIS Provjerava jesu li dostupne sve potrebne skripte.. OPIS Provjerava obavezne ovisnosti skripti i daje upute za preuzimanje ako ih nema.#> param( [Parameter(Mandatory = $true)] [niz]$ScriptDirectory, [Parameter(Mandatory = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script u $RequiredScripts) { $scriptPath = Join-Path $ScriptDirectory $script if (-not (Test-Path $scriptPath)) { $missingScripts += $script } } if ($missingScripts.Count -gt; 0) { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Red Write-Host " MISSING DEPENDENCIES" -foregroundColor Red Write-Host ("=" * 70) -ForegroundColor Red Write-Host "" Write-Host "Sljedeće obavezne skripte nisu pronađene:" -ForegroundColor Yellow foreach ($script u $missingScripts) { Write-Host " - $script" -foregroundColor White } Write-Host "" Write-Host "Preuzmite najnovije skripte na adresi:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor White Write-Host " Navigacija na: '$DownloadSubPage'" -ForegroundColor White Write-Host "" Write-Host "Izdvoji sve skripte u isti direktorij i ponovno pokreni." -ForegroundColor Yellow Write-Host "" Povrat $false } Povrat $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)) { Izlaz 1 }
# ================================================================== # DEINSTALACIJA# ==================================================================
if ($Uninstall) { Write-Host "" Write-Host "Uklanjanje zakazanog zadatka: $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 "Zadatak je uspješno uklonjen." -ForegroundColor Green } else { Write-Host "Zadatak nije pronađen." -ForegroundColor Grey } izlaz 0 }
# ================================================================== # PROVJERA VALJANOSTI# ==================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host "POGREŠKA: -AggregationInputPath i -ReportBasePath su obavezni." -ForegroundColor Red Write-Host "" Write-Host "Primjer:" -foregroundColor yellow Write-Host ' .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"' Izlaz 1 }
# Find orchestrator script if (-not $ScriptPath) { $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }
if (-not (Test-Path $ScriptPath)) { Write-Host "POGREŠKA: Orchestrator script not found: $ScriptPath" -ForegroundColor Red Izlaz 1 }
# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot "Aggregate-SecureBootData.ps1" if (-not (Test-Path $aggregateScript)) { Write-Host "UPOZORENJE: Aggregate-SecureBootData.ps1 nije pronađeno u direktoriju skripte" -ForegroundColor Yellow Write-Host "Orchestrator možda neće uspjeti ako ne može pronaći ovu skriptu." -ForegroundColor 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 -list
Write-Host "Configuration:" -ForegroundColor Yellow Write-Host " Naziv zadatka: $TaskName" Write-Host " Orchestrator: $displayScriptPath" Write-Host " Ulazni put: $AggregationInputPath" Write-Host " Put izvješća: $ReportBasePath" Write-Host " Ciljna OU: $(if ($TargetOU) { $TargetOU } else { '(korijen domene)' })" Write-Host "Interval ankete: $PollIntervalMinutes minuta" Write-Host " Service Account: $ServiceAccount" Write-Host " Način implementacije: $(if ($UseWinCS) { "WinCS (WinCsFlags.exe)" } else { "AvailableUpdatesPolicy (GPO)" })" if ($UseWinCS) { Write-Host " WinCS tipka: $WinCSKey" } Write-Host ""
# ================================================================== # OTKRIVANJE OBJEKTA PRAVILNIKA GRUPE – AUTOMATSKA IMPLEMENTACIJA AKO NEMA# ==================================================================
$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 "Provjera otkrivanja GPO-a..." -ForegroundColor Yellow try { # Dohvatite domenu iz AggregationInputPath (npr. \\domena\zajedničko korištenje) $domainFromPath = if ($AggregationInputPath -match '^\\\\([^\\]+)\\') { $matches[1] } else { $env:USERDNSDOMAIN } # Provjera postoji li objekt pravilnika grupe $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue if ($existingGpo) { Write-Host " Detection GPO found: $CollectionGPOName" -ForegroundColor Green } else { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Yellow Write-Host " DETECTION GPO NOT FOUND" -ForegroundColor Yellow Write-Host ("=" * 70) -foregroundColor Yellow Write-Host "" Write-Host "Pravilnik grupe za otkrivanje '$CollectionGPOName' nije pronađen." -ForegroundColor Yellow Write-Host "Ovaj objekt pravilnika grupe potreban je za prikupljanje podataka o statusu uređaja." -ForegroundColor Yellow Write-Host "" # Pitajte korisnika želi li odmah implementirati objekt pravilnika grupe Write-Host "Želite li odmah implementirati objekt pravilnika grupe za prepoznavanje? (y/n)" -foregroundColor Cyan $response = Read-Host if ($response -match '^[Yy]') { Write-Host "" Write-Host "Pokretanje implementacije GPO-a..." -ForegroundColor Cyan Write-Host "" # Parametri međuverzije za implementaciju GPO-a $gpoParams = @{ NazivDomene = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1" } if ($TargetOU) { $gpoParams.OUPath = $TargetOU } else { # Koristite AutoDetectOU da biste korisniku omogućili odabir $gpoParams.AutoDetectOU = $true } # Pokretanje skripte za implementaciju objekta pravilnika grupe & $deployGpoScript @gpoParams if ($LASTEXITCODE -ne 0) { Write-Host "Implementacija objekta pravilnika grupe možda je naišla na probleme. Pregledajte izlaz iznad." -ForegroundColor Yellow Write-Host "Možete nastaviti s implementacijom orkestratora ili pritisnuti Ctrl+C za prekidanje." -ForegroundColor Yellow Write-Host "" Read-Host "Pritisnite Enter da biste nastavili" } else { Write-Host "" Write-Host "Otkrivanje objekta pravilnika grupe uspješno implementirano!" -ForegroundColor Green Write-Host "" } } else { Write-Host "" Write-Host "Preskakanje implementacije GPO-a. The orchestrator will not receive device data" -ForegroundColor Yellow Write-Host "dok se GPOO za otkrivanje ne implementira ručno." -ForegroundColor Yellow Write-Host "" Write-Host "Da biste kasnije implementirali GPO, pokrenite postupak:" -ForegroundColor Cyan Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath'" -AutoDetectOU" -foregroundColor White Write-Host "" } } } catch { Write-Host " Nije moguće provjeriti GPO: $($_. Exception.Message)" -foregroundColor yellow Write-Host " Nastavak s implementacijom orkestratora..." -ForegroundColor Grey } } else { Write-Host " Modul pravilnika grupe nije dostupan – preskakanje provjere objekta pravilnika grupe" -ForegroundColor Grey Write-Host " Ensure detection GPO is deployed separate." -ForegroundColor grey }
Write-Host ""
# ================================================================== # BUILD ARGUMENATA# ==================================================================
$arguments = @( "-NoProfile" "-ExecutionPolicy Bypass" "-File '"$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 # Zadatak će interno koristiti cijeli put
# ================================================================== # STVARANJE ZAKAZANOG ZADATKA# ==================================================================
# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Write-Host "Zadatak već postoji. Ažuriranje..." -foregroundColor Yellow 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 } else { # Normalizirajte format lokalnog računa: COMPUTERNAME\User -> User # Register-ScheduledTask ne prihvaća COMPUTERNAME\User ili .\User za lokalne račune $taskUser = $ServiceAccount if ($ServiceAccount -match "^$([regex]::Escape($env:COMPUTERNAME))\\(.+)$") { $taskUser = $Matches[1] Write-Host " Note: Local account detected, using '$taskUser' for task registration" -ForegroundColor grey }
# Prompt for password Write-Host "Unesite lozinku za $ServiceAccount" -foregroundColor Yellow $cred = Get-Credential -UserName $taskUser -Message "Service account credentials for scheduled task" (Vjerodajnice servisnog računa za zakazani zadatak) if (-not $cred) { Write-Host "Unos vjerodajnica je otkazan. Aborting." -ForegroundColor Red Izlaz 1 } $principal = New-ScheduledTaskPrincipal -UserId $taskUser -LogonType Password -RunLevel Najviša }
# Task settings $settings = New-ScheduledTaskSettingsSet ' -AllowStartIfOnBatteries ' -DontStopIfGoingOnBatteries ' -StartWhenAvailable ' -RunOnlyIfNetworkAvailable ' -RestartCount 3 ' -RestartInterval (New-TimeSpan -Minutes 5) ' -ExecutionTimeLimit (New-TimeSpan -Days 30) # Dopusti dugotrajno
# Register task try { if ($ServiceAccount -eq "SYSTEM") { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Implementacija certifikata sigurnog pokretanja sustava – automatizirana implementacija GPO-a" } else { # Pomoću New-ScheduledTask ugradite glavni operator (s najvišom mogućnošću RunLevel High) u objekt zadatka, # zatim se registrirajte s -InputObject + -User/-Password (odvojeni skup parametara od parametra -Principal) $taskDefinition = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings $taskDefinition.Description = "Implementacija certifikata sigurnog pokretanja sustava – automatizirana implementacija GPO-a" # Napomena: Register-ScheduledTask zahtijeva lozinku u obliku običnog teksta – ne postoji preopterećenje SecureStringom $netCred = $cred. GetNetworkCredential() Register-ScheduledTask -TaskName $TaskName -InputObject $taskDefinition -User $taskUser -Password $netCred.Password -ErrorAction Stop $netCred = $null } Write-Host "Scheduled task created successfully!" -ForegroundColor Green } catch { Write-Host "Stvaranje zakazanog zadatka nije uspjelo: $($_. Exception.Message)" -foregroundColor Red Izlaz 1 }
# ================================================================== # STVARANJE PREČACA STATUSA# ==================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (Test-Path $statusScript) { Write-Host "" Write-Host "Da biste provjerili status uvođenja, pokrenite postupak:" -ForegroundColor Yellow Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'"" -ForegroundColor Cyan }
# ================================================================== # IZLAZNI# ==================================================================
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Green Write-Host " DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host ("=" * 70) -foregroundColor Green Write-Host "" Write-Host "Orkestrator će se pokrenuti za otprilike 1 minutu." -ForegroundColor White Write-Host "" Write-Host "MONITORING:" -ForegroundColor Yellow Write-Host " Prikaz statusa zadatka: Get-ScheduledTask -TaskName '$TaskName' | Odaberi državu" Write-Host " Prikaz zapisnika zadataka: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyyMMdd').log' -Tail 50" Write-Host " Prikaz stanja uvođenja: Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json" Write-Host " Prikaz nadzorne ploče: Start '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html'" Write-Host " Quick status: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "UPRAVLJANJE:" -ForegroundColor Yellow Write-Host " Ručno pokreni: Start-ScheduledTask -TaskName '$TaskName'" Write-Host " Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host " Remove: .\Deploy-OrchestratorTask.ps1 -uninstall" Write-Host ""