Bu örnek betiği kopyalayıp yapıştırın ve ortamınız için gerektiği gibi değiştirin:
<# . ÖZET Güvenli Önyükleme Olay Koleksiyonu için GPO Dağıtım Betiği Koleksiyon betiğini zamanlanmış görev olarak dağıtmak için bir GPO oluşturur ve bağlar
.DESCRIPTION Bu betik, grup ilkesi aracılığıyla Güvenli Önyükleme olay koleksiyonunun dağıtımını otomatikleştirir.Aşağıdakilerle bir GPO oluşturur: - Koleksiyon betiğini günlük olarak çalıştıran zamanlanmış bir görev - Merkezi paylaşıma yazmak için uygun izinler - Belirli işletim sistemi sürümlerini hedeflemek için WMI filtreleri
.PARAMETER GPOName Yeni GPO adı
.PARAMETER DomainName Hedef etki alanı FQDN'si
.PARAMETER OUPath GPO'nun bağlanacak OU'ların Ayırt Edici Adı.Dizi olarak birden çok OU kabul eder. -AutoDetectOU belirtilirse gerekli değildir.
.PARAMETER AutoDetectOU Etkileşimli listeye geçin ve Active Directory'den OU'ları seçin.Belirtildiğinde, -OUPath isteğe bağlıdır.
.PARAMETER CollectionSharePath Koleksiyon sonuçlarının depolanacağı UNC yolu
.PARAMETER ScriptSourcePath Koleksiyon betiğinin depolandığı yol (SYSVOL'e kopyalanacak)
.PARAMETER RandomDelayHours Betik yürütmenin uç noktalara rastgele yayılması için saat sayısı.Bu, tüm makinelerin paylaşıma aynı anda yazmasını önler.Varsayılan: 4 saat. Geçerli aralık: 1-24 saat. Önerilen değerler: - 1-10K cihazlar: 4 saat (varsayılan) - 10K-50K cihazlar: 8 saat - 50K+ cihaz: 12-24 saat
.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 Etki alanındaki tüm OU'ları listeler ve seçim ister.
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath @("OU=Workstations,DC=contoso,DC=com", "OU=Laptops,DC=contoso,DC=com") GPO'yu tek bir çalıştırmada birden çok OU'ya bağlar.
.NOTES Gerekli: Active Directory PowerShell modülü, grup ilkesi modülü Etki alanı Yönetici veya temsilci GPO oluşturma haklarıyla çalıştırılmalıdır #>
[CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$GPOName = "SecureBoot-EventCollection", [Parameter(Zorunlu = $false)] [string]$DomainName, [Parameter(Zorunlu = $false)] [string[]]$OUPath, [Parameter(Zorunlu = $false)] [switch]$AutoDetectOU, [Parameter(Zorunlu = $false)] [string]$CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs", [Parameter(Zorunlu = $false)] [string]$ScriptSourcePath = ".\Detect-SecureBootCertUpdateStatus.ps1", [Parameter(Zorunlu = $false)] [ValidateSet("Daily", "Weekly", "AtStartup")] [string]$Schedule = "Daily", [Parameter(Zorunlu = $false)] [string]$ScheduleTime = "14:00", [Parametre(Zorunlu = $false)] [ValidateRange(1, 24)] [int]$RandomDelayHours = 4 )
#Requires -Modules ActiveDirectory, GroupPolicy #Requires -Sürüm 5.1
$ErrorActionPreference = "Stop" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Dağıtım ve İzleme Örnekleri"
# ============================================================================ # BAĞıMLıLıK DOĞRULAMA # ============================================================================
function Test-ScriptDependencies { param( [Parameter(Zorunlu = $true)] [string]$ScriptDirectory, [Parameter(Zorunlu = $true)] [dize[]]$RequiredScripts ) $missingScripts = @() foreach ($RequiredScripts $script) { $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 " EKSİk BAĞIMLAR" -ForegroundColor Red Write-Host ("=" * 70) -ForegroundColor Red "" Write-Host Write-Host "Aşağıdaki gerekli betikler bulunamadı:" -ForegroundColor Yellow foreach ($missingScripts $script) { Write-Host " - $script" -ForegroundColor White } "" Write-Host Write-Host "Lütfen en son betikleri indirin:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor White Write-Host " Git: '$DownloadSubPage'" -ForegroundColor White "" Write-Host Write-Host "Tüm betikleri aynı dizine ayıklayın ve yeniden çalıştırın." -ForegroundColor Yellow "" Write-Host return $false } $true döndür }
# The Detect script is required - it gets deployed to endpoints via GPO $requiredScripts = @( "Detect-SecureBootCertUpdateStatus.ps1" )
if (-not (Test-ScriptDependencies -ScriptDirectory $PSScriptRoot -RequiredScripts $requiredScripts)) { çıkış 1 }
# ============================================================================ # ETKI ALANı ADıNı OTOMATIK OLARAK ALGıLA # ============================================================================
if (-not $DomainName) { $DomainName = $env:USERDNSDOMAIN if (-not $DomainName) { # AD modülünden almayı deneyin try { Import-Module ActiveDirectory -ErrorAction Stop $DomainName = (Get-ADDomain). DNSRoot } catch { Write-Host "HATA: Etki alanı adı otomatik olarak algılanamadı." -ForegroundColor Red Write-Host "Lütfen -DomainName parametresini belirtin." -ForegroundColor Yellow "" Write-Host Write-Host "Örnek:" -ForegroundColor Gray Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName contoso.com -AutoDetectOU" -ForegroundColor White çıkış 1 } } Write-Host "Otomatik algılanan etki alanı: $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 "Güvenli Önyükleme Koleksiyonu - GPO Dağıtımı" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan
# Validate prerequisites Write-Host "'n[1/6] Önkoşullar doğrulanıyor..." -ForegroundColor Yellow
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) { throw "ActiveDirectory modülü bulunamadı. RSAT araçlarını yükleyin." }
if (-not (Get-Module -ListAvailable -Name GroupPolicy)) { throw "GroupPolicy modülü bulunamadı. RSAT araçlarını yükleyin." }
Import-Module ActiveDirectory Import-Module GroupPolicy
# Validate domain connectivity try { $domain = Get-ADDomain -Server $DomainName Write-Host " Etki alanına bağlı: $($domain. DNSRoot)" -ForegroundColor Green } catch { throw "Etki alanına bağlanılamıyor: $DomainName. Hata: $_" }
# Handle OU selection if ($AutoDetectOU) { Write-Host "'n Etki alanında OU'ları bulma..." -ForegroundColor Cyan $allOUs = Get-ADOrganizationalUnit -Filter * -Server $DomainName | Sort-Object DistinguishedName | @{N='Index' Select-Object; E={0}}, Ad, DistinguishedName # Dizin atama for ($i = 0; $i -lt $allOUs.Count; $i++) { $allOUs[$i]. Dizin = $i + 1 } Write-Host "'n Kullanılabilir OU'lar:" -ForegroundColor Yellow Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray $allOUs | ForEach-Object { Write-Host (" {0,3}) {1}" -f $_. Dizin, $_. DistinguishedName) -ForegroundColor White } Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray Write-Host " İpucu: Birden çok OU seçmek için virgülle ayrılmış sayılar girin (ör. 1,3,5)" -ForegroundColor DarkGray Write-Host " TÜM OU'ları seçmek için 'A' girin" -ForegroundColor DarkGray "" Write-Host $selection = Read-Host " GPO'ya bağlanmak için OU'ları seçin" if ($selection -eq 'A' -veya $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 ($indices'da $idx) { $selected = $allOUs | Where-Object { $_. Index -eq $idx } if ($selected) { $OUPath += $selected. DistinguishedName } else { Write-Warning "Geçersiz dizin: $idx - atlanıyor" } } } if ($OUPath.Count -eq 0) { throw "Seçili OU yok. Durduruldu." } Write-Host "'n Selected $($OUPath.Count) OU(s):" -ForegroundColor Green $OUPath | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray } } elseif (-not $OUPath -veya $OUPath.Count -eq 0) { throw "-OUPath veya -AutoDetectOU belirtilmelidir." } else { # Her OU'nın mevcut olduğunu doğrulayın foreach ($OUPath'da $path) { try { $ou = Get-ADOrganizationalUnit -Identity $path -Server $DomainName Write-Host " Hedef OU bulundu: $($ou. Name)" -ForegroundColor Green } catch { throw "OU bulunamadı: $path" } } }
# Validate source script exists if (-not (Test-Path $ScriptSourcePath)) { throw "Koleksiyon betiği bulunamadı: $ScriptSourcePath" }
# Step 2: Create collection share structure Write-Host "'n[2/6] Koleksiyon paylaşımı ayarlanıyor..." -ForegroundColor Yellow
$sysvolScriptPath = "\\$DomainName\SYSVOL\$DomainName\Scripts\SecureBootCollection"
# Create SYSVOL script folder if (-not (Test-Path $sysvolScriptPath)) { New-Item -ItemType Directory -Path $sysvolScriptPath -Force | Out-Null Write-Host " SysVOL betik klasörü oluşturuldu: $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 Kapsayıcısı) { Remove-Item $destScript -Recurse -Force }
Copy-Item -Path $ScriptSourcePath -Destination $destScript -Force Write-Host " SYSVOL'e kopyalanan koleksiyon betiği" -ForegroundColor Green
# Create a wrapper script that calls the main script with parameters $wrapperScript = @" # Güvenli Önyükleme Olay Koleksiyonu Sarmalayıcısı # Deploy-GPO-SecureBootCollection.ps1 tarafından otomatik oluşturulan
`$ErrorActionPreference = 'SilentlyContinue'
# Configuration '$CollectionShare = '$CollectionSharePath' '$ScriptPath = '$sysvolScriptPath\Detect-SecureBootCertUpdateStatus.ps1'
# Run collection with -OutputPath parameter if (Test Yolu '$ScriptPath) { '$ScriptPath -OutputPath '$CollectionShare & } else { Write-EventLog -LogName Uygulaması -Source "SecureBootCollection" -EventId 1001 -EntryType Error -Message "Koleksiyon betiği bulunamadı: '$ScriptPath" } " @
$wrapperPath = Join-Path $sysvolScriptPath "Run-SecureBootCollection.ps1" $wrapperScript | Out-File -FilePath $wrapperPath -Encoding UTF8 -Force Write-Host " Sarmalayıcı betiği oluşturuldu" -ForegroundColor Green
# Create collection share (if on a file server) Write-Host " Koleksiyon paylaşım yolu: $CollectionSharePath" -ForegroundColor Cyan Write-Host " NOT: Bu paylaşımın 'Etki Alanı Bilgisayarları' yazma erişimiyle var olduğundan emin olun" -ForegroundColor Yellow
# Step 3: Create the GPO Write-Host "'n[3/6] grup ilkesi Nesnesi Oluşturuluyor..." -ForegroundColor Sarı
# Check if GPO already exists $existingGPO = Get-GPO -Name $GPOName -Domain $DomainName -ErrorAction SilentlyContinue
if ($existingGPO) { Write-Host " GPO '$GPOName' zaten var. Güncelleştiriliyor..." -ForegroundColor Yellow $gpo = $existingGPO } else { $gpo = New-GPO -Name $GPOName -Domain $DomainName -Comment "Secure Boot olay koleksiyonu betiğini uç noktalara dağıtır" Write-Host " Oluşturulan GPO: $GPOName" -ForegroundColor Green }
# Step 4: Configure Scheduled Task via GPO Preferences Write-Host "'n[4/6] Zamanlanmış görevi yapılandırıyor..." -ForegroundColor Yellow
# Build the scheduled task XML # RandomDelay, sunucu aşırı yüklemesini önlemek için yürütmeyi uç noktalara yayar Write-Host " Rastgele gecikme: $RandomDelayHours saat (yükü filoya yayar)" -ForegroundColor Cyan
$taskTrigger = switch ($Schedule) { "Günlük" { @" CalendarTrigger>< <StartBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary> <Etkin>true</Enabled> ScheduleByDay>< <DaysInterval>1</DaysInterval> </ScheduleByDay> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </CalendarTrigger> "@ } "Haftalık" { @" CalendarTrigger>< <StartBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary> <Etkin>true</Enabled> ScheduleByWeek>< <WeeksInterval>1</WeeksInterval> <DaysOfWeek> <Çarşamba /> </DaysOfWeek> </ScheduleByWeek> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </CalendarTrigger> "@ } "AtStartup" { # Başlangıç tetikleyicileri için Gecikme'yi kullanarak rastgele başlangıç zamanı ekleyin # Her makine önyüklemeden sonra 5 ile (5 + RandomDelayHours*60) dakika arasında başlar $maxDelayMinutes = 5 + ($RandomDelayHours * 60) @" BootTrigger>< <Etkin>true</Enabled> PT5M</Delay>>< Gecikme <RandomDelay>PT${RandomDelayHours}H</RandomDelay> /BootTrigger>< "@ } }
$scheduledTaskXML = @" <?xml version="1.0" encoding="UTF-16"?> <Görev sürümü="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Açıklama>Kurumsal nüfus sayımı için Güvenli Önyükleme olay verilerini toplar</Description> <Yazar>Enterprise Security</Author> </RegistrationInfo> <Tetikleyicileri> $taskTrigger </Triggers> <Sorumluları> <Principal id="Author"> <UserId>S-1-5-18</UserId> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Ayarları> <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>< <Etkin>true</Enabled> <Gizli>yanlış</Gizli> <RunOnlyIfIdle>false</RunOnlyIfIdle> <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> <Önceliği>7</Priority> </Ayarlar> <Actions Context="Author"> <Exec> <Komut>powershell.exe</Command> <Bağımsız Değişkenleri>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Arguments> </Exec> </Actions> </Task> " @
# Save task XML to SYSVOL for reference/backup $taskXmlPath = Join-Path $sysvolScriptPath "SecureBootCollection-Task.xml" $scheduledTaskXML | Out-File -FilePath $taskXmlPath -Kodlama Unicode -Force Write-Host " Zamanlanmış görev XML'i SYSVOL'e kaydedildi (yedekleme)" -ForegroundColor Green
# Inject scheduled task into GPO Preferences Write-Host " GPO Tercihlerine zamanlanmış görev eklanıyor..." -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 -Path $gpoPrefPath -Force | Out-Null }
# Generate unique GUID for the task $taskGuid = [guid]::NewGuid(). ToString("B"). ToUpper()
# Build GPO Preferences ScheduledTasks.xml format # Bu, standart Görev Zamanlayıcı XML'sinden farklıdır - GPP biçimindedir $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 'yyyy-MM-dd HH:mm:ss')" uid="$taskGuid" userContext="0" removePolicy="0"> <Properties action="C" name="SecureBoot-EventCollection" runAs="NT AUTHORITY\System" logonType="S4U"> <Görev sürümü="1.3"> <RegistrationInfo> <Yazar>Enterprise Security</Author> <Açıklaması>Kurumsal uyumluluk izleme için Güvenli Önyükleme sertifika durumunu toplar</Açıklama> </RegistrationInfo> <Sorumluları> <Principal id="Author"> <UserId>NT AUTHORITY\System</UserId> <LogonType>S4U</LogonType> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Ayarları> <IdleSettings> <Süre>PT10M</Süre> PT1H</WaitTimeout>><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>< <Etkin>true</Enabled> <Gizli>yanlış</Gizli> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> <Önceliği>7</Öncelik> </Ayarlar> <Tetikleyicileri> $taskTrigger </Triggers> <Actions Context="Author"> <Exec> <Komut>powershell.exe</Command> <Bağımsız Değişkenleri>-NoProfile -ExecutionPolicy Atlama -Dosya "$wrapperPath"</Arguments> </Exec> /Actions>< </Task> </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 " [Tamam] GPO'ya eklenen zamanlanmış görev" -ForegroundColor Green Write-Host " Görev zamanlaması: $RandomDelayHours saatlik rastgele gecikmeyle $ScheduleTime $Schedule" -ForegroundColor Gray
# Step 5: Link GPO to OU(s) Write-Host "'n[5/6] GPO'nun OU'lara bağlanması)..." -ForegroundColor Yellow
$linkedCount = 0 $skippedCount = 0
foreach ($targetOU in $OUPath) { $existingLink = Get-GPInheritance -Hedef $targetOU -Etki Alanı $DomainName | Select-Object -ExpandProperty GpoLinks | Where-Object { $_. DisplayName -eq $GPOName }
if (-not $existingLink) { New-GPLink -Name $GPOName -Target $targetOU -Domain $DomainName -LinkEnabled Yes | Out-Null Write-Host " [Tamam] Bağlı: $targetOU" -ForegroundColor Green $linkedCount++ } else { Write-Host " - Zaten bağlantılı: $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 filtresi oluşturuluyor..." -ForegroundColor Yellow
$wmiFilterName = "Windows 10 and 11 Workstations" $wmiQuery = 'SELECT * FROM Win32_OperatingSystem WHERE Version LIKE "10.%" AND ProductType = "1"'
Write-Host @" [NOT] İsteğE BAĞLI: GPMC'de WMI Filtresi oluşturma Filtre Adı: $wmiFilterName Sorgu: $wmiQuery Bu, GPO'ya yalnızca Windows 10/11 iş istasyonları için geçerli olacak şekilde filtre uygular.
"@ -ForegroundColor Yellow
# Summary Write-Host "'n============================================" -ForegroundColor Cyan Write-Host "DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host "============================================" -ForegroundColor Cyan Write-Host @"
Summary: - GPO Adı: $GPOName - Hedef OU: $OUPath - Koleksiyon Paylaşımı: $CollectionSharePath - Betik Konumu: $sysvolScriptPath - Zamanlama: $ScheduleTime'da $Schedule
Next Steps: 1. Koleksiyon paylaşımını uygun izinlerle oluşturun: - Paylaş: $CollectionSharePath - İzinler: Etki Alanı Bilgisayarları (Yazma), Etki Alanı Yöneticileri (Tam)
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