Skopírujte a prilepte tento vzorový skript a podľa potreby ho upravte pre svoje prostredie:
<# . PREHĽADU Skript nasadenia objektu GPO pre kolekciu udalostí zabezpečeného spustenia Vytvorí a prepojí objekt GPO na nasadenie skriptu kolekcie ako naplánovanej úlohy
.DESCRIPTION Tento skript automatizuje nasadenie kolekcie udalostí zabezpečeného spustenia prostredníctvom skupinová politika.Vytvorí objekt GPO s: - Naplánovaná úloha, ktorá denne spúšťa skript kolekcie - Správne povolenia na písanie do centrálneho zdieľania – filtre WMI na zacielenie na konkrétne verzie operačného systému
.PARAMETER GPOName Názov nového objektu GPO
.PARAMETER DomainName FQDN cieľovej domény
.PARAMETER OUPath Rozlišujúci názov OU(ov) na prepojenie objektu GPO.Akceptuje viacero OU ako pole. Nevyžaduje sa, ak je zadaná funkcia -AutoDetectOU.
.PARAMETER AutoDetectOU Prepnite na interaktívny zoznam a vyberte používateľov OU zo služby Active Directory.Ak je zadané, parameter -OUPath je voliteľný.
.PARAMETER CollectionSharePath Cesta UNC, kde sa uložia výsledky kolekcie
.PARAMETER ScriptSourcePath Cesta, kde je uložený skript kolekcie (skopíruje sa do SYSVOL)
.PARAMETER RandomDelayHours Počet hodín náhodného rozloženia spustenia skriptu v koncových bodoch.Tým sa zabráni súčasnému zapisovaniu všetkých počítačov do zdieľania.Predvolené: 4 hodiny. Platný rozsah: 1 – 24 hodín. Odporúčané hodnoty: - Zariadenia s rozlíšením 1 až 10 K: 4 hodiny (predvolené) - Zariadenia 10K-50K: 8 hodín - 50 K + zariadenia: 12-24 hodín
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath "OU=Pracovné stanice,DC=contoso,DC=com"
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath "OU=Pracovné stanice,DC=contoso,DC=com" -RandomDelayHours 8
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -AutoDetectOU Zobrazí zoznam všetkých operačných služieb v doméne a výzvy na výber.
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath @("OU=Pracovné stanice,DC=contoso,DC=com", "OU=Laptops,DC=contoso,DC=com") Prepája objekt GPO s viacerými OU v jednom spustení.
.NOTES Vyžaduje sa: modul Prostredia PowerShell služby Active Directory, modul skupinová politika Musí byť spustený s doménovými Spravovanie alebo delegovanými právami na vytváranie objektu GPO. #>
[CmdletBinding()] param( [Parameter(Povinné = $false)] [reťazec]$GPOName = "SecureBoot-EventCollection", [Parameter(Povinné = $false)] [reťazec]$DomainName, [Parameter(Povinné = $false)] [reťazec[]]$OUPath, [Parameter(Povinné = $false)] [prepínač]$AutoDetectOU, [Parameter(Povinné = $false)] [string]$CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs", [Parameter(Povinné = $false)] [reťazec]$ScriptSourcePath = ".\Detect-SecureBootCertUpdateStatus.ps1", [Parameter(Povinné = $false)] [ValidateSet("Denne"; "Týždenne", "AtStartup")] [reťazec]$Schedule = "Denne", [Parameter(Povinné = $false)] [reťazec]$ScheduleTime = "14:00", [Parameter(Povinné = $false)] [ValidateRange(1, 24)] [int]$RandomDelayHours = 4 )
#Requires -Modules ActiveDirectory, GroupPolicy #Requires verzie 5.1
$ErrorActionPreference = "Stop" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Nasadenie a monitorovanie ukážok"
# ============================================================================ # OVERENIE ZÁVISLOSTI # ============================================================================
function Test-ScriptDependencies { param( [Parameter(Povinné = $true)] [reťazec]$ScriptDirectory, [Parameter(Povinné = $true)] [reťazec[]]$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) -Farba popredia červená Write-Host "MISSING DEPENDENCIES" -ForegroundColor Red Write-Host ("=" * 70) -Farba popredia červená Write-Host "" Write-Host "Nenašli sa nasledujúce požadované skripty:" -ForegroundColor Yellow foreach ($script in $missingScripts) { Write-Host " - $script" -Farba popredia Biela } Write-Host "" Write-Host "Stiahnite si najnovšie skripty z:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -Farba popredia biela Write-Host " Prejsť na: '$DownloadSubPage'" -ForegroundColor White Write-Host "" Write-Host "Extrahovať všetky skripty do rovnakého adresára a spustiť znova." -ForegroundColor Yellow Write-Host "" vrátenie $false } vrátenie $true }
# The Detect script is required - it gets deployed to endpoints via GPO $requiredScripts = @( "Detect-SecureBootCertUpdateStatus.ps1" )
if (-not (Test-ScriptDependencies -ScriptDirectory $PSScriptRoot -RequiredScripts $requiredScripts)) { ukončiť 1 }
# ============================================================================ # AUTOMATICKY ZISTIŤ NÁZOV DOMÉNY # ============================================================================
if (-not $DomainName) { $DomainName = $env:USERDNSDOMAIN ak (-nie $DomainName) { # Skúste získať z modulu AD vyskúšať { Import-Module ActiveDirectory – zastavenie erroraction $DomainName = (Get-ADDomain). DNSRoot } chytiť { Write-Host "CHYBA: Nepodarilo sa automaticky zistiť názov domény." -Farba popredia červená Write-Host "Please specify -DomainName parameter" (Zadajte parameter -DomainName). -ForegroundColor Yellow Write-Host "" Write-Host "Example:" -ForegroundColor Gray Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName contoso.com -AutoDetectOU" -ForegroundColor White ukončiť 1 } } Write-Host "Automaticky zistená doména: $DomainName" -ForegroundColor Green }
# Set CollectionSharePath default if not explicitly provided if (-not $PSBoundParameters.ContainsKey('CollectionSharePath')) { $CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs" }
Write-Host "============================================" -ForegroundColor Cyan Write-Host "Secure Boot Collection - GPO Deployment" -ForegroundColor Cyan Write-Host "============================================" -Azúrová farba popredia
# Validate prerequisites Write-Host "'n[1/6] Overujú sa predpoklady... -Farba popredia žltá
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) { throw "ActiveDirectory modul sa nenašiel. Nainštalujte nástroje RSAT." }
if (-not (Get-Module -ListAvailable -Name GroupPolicy)) { throw "GroupPolicy modul sa nenašiel. Nainštalujte nástroje RSAT." }
Import-Module ActiveDirectory Import-Module GroupPolicy
# Validate domain connectivity vyskúšať { $domain = Get-ADDomain -Server $DomainName Write-Host " Pripojené k doméne: $($domain. DNSRoot)" -ForegroundColor Green } chytiť { hodiť "Nedá sa pripojiť k doméne: $DomainName. Chyba: $_" }
# Handle OU selection ak ($AutoDetectOU) { Write-Host "'n Discovering OUs in domain..." -ForegroundColor Cyan $allOUs = Get-ADOrganizationalUnit -Filter * -Server $DomainName | Sort-Object DistinguishedName | Select-Object @{N='Index'; E={0}}, názov, rozlišujúci názov # Priradiť indexy for ($i = 0; $i -lt $allOUs.Count; $i++) { $allOUs[$i]. Index = $i + 1 } Write-Host "'n Dostupné OUs:" -Farba popredia žltá Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray $allOUs | ForEach-Object { Write-Host (" {0,3}) {1}" -f $_. Index, $_. DistinguishedName) -Farba popredia Biela } Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray Write-Host " Tip: Zadajte čísla oddelené čiarkou a vyberte viacero OU (napr. 1,3,5)" -ForegroundColor DarkGray Write-Host " Enter 'A' to select ALL OUs" -ForegroundColor DarkGray Write-Host "" $selection = Read-Host " Select OU(s) to link GPO" if ($selection -eq 'A' -or $selection -eq 'a') { $OUPath = $allOUs.DistinguishedName Write-Host " Selected ALL $($OUPath.Count) OUs" -ForegroundColor Green } else { $indices = $selection -split ',' | ForEach-Object { [int]$_. Trim() } $OUPath = @() foreach ($idx in $indices) { $selected = $allOUs | Where-Object { $_. Index -eq $idx } ak ($selected) { $OUPath += $selected. DistinguishedName } else { Write-Warning "Neplatný index: $idx - vynecháva sa" } } } if ($OUPath.Count -eq 0) { hodiť "Nie sú vybraté žiadne jednotky OU. Ruší sa." } Write-Host "'n Selected $($OUPath.Count) OU(s):" -ForegroundColor Green $OUPath | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray } } elseif (-not $OUPath -or $OUPath.Count -eq 0) { hodiť "Buď -OUPath alebo -AutoDetectOU musí byť zadaný." } else { # Overte, či existuje každá ÚP foreach ($path in $OUPath) { vyskúšať { $ou = Get-ADOrganizationalUnit -Identity $path -Server $DomainName Write-Host " Target OU found: $($ou. Name)" -ForegroundColor Green } chytiť { hodiť "OU nenašla: $path" } } }
# Validate source script exists if (-not (Test-Path $ScriptSourcePath)) { throw "Kolekcia skript sa nenašiel: $ScriptSourcePath" }
# Step 2: Create collection share structure Write-Host "'n[2/6] Nastavenie zdieľania kolekcie..." -Farba popredia žltá
$sysvolScriptPath = "\\$DomainName\SYSVOL\$DomainName\Scripts\SecureBootCollection"
# Create SYSVOL script folder if (-not (Test-Path $sysvolScriptPath)) { New-Item -ItemType Directory -Path $sysvolScriptPath -Force | Hodnota out-null Write-Host " Created SYSVOL script folder: $sysvolScriptPath" -ForegroundColor Green }
# Copy collection script to SYSVOL $destScript = Join-Path $sysvolScriptPath "Detect-SecureBootCertUpdateStatus.ps1"
# Remove existing destination if it's a directory (fix for Copy-Item bug) if (Test-Path $destScript -PathType Container) { Remove-Item $destScript -Recurse -Force }
Copy-Item -Path $ScriptSourcePath -Destination $destScript -Force Write-Host " Skopírovaný skript kolekcie do SYSVOL" -ForegroundColor Green
# Create a wrapper script that calls the main script with parameters $wrapperScript = @" # Obal udalosti zabezpečeného spustenia # Automaticky generované Deploy-GPO-SecureBootCollection.ps1
`$ErrorActionPreference = 'SilentlyContinue'
# Configuration '$CollectionShare = '$CollectionSharePath' '$ScriptPath = '$sysvolScriptPath\Detect-SecureBootCertUpdateStatus.ps1'
# Run collection with -OutputPath parameter if (Testovacia cesta "$ScriptPath) { & '$ScriptPath -OutputPath '$CollectionShare } else { Write-EventLog -LogName Application -Source "SecureBootCollection" -EventId 1001 -EntryType Error -Message "Kolekcia skript sa nenašiel: '$ScriptPath" } " @
$wrapperPath = Join-Path $sysvolScriptPath "Run-SecureBootCollection.ps1" $wrapperScript | Out-File -FilePath $wrapperPath -kódovanie UTF8 -Force Write-Host "Created wrapper script" -ForegroundColor Green
# Create collection share (if on a file server) Write-Host " Cesta zdieľania kolekcie: $CollectionSharePath" -ForegroundColor Cyan Write-Host " POZNÁMKA: Uistite sa, že toto zdieľanie existuje s prístupom na zápis domain computers" -ForegroundColor Yellow
# Step 3: Create the GPO Write-Host "'n[3/6] Creating skupinová politika Object..." -ForegroundColor Yellow
# Check if GPO already exists $existingGPO = Get-GPO -Name $GPOName -Domain $DomainName -ErrorAction SilentlyContinue
if ($existingGPO) { Write-Host objekt GPO "$GPOName" už existuje. Aktualizuje sa... -Farba popredia žltá $gpo = $existingGPO } else { $gpo = New-GPO -Name $GPOName -Domain $DomainName -Comment "Deploys Secure Boot event collection script to endpoints" Write-Host " Created GPO: $GPOName" -ForegroundColor Green }
# Step 4: Configure Scheduled Task via GPO Preferences Write-Host "'n[4/6] Konfigurácia naplánovanej úlohy..." -Farba popredia žltá
# Build the scheduled task XML # RandomDelay šíri spustenie cez koncové body, aby sa zabránilo preťaženiu servera Write-Host " Náhodné oneskorenie: $RandomDelayHours hodín (rozloženie zaťaženia cez flotilu)" -ForegroundColor Cyan
$taskTrigger = switch ($Schedule) { "Denne" { @" <CalendarTrigger> <StartBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary> <povolené>true</Enabled> <ScheduleByDay> <DaysInterval>1</DaysInterval> </ScheduleByDay> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </CalendarTrigger> "@ } "Týždenne" { @" <CalendarTrigger> <StartBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary> <povolené>true</Enabled> <ScheduleByWeek> <WeeksInterval>1</WeeksInterval> <DaysOfWeek> <streda /> </DaysOfWeek> </ScheduleByWeek> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </CalendarTrigger> "@ } "AtStartup" { # Pri spúšťačoch pri spustení použite na pridanie náhodného času spustenia oneskorenie # Každý počítač začne medzi 5 a (5 + RandomDelayHours*60) minút po štarte $maxDelayMinutes = 5 + ($RandomDelayHours * 60) @" <BootTrigger> <Povolené>pravda</Povolené> <</Delay>PT5M> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </BootTrigger> "@ } }
$scheduledTaskXML = @" <?xml version="1.0" encoding="UTF-16"?> <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Popis>zhromažďuje údaje udalostí zabezpečeného spustenia pre sčítanie podnikových</Popis> <</Author>Enterprise Security> </RegistrationInfo> >spúšťačov < $taskTrigger </Triggers> <principals> <principal id="Author"> <UserId>S-1-5-18</UserId> <</RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> >nastavení < <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>false</StopOnIdleEnd> <>RestartOnIdle>false</RestartOnIdle </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Povolené>pravdivé</Povolené> <Skryté></Skryté> <RunOnlyIfIdle>false</RunOnlyIfIdle> <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>powershell.exe</Command> <Argumenty>-NoProfile -ExecutionPolicy Bypass -Súbor "$wrapperPath"</Argumenty> </Exec> </Actions> </Task> " @
# Save task XML to SYSVOL for reference/backup $taskXmlPath = Join-Path $sysvolScriptPath "SecureBootCollection-Task.xml" $scheduledTaskXML | Out-File -FilePath $taskXmlPath -Kódovanie Unicode -Force Write-Host " Saved scheduled task XML to SYSVOL (backup)" -ForegroundColor Green
# Inject scheduled task into GPO Preferences Write-Host " Injektuje plánovanú úlohu do predvolieb OBJEKTU GPO..." -PopredieColor Azúrová
$gpoId = $gpo.Id.ToString() $gpoPrefPath = "\\$DomainName\SYSVOL\$DomainName\Policies\{$gpoId}\Machine\Preferences\ScheduledTasks"
# Create Preferences folder structure if (-not (Test-Path $gpoPrefPath)) { New-Item -ItemType Directory -Path $gpoPrefPath -Force | Hodnota out-null }
# Generate unique GUID for the task $taskGuid = [guid]::NewGuid(). ToString("B"). ToUpper()
# Build GPO Preferences ScheduledTasks.xml format # Toto sa líši od štandardného súboru XML Plánovač úloh – je to formát GPP $gppScheduledTasksXml = @" <?xml version="1.0" encoding="utf-8"?> <ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"> <TaskV2 clsid="{D8896631-B747-47a7-84A6-C155337F3BC8}" name="SecureBoot-EventCollection" image="0" changed="$(Get-Date -Format 'rrrr-MM-dd HH:mm:ss')" uid="$taskGuid" userContext="0" removePolicy="0"> <Properties action="C" name="SecureBoot-EventCollection" runAs="NT AUTHORITY\System" logonType="S4U"> <task version="1.3"> <RegistrationInfo> <Author>Enterprise Security</Author> <Popis>zhromažďuje stav certifikátu zabezpečeného spustenia na monitorovanie súladu podniku</Description> </RegistrationInfo> <principals> <principal id="Author"> <UserId>NT AUTHORITY\System</UserId> <LogonType>S4U</LogonType> <</RunLevel>HighestAvailable</RunLevel> </Principal> ></Principals >nastavení < <idleSettings> <Trvanie>PT10M</Trvanie> <WaitTimeout>PT1H</WaitTimeout> <StopOnIdleEnd>false</StopOnIdleEnd> <>RestartOnIdle>false</RestartOnIdle ></IdleSettings <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable> <AllowStartOnDemand>true</AllowStartOnDemand> <Povolené>pravda</Povolené> <Skryté></Skryté> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <>spúšťačov $taskTrigger </Triggers> <Actions Context="Author"> <Exec> <command>powershell.exe</Command> <Argumenty>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Argumenty> </Exec> </Actions> </Task> ></Properties ></TaskV2 ></ScheduledTasks " @
# Write GPP ScheduledTasks.xml to GPO $gppXmlPath = Join-Path $gpoPrefPath "ScheduledTasks.xml" $gppScheduledTasksXml | Out-File -FilePath $gppXmlPath -kódovanie UTF8 -Force Write-Host " [OK] Naplánovaná úloha sa vloží do objektu GPO" -ForegroundColor Green Write-Host " Plán úlohy: $Schedule v $ScheduleTime s náhodným oneskorením $RandomDelayHours hodiny" -Farba popredia sivá
# Step 5: Link GPO to OU(s) Write-Host "'n[5/6] Prepájanie objektu GPO s jednotkami OU... -Farba popredia žltá
$linkedCount = 0 $skippedCount = 0
foreach ($targetOU in $OUPath) { $existingLink = Get-GPInheritance -Target $targetOU -Domain $DomainName | Select-Object -ExpandProperty GpoLinks | Where-Object { $_. DisplayName -eq $GPOName }
if (-not $existingLink) { New-GPLink -Name $GPOName -Target $targetOU -Domain $DomainName -LinkEnabled Yes | Hodnota out-null Write-Host " [OK] Prepojené na: $targetOU" -ForegroundColor Green $linkedCount+ + } else { Write-Host " - Už prepojené: $targetOU" -ForegroundColor Yellow $skippedCount + + } }
Write-Host "`n Summary: $linkedCount new links, $skippedCount already existed" -ForegroundColor Cyan
# Step 6: Create WMI Filter (optional - for Windows 10/11 only) Write-Host "'n[6/6] Creating WMI filter..." -ForegroundColor Yellow
$wmiFilterName = "Windows 10 and 11 Workstations" $wmiQuery = 'SELECT * FROM Win32_OperatingSystem WHERE Verzia LIKE "10.%" AND ProductType = "1"'
Write-Host @" [POZNÁMKA] VOLITEĽNÉ: Vytvorenie filtra WMI v objekte GPMC Názov filtra: $wmiFilterName Dotaz: $wmiQuery Týmto sa filtruje objekt GPO tak, aby sa vzťahoval iba na pracovné stanice Windows 10/11.
"@ -ForegroundColor Yellow
# Summary Write-Host "'n============================================" -Azúrová farba popredia Write-Host "DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host "============================================" -Azúrová farba popredia Write-Host @"
Summary: - Názov objektu GPO: $GPOName - Cieľová OU: $OUPath - Zdieľanie kolekcie: $CollectionSharePath - Umiestnenie skriptu: $sysvolScriptPath - Plán: $Schedule na $ScheduleTime
Next Steps: 1. Vytvorte zdieľanie kolekcie so správnymi povoleniami: - Zdieľanie: $CollectionSharePath - Povolenia: Domain Computers (Write), Domain Admins (Full)
2. Complete the scheduled task configuration in GPMC (see instructions above)
3. Run 'gpupdate /force' on a test machine to verify deployment
4. Monitor collection results in: $CollectionSharePath
5. Run aggregation script to generate reports: .\Aggregate-SecureBootData.ps1 -InputPath "$CollectionSharePath"
"@ -ForegroundColor White