Скопіюйте та вставте цей зразок сценарію та змініть його за потреби для свого середовища:

<# . ПІДСУМОК     Сценарій розгортання GPO для колекції подій безпечного завантаження     Створення та зв'язує об'єкт групової політики для розгортання сценарію колекції як запланованого завдання

.DESCRIPTION     Цей сценарій автоматизує розгортання колекції подій безпечного завантаження за допомогою Групова політика.Створюється об'єкт групової мережі з:     – заплановане завдання, яке щоденно запускає сценарій колекції;     - Належні дозволи на запис до центральної спільної     - Фільтри WMI для націлювання певних версій ОС

.PARAMETER GPOName     Ім'я нового об'єкту групової замовлення

.PARAMETER DomainName     FQDN цільового домену

.PARAMETER OUPath     Відмітне ім'я підрозділу для зв'язування об'єктної об'єктної роботи.Приймає кілька OUs як масив. Не потрібно, якщо вказано параметр -AutoDetectOU.

.PARAMETER AutoDetectOU     Перейдіть до інтерактивного списку та виберіть OUs зі служби Active Directory.Якщо вказано, –OUPath необов'язковий.

.PARAMETER CollectionSharePath     UNC-шлях, у якому зберігатимуться результати колекції

.PARAMETER ScriptSourcePath     Шлях, у якому зберігається сценарій колекції (буде скопійовано до SYSVOL)

.PARAMETER RandomDelayHours     Кількість годин для випадкового поширення виконання сценарію в кінцевих точках.Це запобігає одночасному запису на спільний доступ на всіх комп'ютерах.За замовчуванням: 4 години. Припустимий діапазон: 1-24 години.     Рекомендовані значення:     - 1-10K-пристрої: 4 години (за замовчуванням)     - 10K-50K пристроїв: 8 годин     - 50K+ пристроїв: 12-24 години

.EXAMPLE     .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath "OU=Workstations,DC=contoso,DC=com"

.EXAMPLE     .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath "OU=Workstations,DC=contoso,DC=com" -RandomDelayHours 8

.EXAMPLE     .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -AutoDetectOU     Список усіх OUs у домені та запит на вибір.     

.EXAMPLE     .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath @("OU=Workstations,DC=contoso,DC=com", "OU=Laptops,DC=contoso,DC=com")     Зв'язує GPO з кількома OUs в одному запуску.     

.NOTES     Потрібен модуль Active Directory PowerShell, модуль Групова політика     Має бути запущено з правами на Admin домену або делегованими правами на створення об'єктів групових викликів #>

[CmdletBinding()] param(     [Parameter(Mandatory = $false)]     [string]$GPOName = "SecureBoot-EventCollection",     [Parameter(Mandatory = $false)]     [string]$DomainName,     [Parameter(Mandatory = $false)]     [string[]]$OUPath,     [Parameter(Mandatory = $false)]     [switch]$AutoDetectOU,     [Parameter(Mandatory = $false)]     [string]$CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs",     [Parameter(Mandatory = $false)]     [string]$ScriptSourcePath = ".\Detect-SecureBootCertUpdateStatus.ps1",     [Parameter(Mandatory = $false)]     [ValidateSet("Daily", "Weekly", "AtStartup")]     [string]$Schedule = "Щоденно",     [Parameter(Mandatory = $false)]     [string]$ScheduleTime = "14:00",     [Parameter(Mandatory = $false)]     [Перевірити рангу(1, 24)]     [int]$RandomDelayHours = 4 )                                        

#Requires -Modules ActiveDirectory, GroupPolicy #Requires версії 5.1

$ErrorActionPreference = "Stop" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Зразки розгортання та моніторингу"

# ============================================================================ # ПЕРЕВІРКА ЗАЛЕЖНОСТІ # ============================================================================

function Test-ScriptDependencies {     param(         [Parameter(Mandatory = $true)]         [string]$ScriptDirectory,         [Parameter(Mandatory = $true)]         [string[]]$RequiredScripts     )     $missingScripts = @()     foreach ($script in $RequiredScripts) {         $scriptPath = Join-Path $ScriptDirectory $script         якщо (-not (test-path $scriptPath)) {             $missingScripts += $script         } (})     } (})     якщо ($missingScripts.Count -gt 0) {         Write-Host ""         Write-Host ("=" * 70) -ForegroundColor Red         Write-Host "ВІДСУТНІ ЗАЛЕЖНОСТІ" - Червоний колір переднього плану         Write-Host ("=" * 70) - Червоний колір переднього плану         Write-Host ""         Write-Host "Не знайдено такі необхідні сценарії:" -ForegroundColor Yellow         foreach ($script in $missingScripts) {             Write-Host " - $script" -ForegroundColor White         } (})         Write-Host ""         Write-Host "Завантажте останні сценарії з:" -ForegroundColor Cyan         Write-Host " URL-адреса: $DownloadUrl" -ForegroundColor White         Write-Host " Перейти до: "$DownloadSubPage"" -ForegroundColor White         Write-Host ""         Write-Host "Видобути всі сценарії до одного каталогу та запустити знову". -ForegroundColor Yellow         Write-Host ""         повернути $false     } (})     повернути $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)) {     вихід 1 }

# ============================================================================ # АВТОВИЯВИЗНАЧЕННЯ ІМЕНІ ДОМЕНУ # ============================================================================

if (-not $DomainName) {     $DomainName = $env:USERDNSDOMAIN     якщо (-не $DomainName) {         # Спробуйте отримати з модуля AD         спробуйте {             Import-Module ActiveDirectory – зупинка дії помилки             $DomainName = (Get-ADDomain). DNSRoot         } зловити {             Write-Host "ПОМИЛКА: не вдалося автоматично виявити ім'я домену". -ForegroundColor Red             Write-Host "Укажіть параметр -DomainName". -ForegroundColor Yellow             Write-Host ""             Write-Host "Приклад:" -ForegroundColor Gray             Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName contoso.com -AutoDetectOU" -ForegroundColor White             вихід 1         } (})     } (})     Write-Host "Автоматично виявлений домен: $DomainName" -ForegroundColor Green }

# Set CollectionSharePath default if not explicitly provided якщо (-не $PSBoundParameters.ContainsKey('CollectionSharePath')) {     $CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs" }

Write-Host "============================================" -ForegroundColor Cyan Write-Host "Secure Boot Collection - GPO Deployment" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan

# Validate prerequisites Write-Host "'n[1/6] Перевірка передумов..." -ForegroundColor Yellow

if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {     throw "Модуль ActiveDirectory не знайдено. Інсталюйте інструменти RSAT." }

if (-not (Get-Module -ListAvailable -Name GroupPolicy)) {     throw "Модуль GroupPolicy не знайдено. Інсталюйте інструменти RSAT." }

Import-Module ActiveDirectory Import-Module Групова політика

# Validate domain connectivity спробуйте {     $domain = Get-ADDomain -Server $DomainName     Write-Host " Підключено до домену: $($domain. DNSRoot)" -ForegroundColor Green } зловити {     throw "Не вдалося підключитися до домену: $DomainName. Помилка: $_" }

# Handle OU selection якщо ($AutoDetectOU) {     Write-Host "'n Discovering OUs in domain..." -ForegroundColor Cyan     $allOUs = Get-ADOrganizationalUnit -Filter * -Server $DomainName |          Sort-Object Відмітне ім'я |         Select-Object @{N="Індекс"; E={0}}, ім'я, відмітна назва     # Призначення індексів     для ($i = 0; $i -lt $allOUs.Count; $i++) {         $allOUs[$i]. Індекс = $i + 1     } (})     Write-Host "'n Available OUs:" -ForegroundColor Yellow     Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray     $allOUs | ForEach-Object {         Write-Host (" {0,3}) {1}" -f $_. Індекс, $_. DistinguishedName) – білий колір переднього плану     } (})     Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray     Write-Host " Порада. Введіть числа, розділені комами, щоб вибрати кілька OUs (наприклад, 1,3,5)" -ForegroundColor DarkGray     Write-Host " Enter "A", щоб вибрати ALL OUs" -ForegroundColor DarkGray     Write-Host ""     $selection = Read-Host " Виберіть OU(и), щоб зв'язати GPO"     якщо ($selection -eq 'A' -або $selection -eq 'a') {         $OUPath = $allOUs.DistinguishedName         Write-Host " Selected ALL $($OUPath.Count) OUs" -ForegroundColor Green     } інакше {         $indices = $selection -split "", | ForEach-Object { [int]$_. Trim() }         $OUPath = @()         foreach ($idx in $indices) {             $selected = $allOUs | Where-Object { $_. Індекс –eq $idx }             якщо ($selected) {                 $OUPath += $selected. Відмітна назва             } інакше {                 Write-Warning "Неприпустимий індекс: $idx - пропуск"             } (})         } (})     } (})     якщо ($OUPath.Count -eq 0) {         throw "No OUs selected.                          Перервано".     } (})          Write-Host "'n Selected $($OUPath.Count) OU(s):" -ForegroundColor Green     $OUPath | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray }      } elseif (-not $OUPath -або $OUPath.Count -eq 0) {     throw "Потрібно вказати -OUPath або -AutoDetectOU." } інакше {     # Перевірка наявності кожного підрозділу     foreach ($path in $OUPath) {         спробуйте {             $ou = Get-ADOrganizationalUnit -Identity $path -Server $DomainName             Write-Host " Цільовий підрозділу знайдено: $($ou. Name)" -ForegroundColor Green         } зловити {             throw "OU не знайдено: $path"         } (})     } (}) }

# Validate source script exists якщо (-not (test-path $ScriptSourcePath)) {     throw "Сценарій колекції не знайдено: $ScriptSourcePath" }

# Step 2: Create collection share structure Write-Host "'n[2/6] Налаштування спільної колекції..." -ForegroundColor Yellow

$sysvolScriptPath = "\\$DomainName\SYSVOL\$DomainName\Scripts\SecureBootCollection"

# Create SYSVOL script folder якщо (-not (test-path $sysvolScriptPath)) {     New-Item -ItemType Directory – шлях $sysvolScriptPath -Force | Out-Null     Write-Host " Створено папку сценаріїв SYSVOL: $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) якщо (тестовий $destScript -PathType контейнер) {     Remove-Item $destScript -Recurse -Force }

Copy-Item -Path $ScriptSourcePath -Destination $destScript -Force Write-Host " Скопійований сценарій колекції до SYSVOL" -ForegroundColor Green

# Create a wrapper script that calls the main script with parameters $wrapperScript = @" # Secure Boot Event Collection Wrapper # Автоматично створений Deploy-GPO-SecureBootCollection.ps1

`$ErrorActionPreference = 'SilentlyContinue'

# Configuration '$CollectionShare = '$CollectionSharePath' '$ScriptPath = '$sysvolScriptPath\Detect-SecureBootCertUpdateStatus.ps1'

# Run collection with -OutputPath parameter якщо (тестовий шлях "$ScriptPath) {     & '$ScriptPath -OutputPath '$CollectionShare } інакше {     Write-EventLog -LogName Application -Source "SecureBootCollection" -EventId 1001 -EntryType Error -Message "Сценарій колекції не знайдено: "$ScriptPath" } (}) " @

$wrapperPath = Join-Path $sysvolScriptPath "Run-SecureBootCollection.ps1" $wrapperScript | Out-File -FilePath $wrapperPath -Encoding UTF8 -Force Write-Host " Created wrapper script" -ForegroundColor Green

# Create collection share (if on a file server) Write-Host " Шлях спільного доступу до колекції: $CollectionSharePath" -ForegroundColor Cyan Write-Host " ПРИМІТКА. Переконайтеся, що ця спільна ресурс існує з доступом до запису "Доменні комп'ютери" -ForegroundColor Yellow

# Step 3: Create the GPO Write-Host "'n[3/6] Створення об'єкта Групова політика..." -ForegroundColor Yellow

# Check if GPO already exists $existingGPO = Get-GPO - Name $GPOName -Domain $DomainName -ErrorAction SilentlyContinue

if ($existingGPO) {     Write-Host " GPO "$GPOName" уже існує. Триває оновлення..." – жовтий колір переднього плану     $gpo = $existingGPO } інакше {     $gpo = New-GPO - Name $GPOName -Domain $DomainName -Comment "Deploys Secure Boot event script to endpoints"     Write-Host " Створено групову фразу: $GPOName" -ForegroundColor Green }

# Step 4: Configure Scheduled Task via GPO Preferences Write-Host "'n[4/6] Настроювання запланованого завдання..." -ForegroundColor Yellow

# Build the scheduled task XML # RandomDelay поширюється на кінцеві точки, щоб запобігти перевантаженню сервера Write-Host " Випадкова затримка: $RandomDelayHours годин (поширюється навантаження по флоту)" -ForegroundColor Cyan

$taskTrigger = switch ($Schedule) {     "Щоденно" {         @"         <>>"< календарів"           <startBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary>           <увімкнуто>true</Enabled>           <ScheduleByDay>             <днівInterval>1</DaysInterval>           </ScheduleByDay>           <RandomDelay>PT${RandomDelayHours}H</RandomDelay>         </CalendarTrigger> "@     } (})     "Щотижнево" {         @"         <>>"< календарів"           <Початкова>2024-01-01T${ScheduleTime}:00</StartBoundary>           <увімкнуто>true</Enabled>           <> ScheduleByWeek             <тижнівInterval>1</WeeksInterval>             <>"День тижня"               <середу />             </DaysOfWeek>           </ScheduleByWeek>           <RandomDelay>PT${RandomDelayHours}H</RandomDelay>         </CalendarTrigger> "@     } (})     "AtStartup" {         # Для тригерів запуску використовуйте функцію Delay (Затримка), щоб додати випадковий час початку.         # Кожен комп'ютер запускається між 5 і (5 + RandomDelayHours *60) хвилин після завантаження         $maxDelayMinutes = 5 + ($RandomDelayHours * 60)         @"         <>BootTrigger           <увімкнуто>true</Enabled>           <затримка>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>     <Опис>збирає дані події безпечного завантаження для корпоративного перепису</Description>     <автор><корпоративної безпеки /автор>   </RegistrationInfo>   тригери <>     $taskTrigger   </Triggers>  >принципалів <     <principal id="Author">       <ідентифікатор користувача>S-1-5-18</UserId>       <runLevel>HighestAvailable</RunLevel>     </>принципала   </Principals>  >настройок <     <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>     <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>     <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>     <AllowHardTerminate>true</AllowHardTerminate>     <початокВиявний>true</StartWhenAvailable>     <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>     <>IdleSettings       <StopOnIdleEnd>false</StopOnIdleEnd>       <RestartOnIdle>false</RestartOnIdle>     </IdleSettings>     <AllowStartOnDemand>true</AllowStartOnDemand>     <Увімкнуто>true</Enabled>     <приховані>false</Hidden>     <RunOnlyIfIdle>false</RunOnlyIfIdle>     <ЗаборонитиStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>     <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>     <WakeToRun>false</WakeToRun>     <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>     <пріоритет>7</Priority>   </Settings>   <actions Context="Author">     <Exec>       <команд>powershell.exe</Command>       <аргументи>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Arguments>     </Exec>   </Actions> </> завдань " @

# Save task XML to SYSVOL for reference/backup $taskXmlPath = Join-Path $sysvolScriptPath "SecureBootCollection-Task.xml" $scheduledTaskXML | Out-File -FilePath $taskXmlPath -Encoding Юнікод -Force Write-Host " Saved scheduled task XML to SYSVOL (backup)" -ForegroundColor Green

# Inject scheduled task into GPO Preferences Write-Host "Ін'єкція запланованого завдання в GPO Preferences..." -ForegroundColor Cyan

$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 – шлях $gpoPrefPath -Force | Out-Null }

# Generate unique GUID for the task $taskGuid = [GUID]::NewGuid(). ToString("B"). ToUpper()

# Build GPO Preferences ScheduledTasks.xml format # Це відрізняється від стандартного XML планувальника завдань – це формат 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="0"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')» uid="$taskGuid" userContext="0" removePolicy="0">     <Properties action="C" name="SecureBoot-EventCollection" runAs="NT AUTHORITY\System" logonType="S4U">       <версія завдання="1.3">         <RegistrationInfo>           <автор><корпоративної безпеки /Автор>           <Опис>збирає стан сертифіката безпечного завантаження для моніторингу відповідності корпоративному</Description>         </RegistrationInfo>        >принципалів <           <principal id="Author">             <UserId>NT AUTHORITY\System</UserId>             <LogonType>S4U</LogonType>             <runLevel>HighestAvailable</RunLevel>           </principal>         </Principals>        >настройок <           <>idleSettings             <тривалість>PT10M</тривалість>             <waitTimeout>PT1H</WaitTimeout>             <StopOnIdleEnd>false</StopOnIdleEnd>             <RestartOnIdle>false</RestartOnIdle>           </IdleSettings>           <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>           <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>           <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>           <AllowHardTerminate>true</AllowHardTerminate>           <початокУвімніть,>true</StartWhenAvailable>           <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>           <AllowStartOnDemand>true</AllowStartOnDemand>           <увімкнуто>true</Enabled>           <прихований>false</Hidden>           <RunOnlyIfIdle>false</RunOnlyIfIdle>           <WakeToRun>false</WakeToRun>           <executionTimeLimit>PT1H</ExecutionTimeLimit>           <пріоритет>7</Priority>         </Settings>         тригери <>           $taskTrigger         </Triggers>         <actions Context="Author">           <Exec>            >powershell.exe<команд </Command>             <аргументи>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Arguments>           </Exec>         </Actions>       </> завдань     </Properties>   </TaskV2> </ScheduledTasks> " @

# Write GPP ScheduledTasks.xml to GPO $gppXmlPath = Join-Path $gpoPrefPath "ScheduledTasks.xml" $gppScheduledTasksXml | Out-File -FilePath $gppXmlPath -Encoding UTF8 -Force Write-Host " [OK] Заплановане завдання вводиться в GPO" -ForegroundColor Green Write-Host " Розклад завдань: $Schedule на $ScheduleTime з випадковою затримкою $RandomDelayHours години" -ForegroundColor Gray

# Step 5: Link GPO to OU(s) Write-Host "'n[5/6] Зв'язування GPO з OU(и)..." -ForegroundColor Yellow

$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 Так | Out-Null         Write-Host " [OK] Пов'язано з: $targetOU" -ForegroundColor Green         $linkedCount++     } інакше {         Write-Host " – уже зв'язано: $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] Створення фільтра WMI..." -ForegroundColor Yellow

$wmiFilterName = "Windows 10 and 11 Workstations" $wmiQuery = "SELECT * FROM Win32_OperatingSystem WHERE VERSION LIKE "10.%" AND ProductType = "1""

Write-Host @"    [ПРИМІТКА] НЕОБОВ'ЯЗКОВО: Створення фільтра WMI у консолі керування груповими політиками (GPMC)    Ім'я фільтра: $wmiFilterName    Запит: $wmiQuery    Це фільтрує об'єкт групової безпеки, який застосовуватиметься лише до робочих станцій Windows 10/11.            

"@ -ForegroundColor Yellow

# Summary Write-Host "'n============================================" -ForegroundColor Cyan Write-Host "РОЗГОРТАННЯ ЗАВЕРШЕНО" - Зелений колір переднього плану Write-Host "============================================" -ForegroundColor Cyan Write-Host @"

Summary: - Ім'я об'єктної об'єктної об'єкт $GPOName ної об'єкт - Цільовий підрозділу: $OUPath - Спільний доступ до колекції: $CollectionSharePath - Розташування сценарію: $sysvolScriptPath - розклад: $Schedule за адресою $ScheduleTime

Next Steps: 1. Створіть спільний доступ до колекції з відповідними дозволами:    - Спільний доступ: $CollectionSharePath    - Дозволи: доменні комп'ютери (записування), адміністратори домену (повний)

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  

​​​​​​​

Потрібна додаткова довідка?

Потрібні додаткові параметри?

Ознайомтеся з перевагами передплати, перегляньте навчальні курси, дізнайтесь, як захистити свій пристрій тощо.