Bir Windows ortamında yüzlerce bilgisayarı yönetiyorsanız, Group Policy nesnelerini GUI üzerinden tek tek düzenlemek hem zaman kaybı hem de hata riski demektir. PowerShell ve komut satırı araçlarıyla GPO yönetimini otomatize ettiğinizde, saatler süren işleri dakikalar içinde bitirirsiniz. Bu yazıda, gerçek dünya senaryolarından yola çıkarak GPO yönetiminin komut satırı tarafını derinlemesine inceleyeceğiz.
Temel Hazırlık: GroupPolicy Modülü
Başlamadan önce, PowerShell’de GPO yönetimi için GroupPolicy modülünün yüklü olması gerekiyor. Bu modül, Remote Server Administration Tools (RSAT) paketinin bir parçasıdır.
# RSAT GroupPolicy araçlarını yükle (Windows 10/11)
Add-WindowsCapability -Online -Name "Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0"
# Windows Server üzerinde
Install-WindowsFeature -Name GPMC
# Modülün yüklü olup olmadığını kontrol et
Get-Module -ListAvailable -Name GroupPolicy
# Modülü içe aktar
Import-Module GroupPolicy
Modülü yükledikten sonra, Get-Command -Module GroupPolicy komutuyla kullanabileceğiniz tüm cmdlet’leri listeleyebilirsiniz. Şu an itibarıyla bu modül 25’ten fazla cmdlet içeriyor ve neredeyse her GPO işlemini komut satırından yapmanıza olanak tanıyor.
GPO Listeleme ve Sorgulama
Ortamdaki mevcut GPO’ları listelemek en temel operasyonlardan biridir. Özellikle büyük kurumlarda yüzlerce GPO birikmiş olabilir ve hangisinin ne işe yaradığını bulmak başlı başına bir iş haline gelebilir.
# Domain'deki tüm GPO'ları listele
Get-GPO -All
# Belirli bir GPO'yu ismiyle sorgula
Get-GPO -Name "Default Domain Policy"
# GPO'nun GUID'ini kullanarak sorgula
Get-GPO -Guid "31B2F340-016D-11D2-945F-00C04FB984F9"
# GPO bilgilerini detaylı görüntüle
Get-GPO -Name "Workstation Security Policy" | Format-List *
# Tüm GPO'ları oluşturulma tarihiyle birlikte listele
Get-GPO -All | Select-Object DisplayName, CreationTime, ModificationTime | Sort-Object ModificationTime -Descending
Gerçek bir senaryoyu ele alalım: Şirkette güvenlik denetimi yapıyorsunuz ve “son 6 ayda hiç değiştirilmemiş GPO’lar hangileri?” sorusunun cevabını arıyorsunuz. Bu tür GPO’lar ya eski ve kullanılmayan nesneler ya da güncellenmesi gereken politikalar olabilir.
# Son 6 ayda değiştirilmemiş GPO'ları bul
$altıAyOnce = (Get-Date).AddMonths(-6)
Get-GPO -All | Where-Object { $_.ModificationTime -lt $altıAyOnce } |
Select-Object DisplayName, ModificationTime, GpoStatus |
Sort-Object ModificationTime
GPO Oluşturma ve Silme
Yeni bir GPO oluşturmak son derece basittir. Ama gerçek gücü, bu işlemi bir döngüyle birleştirip toplu oluşturma yaptığınızda görürsünüz.
# Yeni boş bir GPO oluştur
New-GPO -Name "Laptop Security Policy" -Comment "Dizüstü bilgisayarlar için güvenlik politikası"
# Mevcut bir GPO'dan kopyalayarak yeni GPO oluştur
Copy-GPO -SourceName "Workstation Security Policy" -TargetName "Laptop Security Policy"
# GPO'yu Starter GPO'dan oluştur
New-GPO -Name "New Branch Office Policy" -StarterGpoName "Workstations Starter GPO"
# Birden fazla şube ofisi için toplu GPO oluşturma
$subeler = @("Istanbul", "Ankara", "Izmir", "Bursa", "Antalya")
foreach ($sube in $subeler) {
New-GPO -Name "$sube Branch Policy" -Comment "$sube şubesi politikası - $(Get-Date -Format 'yyyy-MM-dd')"
Write-Host "$sube için GPO oluşturuldu." -ForegroundColor Green
}
# GPO silme (dikkatli kullanın!)
Remove-GPO -Name "Eski Politika" -Confirm:$false
Dikkat: Remove-GPO komutu geri alınamaz. Silmeden önce mutlaka yedek alın veya en azından GPO’yu önce devre dışı bırakın.
GPO Bağlantıları: Link Yönetimi
Bir GPO oluşturmak yetmez, onu uygun OU’lara bağlamanız gerekir. GPO link yönetimi, ortam değişikliklerinde sık yapılan operasyonlardan biridir.
# GPO'yu bir OU'ya bağla
New-GPLink -Name "Laptop Security Policy" -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local"
# GPO bağlantısını belirli bir öncelikle oluştur (düşük sayı = yüksek öncelik)
New-GPLink -Name "Laptop Security Policy" -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local" -LinkEnabled Yes -Order 1
# Mevcut bağlantıyı güncelle
Set-GPLink -Name "Laptop Security Policy" -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local" -Enforced Yes
# Bağlantıyı devre dışı bırak (silmeden)
Set-GPLink -Name "Laptop Security Policy" -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local" -LinkEnabled No
# Bağlantıyı kaldır
Remove-GPLink -Name "Laptop Security Policy" -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local"
# Bir OU'ya bağlı tüm GPO'ları listele
Get-GPInheritance -Target "OU=Laptops,OU=Computers,DC=sirket,DC=local"
Gerçek dünya senaryosu: Yeni bir şube ofisi açıldı, hızlıca ilgili GPO’ları doğru OU’lara bağlamanız gerekiyor.
# Şube ofisi için hızlı GPO deployment scripti
$subeAdi = "Istanbul"
$subeOU = "OU=$subeAdi,OU=SubeOfisleri,DC=sirket,DC=local"
$gpoListesi = @(
"Branch Office Security Policy",
"Branch Office Software Restrictions",
"Branch Office Printer Settings"
)
foreach ($gpo in $gpoListesi) {
try {
New-GPLink -Name $gpo -Target $subeOU -LinkEnabled Yes
Write-Host "[$gpo] --> [$subeOU] baglantisi olusturuldu." -ForegroundColor Green
}
catch {
Write-Host "Hata: $($_.Exception.Message)" -ForegroundColor Red
}
}
Registry Tabanlı Politika Ayarları
GPO’ların büyük çoğunluğu registry değerlerini yönetir. PowerShell’de Set-GPRegistryValue ve Get-GPRegistryValue cmdlet’leriyle bu değerleri doğrudan ayarlayabilirsiniz.
# Kullanıcıların Control Panel'a erişimini engelle
Set-GPRegistryValue -Name "Workstation Security Policy" `
-Key "HKCUSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer" `
-ValueName "NoControlPanel" `
-Type DWord `
-Value 1
# Screensaver timeout süresini ayarla (saniye cinsinden, 600 = 10 dakika)
Set-GPRegistryValue -Name "Workstation Security Policy" `
-Key "HKCUSoftwarePoliciesMicrosoftWindowsControl PanelDesktop" `
-ValueName "ScreenSaveTimeOut" `
-Type String `
-Value "600"
# Mevcut registry değerini sorgula
Get-GPRegistryValue -Name "Workstation Security Policy" `
-Key "HKCUSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer" `
-ValueName "NoControlPanel"
# Registry değerini kaldır
Remove-GPRegistryValue -Name "Workstation Security Policy" `
-Key "HKCUSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer" `
-ValueName "NoControlPanel"
# USB storage cihazlarını devre dışı bırak
Set-GPRegistryValue -Name "USB Restriction Policy" `
-Key "HKLMSYSTEMCurrentControlSetServicesUSBSTOR" `
-ValueName "Start" `
-Type DWord `
-Value 4
Toplu Registry Ayarları Uygulama
Bir CSV dosyasından okuyarak toplu registry politikası ayarlamak, büyük ortamlarda hayat kurtarır.
# registry_policies.csv formatı:
# GPOName,Key,ValueName,Type,Value
# policy_settings.csv dosyasından ayarları oku ve uygula
$ayarlar = Import-Csv -Path "C:Scriptspolicy_settings.csv"
foreach ($ayar in $ayarlar) {
try {
Set-GPRegistryValue -Name $ayar.GPOName `
-Key $ayar.Key `
-ValueName $ayar.ValueName `
-Type $ayar.Type `
-Value $ayar.Value
Write-Host "Ayar uygulandı: $($ayar.ValueName)" -ForegroundColor Green
}
catch {
Write-Host "Hata - $($ayar.ValueName): $($_.Exception.Message)" -ForegroundColor Red
}
}
GPO Raporlama ve Dokümantasyon
Denetim ve dokümantasyon amaçlı GPO raporları üretmek sysadmin’in rutin görevlerinden biridir. Özellikle ISO 27001 veya PCI DSS gibi standartlara uyumluluk süreçlerinde bu raporlar kritik önem taşır.
# Tek bir GPO için HTML raporu oluştur
Get-GPOReport -Name "Default Domain Policy" -ReportType Html -Path "C:ReportsDefaultDomainPolicy.html"
# Tüm GPO'lar için XML raporu oluştur
Get-GPOReport -All -ReportType Xml -Path "C:ReportsAllGPOs.xml"
# Tüm GPO'lar için ayrı ayrı HTML raporu oluştur
$raporKlasoru = "C:GPO_Reports$(Get-Date -Format 'yyyyMMdd')"
New-Item -ItemType Directory -Path $raporKlasoru -Force | Out-Null
Get-GPO -All | ForEach-Object {
$dosyaAdi = $_.DisplayName -replace '[\/:*?"<>|]', '_'
$raporYolu = "$raporKlasoru$dosyaAdi.html"
Get-GPOReport -Name $_.DisplayName -ReportType Html -Path $raporYolu
Write-Host "Rapor oluşturuldu: $dosyaAdi.html"
}
Write-Host "`nTüm raporlar $raporKlasoru klasörüne kaydedildi." -ForegroundColor Green
GPRESULT ve RSoP: Politika Uygulamasını Doğrulama
Bir politikanın gerçekten uygulanıp uygulanmadığını anlamak, sorun gidermenin ilk adımıdır. gpresult komutu bu noktada vazgeçilmezdir.
# Mevcut kullanıcı ve bilgisayar için özet RSoP raporu
gpresult /r
# Detaylı HTML raporu oluştur
gpresult /h "C:Reportsrsop_report.html" /f
# Belirli bir kullanıcı için rapor
gpresult /user DOMAINkullanici /r
# Uzak bir bilgisayar için rapor
gpresult /s UZAKBILGISAYAR /r
# Hangi GPO'ların uygulandığını ve hangilerinin filtrelendiğini gör
gpresult /r /scope computer
gpresult /r /scope user
# PowerShell ile RSoP verilerini parse et
$rsopSonuc = gpresult /r 2>&1
$rsopSonuc | Select-String "Applied Group Policy"
GPUPDATE ile Politika Yenileme
# Yerel makinede politikaları hemen yenile
gpupdate /force
# Sadece bilgisayar politikalarını yenile
gpupdate /target:computer /force
# Sadece kullanıcı politikalarını yenile
gpupdate /target:user /force
# PowerShell üzerinden uzak bilgisayarlarda politika yenileme
Invoke-GPUpdate -Computer "PC001" -Force -RandomDelayInMinutes 0
# Bir OU'daki tüm bilgisayarlarda toplu gpupdate
$bilgisayarlar = Get-ADComputer -Filter * -SearchBase "OU=Laptops,OU=Computers,DC=sirket,DC=local" |
Select-Object -ExpandProperty Name
foreach ($bilgisayar in $bilgisayarlar) {
try {
Invoke-GPUpdate -Computer $bilgisayar -Force -RandomDelayInMinutes 0 -AsJob
Write-Host "$bilgisayar - GPUpdate gönderildi" -ForegroundColor Green
}
catch {
Write-Host "$bilgisayar - Hata: $($_.Exception.Message)" -ForegroundColor Red
}
}
GPO Yedekleme ve Geri Yükleme
Değişiklik yapmadan önce yedek almak altın kural. Bir GPO değişikliği tüm domain kullanıcılarını etkileyebileceğinden, rollback planı her zaman hazır olmalı.
# Tek bir GPO'yu yedekle
Backup-GPO -Name "Default Domain Policy" -Path "C:GPO_Backups"
# Tüm GPO'ları yedekle (en sağlıklı yaklaşım)
$yedekKlasoru = "C:GPO_Backups$(Get-Date -Format 'yyyyMMdd_HHmm')"
New-Item -ItemType Directory -Path $yedekKlasoru -Force | Out-Null
Backup-GPO -All -Path $yedekKlasoru
Write-Host "Tüm GPO'lar yedeklendi: $yedekKlasoru" -ForegroundColor Green
# Yedekleri listele
Get-GPOBackup -All -Path "C:GPO_Backups20240115_1430" |
Select-Object DisplayName, BackupID, Timestamp |
Format-Table -AutoSize
# Belirli bir GPO'yu geri yükle
Restore-GPO -Name "Default Domain Policy" -Path "C:GPO_Backups20240115_1430"
# GUID ile geri yükle
Restore-GPO -BackupGpoName "Workstation Security Policy" `
-Path "C:GPO_Backups20240115_1430"
# Tüm GPO'ları geri yükle (felaket kurtarma senaryosu)
Restore-GPO -All -Path "C:GPO_Backups20240115_1430"
Otomatik Yedekleme Scripti
Bu scripti Task Scheduler’a günlük çalışacak şekilde ekleyebilirsiniz.
# C:ScriptsGPO_AutoBackup.ps1
Import-Module GroupPolicy
$yedekKoku = "C:GPO_Backups"
$yedekKlasoru = "$yedekKoku$(Get-Date -Format 'yyyyMMdd')"
$logDosyasi = "$yedekKokubackup_log.txt"
$saklaGunSayisi = 30
# Yedek klasörü oluştur
New-Item -ItemType Directory -Path $yedekKlasoru -Force | Out-Null
# GPO'ları yedekle
try {
$sonuc = Backup-GPO -All -Path $yedekKlasoru
$mesaj = "$(Get-Date): $($sonuc.Count) GPO yedeklendi --> $yedekKlasoru"
Add-Content -Path $logDosyasi -Value $mesaj
Write-Host $mesaj -ForegroundColor Green
}
catch {
$hata = "$(Get-Date): HATA - $($_.Exception.Message)"
Add-Content -Path $logDosyasi -Value $hata
Write-Host $hata -ForegroundColor Red
}
# 30 günden eski yedekleri temizle
Get-ChildItem -Path $yedekKoku -Directory |
Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$saklaGunSayisi) } |
ForEach-Object {
Remove-Item -Path $_.FullName -Recurse -Force
Add-Content -Path $logDosyasi -Value "$(Get-Date): Eski yedek silindi: $($_.Name)"
}
WMI Filtreleri: Hedefli GPO Uygulaması
WMI filtreleri, GPO’ların belirli koşulları karşılayan makinelere uygulanmasını sağlar. Komut satırından WMI filtresi oluşturmak biraz daha karmaşıktır ama otomasyona çok değer katar.
# WMI filtresi oluştur (Windows 10 x64 makineler için)
$wmiFiltre = New-Object Microsoft.GroupPolicy.WmiFilter
# GPMC COM nesnesi üzerinden WMI filtresi oluşturma
# Alternatif: LDAP üzerinden doğrudan WMI filtresi ekle
$domain = Get-ADDomain
$wmiFilterPath = "CN=SOM,CN=WMIPolicy,CN=System,$($domain.DistinguishedName)"
$filtreAdi = "Windows 10 x64 Filter"
$filtreAciklama = "Yalnızca Windows 10 64-bit sistemlere uygulanır"
$wmiSorgu = 'SELECT * FROM Win32_OperatingSystem WHERE Version LIKE "10.%" AND OSArchitecture = "64-bit"'
# GPO'ya WMI filtresi bağlamak için Set-GPWmiFilter kullanılır
# (Bu işlem genellikle GPMC PowerShell extensions gerektirir)
# Pratik alternatif: ADSISearcher ile mevcut WMI filtrelerini listele
$searcher = [ADSISearcher]"(objectClass=msWMI-Som)"
$searcher.SearchRoot = [ADSI]"LDAP://$wmiFilterPath"
$searcher.FindAll() | ForEach-Object {
Write-Host "Filtre: $($_.Properties['msWMI-Name'])"
Write-Host "Sorgu: $($_.Properties['msWMI-Parm2'])`n"
}
Pratik Senaryo: Güvenlik Sıkılaştırma Scripti
Bir SOC ekibinin talebiyle tüm workstation’lara güvenlik politikası uygulamanız gerekiyor. İşte gerçek hayatta kullanabileceğiniz bütünleşik bir script:
# C:ScriptsApply_Security_GPO.ps1
# Workstation güvenlik sıkılaştırma politikası uygulama scripti
Import-Module GroupPolicy
Import-Module ActiveDirectory
$gpoAdi = "Workstation Security Hardening 2024"
$hedefOU = "OU=Workstations,DC=sirket,DC=local"
$yedekKlasoru = "C:GPO_BackupsPreChange_$(Get-Date -Format 'yyyyMMdd_HHmm')"
# Adım 1: Önce yedek al
Write-Host "Adım 1: Mevcut GPO'lar yedekleniyor..." -ForegroundColor Yellow
New-Item -ItemType Directory -Path $yedekKlasoru -Force | Out-Null
Backup-GPO -All -Path $yedekKlasoru
Write-Host "Yedek tamamlandı: $yedekKlasoru" -ForegroundColor Green
# Adım 2: GPO oluştur veya mevcut olanı al
Write-Host "`nAdım 2: GPO hazırlanıyor..." -ForegroundColor Yellow
$mevcutGPO = Get-GPO -Name $gpoAdi -ErrorAction SilentlyContinue
if (-not $mevcutGPO) {
$gpo = New-GPO -Name $gpoAdi -Comment "SOC talebiyle oluşturuldu - $(Get-Date -Format 'yyyy-MM-dd')"
Write-Host "Yeni GPO oluşturuldu: $gpoAdi" -ForegroundColor Green
} else {
$gpo = $mevcutGPO
Write-Host "Mevcut GPO kullanılıyor: $gpoAdi" -ForegroundColor Cyan
}
# Adım 3: Güvenlik ayarlarını uygula
Write-Host "`nAdım 3: Güvenlik ayarları uygulanıyor..." -ForegroundColor Yellow
# SMBv1'i devre dışı bırak
Set-GPRegistryValue -Name $gpoAdi -Key "HKLMSYSTEMCurrentControlSetServicesmrxsmb10" -ValueName "Start" -Type DWord -Value 4
# Autorun'u devre dışı bırak
Set-GPRegistryValue -Name $gpoAdi -Key "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesExplorer" -ValueName "NoDriveTypeAutoRun" -Type DWord -Value 255
# Windows Firewall'u etkinleştir
Set-GPRegistryValue -Name $gpoAdi -Key "HKLMSOFTWAREPoliciesMicrosoftWindowsFirewallDomainProfile" -ValueName "EnableFirewall" -Type DWord -Value 1
# Remote Desktop için NLA zorunlu kıl
Set-GPRegistryValue -Name $gpoAdi -Key "HKLMSOFTWAREPoliciesMicrosoftWindows NTTerminal Services" -ValueName "UserAuthentication" -Type DWord -Value 1
Write-Host "Güvenlik registry değerleri ayarlandı." -ForegroundColor Green
# Adım 4: GPO'yu OU'ya bağla
Write-Host "`nAdım 4: GPO OU'ya bağlanıyor..." -ForegroundColor Yellow
$mevcutLink = Get-GPInheritance -Target $hedefOU |
Select-Object -ExpandProperty GpoLinks |
Where-Object { $_.DisplayName -eq $gpoAdi }
if (-not $mevcutLink) {
New-GPLink -Name $gpoAdi -Target $hedefOU -LinkEnabled Yes
Write-Host "GPO bağlantısı oluşturuldu." -ForegroundColor Green
} else {
Write-Host "GPO zaten bağlı, atlanıyor." -ForegroundColor Cyan
}
# Adım 5: Rapor oluştur
Write-Host "`nAdım 5: Değişiklik raporu oluşturuluyor..." -ForegroundColor Yellow
$raporYolu = "C:ReportsSecurityGPO_$(Get-Date -Format 'yyyyMMdd_HHmm').html"
Get-GPOReport -Name $gpoAdi -ReportType Html -Path $raporYolu
Write-Host "Rapor oluşturuldu: $raporYolu" -ForegroundColor Green
Write-Host "`n=== İşlem Tamamlandı ===" -ForegroundColor Cyan
Write-Host "GPO: $gpoAdi" -ForegroundColor White
Write-Host "Hedef OU: $hedefOU" -ForegroundColor White
Write-Host "Yedek: $yedekKlasoru" -ForegroundColor White
Write-Host "Rapor: $raporYolu" -ForegroundColor White
Sık Yapılan Hatalar ve İpuçları
GPO yönetiminde komut satırı kullanırken dikkat edilmesi gereken birkaç kritik nokta var:
- Enforce vs Link Enable farkı:
Set-GPLink -Enforced YesileSet-GPLink -LinkEnabled Yesfarklı şeylerdir. Enforce, alt OU’lardaki Block Inheritance ayarını geçersiz kılar. - Replication gecikmesi: Bir GPO değişikliği yaptıktan sonra tüm DC’lere replikasyon tamamlanmadan
gpupdate /forceçalıştırmak tutarsız sonuçlara yol açabilir.repadmin /syncallile önce replikasyonu tamamlayın. - SYSVOL izinleri: GPO dosyaları SYSVOL’de tutulur. SYSVOL izin sorunları GPO uygulanmamasına neden olur.
sysvolklasörünün DFS-R ile düzgün replike edildiğini düzenli kontrol edin. - WMI filtresi performansı: Karmaşık WMI sorguları GPO işleme süresini uzatır. Sorguları mümkün olduğunca basit tutun.
- Değişiklik yönetimi: Her GPO değişikliği için değişiklik kaydı tutun. Script’lerinizde
-Commentparametresini kullanmayı alışkanlık haline getirin.
Sonuç
Group Policy yönetimini komut satırına taşımak, başlangıçta alışmayı gerektirse de orta ve büyük ölçekli ortamlarda sağladığı verimlilik inanılmaz boyutlara ulaşabilir. GUI üzerinden 2 saatte yapacağınız bir işi, iyi yazılmış bir PowerShell scriptiyle 10 dakikaya indirebilirsiniz. Üstelik tekrarlanabilir ve hatasız bir şekilde.
Öncelikleriniz şöyle sıralanmalı: ilk olarak test ortamında deneyin, sonra yedek alın, ardından değişikliği uygulayın ve son olarak doğrulayın. Bu döngüyü script’lerinize gömün ve GPO değişikliklerini bir mühendislik disipliniyle ele alın. Bir GPO hatası tüm domain kullanıcılarını etkileyebileceğinden, bu adımları atlamak ciddi sonuçlar doğurabilir.
Yukarıdaki script’leri kendi ortamınıza adapte ederek başlayın. OU yapınızı, domain adınızı ve politika gereksinimlerinizi güncelleyin. Zamanla kendi GPO yönetim kütüphanenizi oluşturacak ve her yeni görevde bu birikimden yararlanacaksınız.