คัดลอกและวางสคริปต์ตัวอย่างนี้และปรับเปลี่ยนตามที่จําเป็นสําหรับสภาพแวดล้อมของคุณ:
<# . คําพ้องความหมาย สคริปต์การปรับใช้ GPO สําหรับคอลเลกชันเหตุการณ์การบูตแบบปลอดภัย สร้างและเชื่อมโยง GPO เพื่อปรับใช้สคริปต์คอลเลกชันเป็นงานที่กําหนดเวลาไว้
.DESCRIPTION สคริปต์นี้ทําให้การปรับใช้คอลเลกชันเหตุการณ์ Secure Boot ผ่านนโยบายกลุ่มเป็นไปโดยอัตโนมัติซึ่งจะสร้าง GPO ด้วย: - งานที่กําหนดเวลาไว้ซึ่งเรียกใช้สคริปต์คอลเลกชันทุกวัน - สิทธิ์ที่เหมาะสมสําหรับการเขียนไปยังส่วนกลางที่ใช้ร่วมกัน - ตัวกรอง WMI สําหรับการกําหนดเป้าหมายเวอร์ชันระบบปฏิบัติการที่เฉพาะเจาะจง
.PARAMETER GPOName ชื่อสําหรับ GPO ใหม่
.PARAMETER DomainName FQDN โดเมนเป้าหมาย
.PARAMETER OUPath ชื่อเฉพาะของ OU เพื่อเชื่อมโยง GPO ไปยอมรับ U หลายรายการเป็นอาร์เรย์ ไม่จําเป็นต้องระบุถ้ามีการระบุ -AutoDetectOU
.PARAMETER AutoDetectOU สลับไปยังรายการแบบโต้ตอบและเลือก U จาก 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 แสดงรายการ U ทั้งหมดในโดเมนและพร้อมท์สําหรับการเลือก
.EXAMPLE .\Deploy-GPO-SecureBootCollection.ps1 -DomainName "contoso.com" -OUPath @("OU=Workstations,DC=contoso,DC=com", "OU=Laptops,DC=contoso,DC=com") ลิงก์ GPO กับหลาย U ในครั้งเดียว
.NOTES จําเป็นต้องมี: โมดูล Active Directory PowerShell, มอดูลนโยบายกลุ่ม ต้องรันด้วยสิทธิ์การสร้าง GPO Admin โดเมนหรือที่ได้รับมอบสิทธิ์ #>
[CmdletBinding()] param( [พารามิเตอร์(บังคับ = $false)] [สตริง]$GPOName = "SecureBoot-EventCollection", [พารามิเตอร์(บังคับ = $false)] [string]$DomainName, [พารามิเตอร์(บังคับ = $false)] [string[]]$OUPath, [พารามิเตอร์(บังคับ = $false)] [switch]$AutoDetectOU, [พารามิเตอร์(บังคับ = $false)] [string]$CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs", [พารามิเตอร์(บังคับ = $false)] [string]$ScriptSourcePath = ".\Detect-SecureBootCertUpdateStatus.ps1", [พารามิเตอร์(บังคับ = $false)] [ValidateSet("Daily", "Weekly", "AtStartup")] [สตริง]$Schedule = "รายวัน", [พารามิเตอร์(บังคับ = $false)] [สตริง]$ScheduleTime = "14:00", [พารามิเตอร์(บังคับ = $false)] [ValidateRange(1, 24)] [int]$RandomDelayHours = 4 )
#Requires -Modules ActiveDirectory, GroupPolicy #Requires -เวอร์ชัน 5.1
$ErrorActionPreference = "Stop" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "ตัวอย่างการปรับใช้และการตรวจสอบ"
# ============================================================================ # การตรวจสอบการขึ้นต่อกัน # ============================================================================
function Test-ScriptDependencies { param( [พารามิเตอร์(บังคับ = $true)] [string]$ScriptDirectory, [พารามิเตอร์(บังคับ = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script ใน $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 "ไม่พบสคริปต์ที่จําเป็นต่อไปนี้:" -ForegroundColor Yellow foreach ($script ใน $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 if (-not $DomainName) { # ลองดาวน์โหลดจากมอดูล AD ลอง { Import-Module ActiveDirectory -ErrorAction Stop $DomainName = (Get-ADDomain) DNSRoot } จับ { Write-Host "ERROR: ไม่สามารถตรวจหาชื่อโดเมนโดยอัตโนมัติได้" -ForegroundColor Red Write-Host "โปรดระบุพารามิเตอร์ -DomainName" -ForegroundColor Yellow Write-Host "" Write-Host "ตัวอย่าง:" -สีพื้นหน้าสีเทา 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 if (-not $PSBoundParameters.ContainsKey('CollectionSharePath')) { $CollectionSharePath = "\\$DomainName\NETLOGON\SecureBootLogs" }
Write-Host "============================================" -ForegroundColor Cyan Write-Host "คอลเลกชันการบูตแบบปลอดภัย - การปรับใช้ GPO" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan
# Validate prerequisites Write-Host "'n[1/6] การตรวจสอบข้อกําหนดเบื้องต้น..." -ForegroundColor สีเหลือง
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) { โยน "ไม่พบโมดูล ActiveDirectory ติดตั้งเครื่องมือ RSAT" }
if (-not (Get-Module -ListAvailable -Name GroupPolicy)) { โยน "ไม่พบโมดูล GroupPolicy ติดตั้งเครื่องมือ RSAT" }
Import-Module ActiveDirectory Import-Module GroupPolicy
# Validate domain connectivity ลอง { $domain = Get-ADDomain -Server $DomainName Write-Host " เชื่อมต่อกับโดเมน: $($domain DNSRoot)" -ForegroundColor Green } จับ { ส่ง "ไม่สามารถเชื่อมต่อกับโดเมน: $DomainName ข้อผิดพลาด: $_" }
# Handle OU selection if ($AutoDetectOU) { Write-Host "'n Discovering OU ในโดเมน..." -ForegroundColor Cyan $allOUs = Get-ADOrganizationalUnit -Filter * -Server $DomainName | Sort-Object DistinguishedName | Select-Object @{N='Index'; E={0}}, ชื่อ, DistinguishedName # กําหนดดัชนี for ($i = 0; $i -lt $allOUs.count; $i++) { $allOUs[$i] ดัชนี = $i + 1 } Write-Host "'n มี OU:" -ForegroundColor สีเหลือง Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray $allOUs | ForEach-Object { Write-Host (" {0,3}) {1}" -f $_. ดัชนี, $_. DistinguishedName) -ForegroundColor White } Write-Host " ---------------------------------------------------------------------" -ForegroundColor DarkGray Write-Host " เคล็ดลับ: ใส่ตัวเลขที่คั่นด้วยเครื่องหมายจุลภาคเพื่อเลือก U หลายตัว (เช่น 1,3,5)" -ForegroundColor DarkGray Write-Host " Enter 'A' เพื่อเลือก ALL OU" -ForegroundColor DarkGray Write-Host "" $selection = Read-Host " เลือก OU เพื่อลิงก์ GPO" if ($selection -eq 'A' -or $selection -eq 'a') { $OUPath = $allOUs.DistinguishedName Write-Host " OU $($OUPath.Count) ที่เลือก" -ForegroundColor Green } อื่น { $indices = $selection -split ',' | ForEach-Object { [int]$_. ตัดแต่ง() } $OUPath = @() foreach ($idx ใน $indices) { $selected = $allOUs | Where-Object { $_. ดัชนี -eq $idx } if ($selected) { $OUPath += $selected DistinguishedName } อื่น { Write-Warning "ดัชนีไม่ถูกต้อง: $idx - ข้าม" } } } if ($OUPath.Count -eq 0) { โยน "ไม่มี OU ที่เลือก กําลังยกเลิก" } Write-Host "'n ที่เลือก $($OUPath.Count) OU:" -ForegroundColor Green $OUPath | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray } } elseif (-not $OUPath -or $OUPath.Count -eq 0) { โยน "ต้องระบุ -OUPath หรือ -AutoDetectOU" } อื่น { # ตรวจสอบความถูกต้องของแต่ละ OU ที่มีอยู่ foreach ($path ใน $OUPath) { ลอง { $ou = Get-ADOrganizationalUnit -Identity $path -Server $DomainName Write-Host " พบ OU เป้าหมาย: $($ou Name)" -ForegroundColor Green } จับ { โยน "ไม่พบ OU: $path" } } }
# Validate source script exists if (-not (Test-Path $ScriptSourcePath)) { ส่ง "ไม่พบสคริปต์คอลเลกชัน: $ScriptSourcePath" }
# Step 2: Create collection share structure Write-Host "'n[2/6] การตั้งค่าการแชร์คอลเลกชัน..." -ForegroundColor สีเหลือง
$sysvolScriptPath = "\\$DomainName\SYSVOL\$DomainName\Scripts\SecureBootCollection"
# Create SYSVOL script folder if (-not (Test-Path $sysvolScriptPath)) { New-Item -ItemType Directory -Path $sysvolScriptPath -Force | ItemType Directory 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) if (Test-Path $destScript -PathType Container) { 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 Wrapper # สร้างโดยอัตโนมัติโดย Deploy-GPO-SecureBootCollection.ps1
`$ErrorActionPreference = 'SilentlyContinue'
# Configuration '$CollectionShare = '$CollectionSharePath' '$ScriptPath = '$sysvolScriptPath\Detect-SecureBootCertUpdateStatus.ps1'
# Run collection with -OutputPath parameter if (Test-Path '$ScriptPath) { & '$ScriptPath -OutputPath '$CollectionShare } อื่น { Write-EventLog -LogName Application -Source "SecureBootCollection" -EventId 1001 -EntryType Error -Message "Collection script not found: '$ScriptPath" } " @
$wrapperPath = Join-Path $sysvolScriptPath "Run-SecureBootCollection.ps1" $wrapperScript | Out-File -FilePath $wrapperPath -Encoding UTF8 -Force Write-Host " สร้างสคริปต์ wrapper" -ForegroundColor Green
# Create collection share (if on a file server) Write-Host " เส้นทางการแชร์คอลเลกชัน: $CollectionSharePath" -ForegroundColor Cyan Write-Host " หมายเหตุ: ตรวจสอบให้แน่ใจว่ามีการใช้ร่วมกันนี้ด้วยการเข้าถึงการเขียน "คอมพิวเตอร์โดเมน" -ForegroundColor สีเหลือง
# Step 3: Create the GPO Write-Host "'n[3/6] การสร้างวัตถุ นโยบายกลุ่ม..." -ForegroundColor สีเหลือง
# 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 collection script to endpoints" Write-Host " สร้าง GPO: $GPOName" -ForegroundColor Green }
# Step 4: Configure Scheduled Task via GPO Preferences Write-Host "'n[4/6] การกําหนดค่างานที่จัดกําหนดการ..." -ForegroundColor สีเหลือง
# Build the scheduled task XML # RandomDelay กระจายการดําเนินการข้ามจุดสิ้นสุดเพื่อป้องกันเซิร์ฟเวอร์เกินพิกัด Write-Host " การหน่วงเวลาแบบสุ่ม: $RandomDelayHours ชั่วโมง (สเปรดโหลดข้ามกองเรือ)" -ForegroundColor Cyan
$taskTrigger = switch ($Schedule) { "รายวัน" { @" >CalendarTrigger < <StartBoundary>2024-01-01T${ScheduleTime}:00</StartBoundary> <เปิดใช้งาน>true</Enabled> <ScheduleByDay> <Days>1</DaysInterval> </ScheduleByDay> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> </calendarTrigger> "@ } "รายสัปดาห์" { @" >CalendarTrigger < <StartBoundary>2024-01-01T${ScheduleTime}:00</startBoundary> <เปิดใช้งาน>true</Enabled> >ScheduleByWeek < <WeeksInterval>1</WeeksInterval> >วัน <สัปดาห์ <วันพุธ /> ></DaysOfWeek </ScheduleByWeek> <RandomDelay>PT${RandomDelayHours}H</RandomDelay> ></CalendarTrigger "@ } "AtStartup" { # สําหรับทริกเกอร์เริ่มต้น ใช้ หน่วงเวลา เพื่อเพิ่มเวลาเริ่มต้นแบบสุ่ม # แต่ละเครื่องจะเริ่มต้นระหว่าง 5 และ (5 + RandomDelayHours*60) นาทีหลังจากการบูต $maxDelayMinutes = 5 + ($RandomDelayHours * 60) @" >BootTrigger < <Enabled>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 ของ < >คําอธิบาย <เก็บรวบรวมข้อมูลเหตุการณ์การบูตแบบปลอดภัยสําหรับ</คําอธิบายขององค์กร> </Author>Enterprise Security>ผู้เขียน < ></RegistrationInfo >ทริกเกอร์ < $taskTrigger > </ทริกเกอร์ >หลัก < <principal id="Author"> <UserId>S-1-5-18</UserId> <>RunLevel สูงสุดที่พร้อมใช้งาน</RunLevel> </> หลัก ></Principals > การตั้งค่า < <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries><เท็จ /DisallowStartIfOnBatteries> <StopIfGoingOnBatteries><เท็จ /StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable> > <IdleSettings <StopOnIdleEnd><ที่ไม่ถูกต้อง /StopOnIdleEnd> <RestartOnIdle><ที่ไม่ถูกต้อง /RestartOnIdle> ></IdleSettings <AllowStartOnDemand>true</AllowStartOnDemand> <เปิดใช้งาน>true</Enabled> <>false ที่ซ่อน</> ที่ซ่อนอยู่ <RunOnlyIfIdle><เท็จ /RunOnlyIfIdle> <ไม่อนุญาต StartOnRemoteAppSession><เท็จ /DisallowStartOnRemoteAppSession> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> <>ระดับความสําคัญ>7</ลําดับความสําคัญ </> การตั้งค่า <การกระทํา บริบท="ผู้เขียน"> > <Exec <Command>powershell.exe</command> อาร์กิวเมนต์ <>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Arguments> </Exec> </แอคชัน> </> งาน " @
# Save task XML to SYSVOL for reference/backup $taskXmlPath = Join-Path $sysvolScriptPath "SecureBootCollection-Task.xml" $scheduledTaskXML | Out-File -FilePath $taskXmlPath -Encoding Unicode -Force Write-Host " บันทึกงานที่จัดกําหนดการ XML ไปยัง SYSVOL (สํารองข้อมูล)" -ForegroundColor Green
# Inject scheduled task into GPO Preferences Write-Host " ใส่งานที่จัดกําหนดการลงในการกําหนดลักษณะ GPO..." -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 # แตกต่างจาก Task Scheduler 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=""$(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"> <Task version="1.3"> >RegistrationInfo ของ < <</Author>Enterprise Security>/Author> <คําอธิบาย>เก็บรวบรวมสถานะใบรับรองการบูตแบบปลอดภัยสําหรับการตรวจสอบการปฏิบัติตามข้อบังคับขององค์กร</คําอธิบาย> ></RegistrationInfo > หลัก < <id หลัก="ผู้เขียน"> <UserId>NT AUTHORITY\System</UserId> <LogonType><S4U /LogonType> <RunLevel>สูงสุดที่พร้อมใช้งาน</RunLevel> </> หลัก </principals> > การตั้งค่า < > <IdleSettings ระยะเวลา <>PT10M</Duration> <WaitTimeout></WaitTimeout> <<false <StopOnIdleEnd>/StopOnIdleEnd> <RestartOnIdle><ที่ไม่ถูกต้อง /RestartOnIdle> ></IdleSettings <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries><เท็จ /DisallowStartIfOnBatteries> <StopIfGoingOnBatteries><เท็จ /StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable> <AllowStartOnDemand>true</AllowStartOnDemand> <เปิดใช้งาน>true</Enabled> <<false>ซ่อน /> ที่ซ่อนอยู่ <RunOnlyIfIdle><ที่ไม่ถูกต้อง /RunOnlyIfIdle> <WakeToRun><เท็จ /WakeToRun> <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> >ระดับความสําคัญ <7</ลําดับความสําคัญ> </> การตั้งค่า >ทริกเกอร์ < $taskTrigger > </ทริกเกอร์ การดําเนินการ <Context="Author"> >exec < >powershell.exe<คําสั่ง </> คําสั่ง อาร์กิวเมนต์ <>-NoProfile -ExecutionPolicy Bypass -File "$wrapperPath"</Arguments> </Exec> </แอคชัน> </> งาน ></คุณสมบัติ > </TaskV2 ></ScheduledTasks " @
# Write GPP ScheduledTasks.xml to GPO $gppXmlPath = Join-Path $gpoPrefPath "ScheduledTasks.xml" $gppScheduledTasksXml | Out-File -FilePath $gppXmlPath -Encoding UTF8 -Force Write-Host " [ตกลง] งานที่จัดกําหนดการจะใส่ลงใน 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 สีเหลือง
$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 | Out-Null Write-Host " [ตกลง] ลิงก์ไปยัง: $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 สีเหลือง
$wmiFilterName = "Windows 10 and 11 Workstations" $wmiQuery = 'SELECT * จาก Win32_OperatingSystem ที่เวอร์ชัน เช่น "10.%" และ ProductType = "1"'
Write-Host @" [หมายเหตุ] ไม่บังคับ: สร้างตัวกรอง WMI ใน GPMC ชื่อตัวกรอง: $wmiFilterName คิวรี: $wmiQuery ซึ่งจะกรอง GPO เพื่อนําไปใช้กับเวิร์กสเตชัน Windows 10/11 เท่านั้น
"@ -ForegroundColor Yellow
# Summary Write-Host "'n============================================" -ForegroundColor Cyan Write-Host "การปรับใช้เสร็จสมบูรณ์" -ForegroundColor สีเขียว Write-Host "============================================" -ForegroundColor Cyan Write-Host @"
Summary: - ชื่อ GPO: $GPOName - OU เป้าหมาย: $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