Group Policy Serisi Bölüm 8: GPO Hijyeni ve Raporlama

Merhaba

Yedi bölümde GPO’ların (Group Policy Object) nasıl çalıştığını, nasıl yazıldığını, nasıl sorun giderildiğini ve nasıl sıkılaştırıldığını gördük. Geriye en az konuşulan, ama yıllar geçtikçe en çok sorun çıkaran konu kaldı: bakım. Bir etki alanı (domain) yıllarca kullanıldığında içinde kimsenin hatırlamadığı onlarca GPO birikir. Hiçbir yere bağlı olmayanlar, içi boş olanlar, geçici diye açılıp unutulanlar, silinmiş ama bağı kalmış olanlar… Bunların her biri hem yönetimi zorlaştırır hem de saldırı yüzeyini büyütür.

Bu bölümde laboratuvarda bilerek kirli bir ortam hazırlıyor, sonra bu kirliliği PowerShell ile tespit ediyoruz. Ardından tüm GPO’ları yedekliyor, bir ayarı bozup yedekten geri yüklüyor, raporlar üretiyor, değişiklik izini güvenlik günlüğünden okuyor ve kullanılmayan bir GPO’yu güvenli sırayla siliyoruz. Serinin kapanışı olduğu için sonunda sekiz bölümün toplu özetini de bulacaksınız.

Uyarı: Bu bölümde test GPO’ları oluşturup siliyoruz ve SYSVOL (System Volume) içinde bilerek yetim bir klasör bırakıyoruz. Bunları yalnızca laboratuvarda yapın. Production (Üretim) ortamında bir GPO’yu silmeden önce mutlaka yedeğini alın, ayarlarını devre dışı bırakın ve bir süre bekleyin. Bölümün sonundaki Güvenli silme sırası bunu adım adım gösterir.

1. GPO Hijyeni Nedir, Hangi Sorunlar Birikir?

GPO hijyeni, ortamdaki GPO’ların düzenli olarak envanterinin çıkarılması, gereksizlerin temizlenmesi, yedeklerinin alınması ve değişikliklerinin izlenmesidir. Amaç az GPO değil, her GPO’nun neden var olduğunu bilmektir.

Zamanla biriken tipik sorunlar şunlardır:

Sorun Nasıl Oluşur Neden Risklidir Nasıl Bulunur
Bağlı olmayan GPO (Group Policy Object) GPO oluşturulur, hiçbir yere link edilmez ya da link sonradan kaldırılır Karışıklık yaratır. Biri yanlışlıkla bağlarsa beklenmedik ayarlar uygulanır Get-GPOReport çıktısında link sayısı 0
Boş GPO İçinde hiç ayar yoktur İşlenme süresini boşuna uzatır, ne işe yaradığı anlaşılmaz Rapordaki Computer ve User bölümleri boş
Ayarları devre dışı GPO Bilgisayar ve kullanıcı ayarları kapatılmıştır Bağlı görünür ama işlevsizdir. Bir gün yanlışlıkla açılabilir GpoStatus değeri AllSettingsDisabled
Yetim GPC (Group Policy Container) GPO’nun AD (Active Directory) parçası vardır, SYSVOL (System Volume) klasörü yoktur Ayarlar istemciye ulaşmaz, hata günlüklerinde dosya bulunamadı görülür AD ve SYSVOL listelerinin karşılaştırılması
Yetim GPT (Group Policy Template) SYSVOL klasörü vardır, AD nesnesi yoktur Eski ayarlar ve script’ler SYSVOL’de gereksiz yer kaplar ve bilgi sızdırabilir AD ve SYSVOL listelerinin karşılaştırılması
Kırık link GPO silinmiş, OU’daki (Organizational Unit) bağı kalmıştır GPMC’de (Group Policy Management Console) bulunamadı görünür, her işlemede boşuna aranır OU’ların gPLink özniteliğindeki GUID’lerin (Globally Unique Identifier) GPO listesiyle karşılaştırılması
Sürüm uyuşmazlığı AD ve SYSVOL’deki sürüm numaraları farklıdır (replikasyon sorunu) İstemciler eski ya da yarım ayar alır Get-GPO çıktısında DSVersion ve SysvolVersion farkı
Aşırı yetki Gereğinden fazla kişi GPO’yu düzenleyebilir Saldırgan bu GPO üzerinden tüm bilgisayarlara kod çalıştırabilir (Bölüm 6) Get-GPPermission taraması

Bu sorunların çoğu tek tek zararsız görünür. Ama bir olay sırasında bu GPO neden var, kim değiştirdi, geri alabilir miyiz sorularına cevap veremiyorsanız, hijyen eksikliğinin bedelini ödüyorsunuzdur.

2. Laboratuvar Planı

Aşağıda neyi, nereye ve hangi sırayla yapacağımız özetlenmiştir:

Adım Ne Yapıyoruz Nerede Hangi Hesap
1 Bilerek kirli bir ortam hazırlamak: test GPO’ları (Group Policy Object), yetim klasör, kırık link Domain controller (W25DC) Yönetici
2 Tüm GPO’ların envanterini çıkarmak Domain controller Yönetici
3 Bağlı olmayan, boş ve devre dışı GPO’ları bulmak Domain controller Yönetici
4 Yetim GPC (Group Policy Container), yetim GPT (Group Policy Template), kırık link ve sürüm uyuşmazlığını bulmak Domain controller Yönetici
5 Tüm GPO’ları yedeklemek, bir ayarı bozup geri yüklemek Domain controller Yönetici
6 HTML (HyperText Markup Language), XML (Extensible Markup Language) ve CSV (Comma-Separated Values) raporları üretmek Domain controller Yönetici
7 Değişiklik takibi: güvenlik günlüğünde GPO değişikliklerini okumak Domain controller Yönetici
8 GPO düzenleme yetkilerini taramak Domain controller Yönetici
9 Kullanılmayan bir GPO’yu güvenli sırayla silmek Domain controller Yönetici
10 Laboratuvarı temizlemek Domain controller Yönetici
Not: Bu bölümün tamamı domain controller’da yönetici olarak açılmış PowerShell penceresinde yapılır. W11CLIENT‘a ihtiyacımız yok. Pencerenin başlığında Administrator yazdığını kontrol edin. Test GPO’larının adı Z - Test - ile başlar, böylece laboratuvar GPO’larınızdan kolayca ayrılırlar ve temizlik adımında tek filtreyle bulunurlar.

3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek

Adım 1: Bilerek kirli bir ortam hazırlamak

Önce dört sorunu üretiyoruz. GPMC (Group Policy Management Console) üzerinden yapmak isterseniz her biri için sol ağaçta Group Policy Objects düğümüne sağ tıklayıp New diyebilirsiniz. Ancak aynı işi PowerShell ile tek blokta yapmak daha hızlı ve tekrarlanabilirdir. Bu yüzden bu adımı doğrudan PowerShell ile yapıyoruz.

Run as administrator (Yönetici olarak çalıştır) açılmış PowerShell penceresinde şu bloğu çalıştırın:

Import-Module GroupPolicy
$kiosk = "OU=Kiosk,OU=Bilgisayarlar,OU=LAB,DC=bakicubuk,DC=tech"

# 1) Hicbir yere bagli olmayan, bos GPO
New-GPO -Name "Z - Test - Bagli Degil" -Comment "Hijyen testi: bos ve baglantisiz" | Out-Null

# 2) Bos ama Kiosk OU'suna bagli GPO
New-GPO -Name "Z - Test - Bos Bagli" -Comment "Hijyen testi: bos ama bagli" | Out-Null
New-GPLink -Name "Z - Test - Bos Bagli" -Target $kiosk -LinkEnabled Yes | Out-Null

# 3) Ayari olan ama hicbir yere bagli olmayan GPO
New-GPO -Name "Z - Test - Ayarli Bagsiz" -Comment "Hijyen testi: ayarli ama baglantisiz" | Out-Null
Set-GPRegistryValue -Name "Z - Test - Ayarli Bagsiz" -Key "HKLM\SOFTWARE\Policies\HijyenTest" -ValueName "Deneme" -Type DWord -Value 1 | Out-Null

# 4) Ayarlari devre disi birakilmis, ama bagli GPO
New-GPO -Name "Z - Test - Devre Disi" -Comment "Hijyen testi: ayarlar kapali" | Out-Null
Set-GPRegistryValue -Name "Z - Test - Devre Disi" -Key "HKLM\SOFTWARE\Policies\HijyenTest" -ValueName "Deneme" -Type DWord -Value 1 | Out-Null
(Get-GPO -Name "Z - Test - Devre Disi").GpoStatus = "AllSettingsDisabled"
New-GPLink -Name "Z - Test - Devre Disi" -Target $kiosk -LinkEnabled Yes | Out-Null

Get-GPO -All | Where-Object DisplayName -like "Z - Test -*" | Select-Object DisplayName, GpoStatus, Id | Format-Table -AutoSize -Wrap

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$kiosk Test GPO’larının (Group Policy Object) bağlanacağı OU’nun (Organizational Unit) DN’si (Distinguished Name) Laboratuvarınızda var olan, zarar vermeyecek bir OU’nun DN’si. Yoksa Get-ADOrganizationalUnit -Filter * komutunun çıktısındaki DistinguishedName değerlerine bakın
Z - Test - Test GPO’larını ayırt eden ad öneki Değiştirmeyin, temizlik adımı bu önekle çalışır
HKLM\SOFTWARE\Policies\HijyenTest GPO’ya yazılan zararsız, uydurma bir kayıt defteri anahtarı Değiştirmeyin. Gerçek bir ayarı etkilemez
-LinkEnabled Yes Link’in etkin olmasını sağlar Değiştirmeyin

Şimdi iki yetim durumunu üretiyoruz. Birincisi SYSVOL’de AD (Active Directory) karşılığı olmayan bir klasör, yani yetim GPT (Group Policy Template). İkincisi AD’de var olup SYSVOL klasörü silinmiş bir GPO, yani yetim GPC (Group Policy Container). Üçüncü olarak, bağlı bir GPO’yu link’ini kaldırmadan silerek kırık link üretiyoruz:

$etki = (Get-ADDomain).DNSRoot
$policies = "\\$etki\SYSVOL\$etki\Policies"
$kiosk = "OU=Kiosk,OU=Bilgisayarlar,OU=LAB,DC=bakicubuk,DC=tech"

# Yetim GPT: SYSVOL'de klasor var, AD'de karsiligi yok
$sahteId = "{" + [guid]::NewGuid().ToString().ToUpper() + "}"
New-Item -Path "$policies\$sahteId" -ItemType Directory | Out-Null
Write-Host "Yetim GPT klasoru: $sahteId"

# Yetim GPC: AD'de GPO var, SYSVOL klasoru silinmis
$yetim = New-GPO -Name "Z - Test - Yetim GPC" -Comment "Hijyen testi: SYSVOL klasoru silinecek"
Remove-Item -Path "$policies\{$($yetim.Id.ToString().ToUpper())}" -Recurse -Force
Write-Host "Yetim GPC: $($yetim.Id)"

# Kirik link: bagli GPO'yu link'ini kaldirmadan siliyoruz
New-GPO -Name "Z - Test - Silinecek Bagli" -Comment "Hijyen testi: silinince kirik link birakir" | Out-Null
New-GPLink -Name "Z - Test - Silinecek Bagli" -Target $kiosk -LinkEnabled Yes | Out-Null
Remove-GPO -Name "Z - Test - Silinecek Bagli"

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$etki Etki alanının DNS (Domain Name System) adı. Get-ADDomain kendisi bulur Değiştirmeyin
$policies SYSVOL (System Volume) içindeki GPO (Group Policy Object) klasörlerinin ana yolu UNC (Universal Naming Convention) yolu Değiştirmeyin
$kiosk Adım 1’in ilk bloğunda kullandığınız OU’nun (Organizational Unit) DN’si (Distinguished Name) Aynı değer
$sahteId Uydurma bir GPO kimliği. Her çalıştırmada yeni üretilir Değiştirmeyin. Ekrana yazılan değeri not edin
Uyarı: Bu blok yalnızca Z - Test - ile başlayan laboratuvar nesnelerine ve kendi ürettiği uydurma klasöre dokunur. Remove-Item satırındaki yol, az önce oluşturduğunuz test GPO’sunun kimliğinden üretilir. Yolu elle değiştirip gerçek bir GPO klasörüne yöneltmeyin.

GPMC’de de bakın. Group Policy Management konsolunu açın (Run (Çalıştır), gpmc.msc), LAB altında Kiosk OU’suna (Organizational Unit) tıklayın. Sağ bölmede Linked Group Policy Objects sekmesinde link’lere bakın. Yalnızca iki link görürsünüz: Z - Test - Bos Bagli ve Z - Test - Devre Disi. Silinen GPO’nun link’i bu listede görünmez, oysa OU’nun gPLink özniteliğinde hala durur. Ayrıca sol ağaçta Group Policy Objects altına bakın: SYSVOL klasörü silinmiş Z - Test - Yetim GPC de normal bir GPO gibi listelenir. Yani GPMC kırık link’i ve yetim GPC’yi göstermez, bunları Adım 4’te PowerShell ile bulacağız.

Adım 2: Tüm GPO’ların envanterini çıkarmak

Envanter, hijyenin ilk adımıdır: elinizde ne var? GPMC’de bu, sol ağaçta Group Policy Objects düğümüne tıklayınca sağ bölmenin Contents sekmesinde görünür. Her GPO’nun adı, durumu ve değişiklik zamanı için Details sekmesine, ayarları için Settings sekmesine bakılır. Yüzlerce GPO’da bunu tek tek yapmak mümkün değildir, bu yüzden PowerShell ile tek tabloya döküyoruz:

Get-GPO -All |
  Sort-Object DisplayName |
  Select-Object DisplayName, GpoStatus, CreationTime, ModificationTime, Id |
  Format-Table -AutoSize -Wrap

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Get-GPO -All Etki alanındaki tüm GPO’ları (Group Policy Object) getirir Değiştirmeyin
GpoStatus GPO’nun hangi tarafının (bilgisayar ya da kullanıcı) etkin olduğu Değiştirmeyin
CreationTime, ModificationTime Oluşturulma ve son değişiklik zamanı. Yıllardır değişmeyen GPO’lar şüpheli adaydır Değiştirmeyin

Adım 3: Bağlı olmayan, boş ve devre dışı GPO’ları bulmak

GPMC’de bir GPO’nun bağlı olup olmadığına, GPO’ya tıklayıp sağ bölmede Scope sekmesindeki Links kutusuna bakarak karar verilir. Ayar olup olmadığı Settings sekmesinde görünür: hiç ayar yoksa orada No settings defined yazar. Bu yöntem birkaç GPO için uygundur. Tümünü taramak için her GPO’nun XML (Extensible Markup Language) raporunu okuyan bir döngü kullanıyoruz:

$envanter = Get-GPO -All | ForEach-Object {
    $r = [xml](Get-GPOReport -Guid $_.Id -ReportType Xml)
    [pscustomobject]@{
        Ad              = $_.DisplayName
        Durum           = $_.GpoStatus
        BagSayisi       = ($r.GPO.LinksTo | Measure-Object).Count
        BilgisayarAyari = (($r.GPO.Computer.ExtensionData | Measure-Object).Count -gt 0)
        KullaniciAyari  = (($r.GPO.User.ExtensionData | Measure-Object).Count -gt 0)
        Degisti         = $_.ModificationTime
    }
}
$envanter | Sort-Object Ad | Format-Table -AutoSize -Wrap

"--- Hicbir yere bagli olmayanlar ---"
$envanter | Where-Object BagSayisi -eq 0 | Select-Object Ad, Durum, Degisti | Format-Table -AutoSize
"--- Hicbir ayari olmayanlar ---"
$envanter | Where-Object { -not $_.BilgisayarAyari -and -not $_.KullaniciAyari } | Select-Object Ad, BagSayisi | Format-Table -AutoSize
"--- Ayarlari tamamen kapali olanlar ---"
$envanter | Where-Object Durum -eq "AllSettingsDisabled" | Select-Object Ad, BagSayisi | Format-Table -AutoSize

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Get-GPOReport -ReportType Xml Her GPO’nun (Group Policy Object) ayrıntılı raporunu XML (Extensible Markup Language) olarak üretir Değiştirmeyin
$r.GPO.LinksTo Rapordaki link listesi. Boşsa GPO hiçbir yere bağlı değildir Değiştirmeyin
$r.GPO.Computer.ExtensionData Bilgisayar tarafındaki ayar grupları. Yoksa bilgisayar tarafında ayar yoktur Değiştirmeyin
AllSettingsDisabled Hem bilgisayar hem kullanıcı ayarları kapalı demektir Yalnızca bir tarafı kapalı olanları görmek için UserSettingsDisabled ya da ComputerSettingsDisabled yazın
Not: Beklenen sonuç: Z - Test - Bagli Degil, Z - Test - Ayarli Bagsiz ve Z - Test - Yetim GPC bağlı olmayanlar listesinde görünür. Ayarsızlar listesinde Z - Test - Bagli Degil, Z - Test - Bos Bagli ve Z - Test - Yetim GPC çıkar. Kapalılar listesinde yalnızca Z - Test - Devre Disi bulunur. Devre Disi GPO’sunun bilgisayar ayarı vardır ama kapalıdır, bu yüzden ayarsızlar listesine girmez. İki noktaya dikkat edin: yetim GPC burada bağsız ve boş görünür, çünkü rapor AD’deki bilgiyi okur ve SYSVOL klasörünün silindiğini söylemez. Bu fark bir sonraki adımda ortaya çıkar. Ayrıca laboratuvarınızda başka GPO’lar bu listelerde çıkarsa bu bir hata değil, hijyen taramasının işe yaradığının kanıtıdır. Her birine tek tek bakıp gerekçesini belirleyin.

Adım 4: Yetim GPC, yetim GPT, kırık link ve sürüm uyuşmazlığını bulmak

Bu sorunlar GPMC’de kolayca görünmez, çünkü GPMC AD’deki GPO listesini esas alır. Önce AD tarafını (GPC) ve SYSVOL tarafını (GPT) karşılaştırıyoruz:

$ad    = (Get-ADDomain).DistinguishedName
$etki  = (Get-ADDomain).DNSRoot
$gpc = Get-ADObject -SearchBase "CN=Policies,CN=System,$ad" -SearchScope OneLevel -Filter 'objectClass -eq "groupPolicyContainer"' | ForEach-Object { $_.Name.ToUpper() }
$gpt = Get-ChildItem "\\$etki\SYSVOL\$etki\Policies" -Directory | Where-Object Name -like "{*}" | ForEach-Object { $_.Name.ToUpper() }

"--- Yetim GPC (AD'de var, SYSVOL'de yok) ---"
$gpc | Where-Object { $_ -notin $gpt }
"--- Yetim GPT (SYSVOL'de var, AD'de yok) ---"
$gpt | Where-Object { $_ -notin $gpc }

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
CN=Policies,CN=System,$ad GPC (Group Policy Container) nesnelerinin AD (Active Directory) içindeki kapsayıcısı Değiştirmeyin
groupPolicyContainer GPO’nun (Group Policy Object) AD nesne sınıfı Değiştirmeyin
\\$etki\SYSVOL\$etki\Policies GPT (Group Policy Template) klasörlerinin yolu Değiştirmeyin
{*} Yalnızca {GUID} biçimindeki klasörleri alır. PolicyDefinitions gibi klasörleri eler Değiştirmeyin

Şimdi kırık link’leri arıyoruz. Her OU’nun ve etki alanı kökünün gPLink özniteliği, bağlı GPO’ların GUID (Globally Unique Identifier) listesini tutar. Bu GUID’lerden GPO listesinde bulunmayanlar kırık linktir:

$ad = (Get-ADDomain).DistinguishedName
$mevcut = (Get-GPO -All).Id | ForEach-Object { $_.Guid.ToUpper() }
Get-ADObject -SearchBase $ad -Filter 'objectClass -eq "organizationalUnit" -or objectClass -eq "domainDNS"' -Properties gPLink |
  Where-Object { $_.gPLink } |
  ForEach-Object {
      $hedef = $_.DistinguishedName
      [regex]::Matches($_.gPLink, '\{([0-9A-Fa-f\-]{36})\}') | ForEach-Object {
          $id = $_.Groups[1].Value.ToUpper()
          [pscustomobject]@{ Hedef = $hedef; GpoId = $id; Durum = $(if ($id -in $mevcut) { "Var" } else { "KIRIK" }) }
      }
  } | Sort-Object Durum, Hedef | Format-Table -AutoSize -Wrap

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
gPLink OU (Organizational Unit) ya da etki alanı köküne bağlı GPO’ları (Group Policy Object) tutan AD (Active Directory) özniteliği Değiştirmeyin
$mevcut Etki alanında gerçekten var olan GPO kimlikleri Değiştirmeyin
\{([0-9A-Fa-f\-]{36})\} gPLink içinden GUID’leri (Globally Unique Identifier) ayıklayan düzenli ifade Değiştirmeyin
KIRIK Karşılığı olmayan link Değiştirmeyin
Not: Bu tarama OU’ları ve etki alanı kökünü kapsar. Site (Active Directory Sites) düzeyindeki link’ler farklı bir kapsayıcıda tutulur ve bu örnekte taranmaz. Siteye GPO bağlıyorsanız taramayı oraya da genişletin.

Son olarak AD ve SYSVOL sürüm numaralarını karşılaştırıyoruz. Her GPO’nun bilgisayar ve kullanıcı tarafı için iki sürüm tutulur: biri AD’de, biri SYSVOL’de. Normalde ikisi eşittir. Farklıysa replikasyon sorunu ya da yarım kalmış bir yazma işlemi vardır:

Get-GPO -All | ForEach-Object {
    [pscustomobject]@{
        Ad            = $_.DisplayName
        BilgAD        = $_.Computer.DSVersion
        BilgSysvol    = $_.Computer.SysvolVersion
        KullAD        = $_.User.DSVersion
        KullSysvol    = $_.User.SysvolVersion
    }
} | Where-Object { $_.BilgAD -ne $_.BilgSysvol -or $_.KullAD -ne $_.KullSysvol } | Format-Table -AutoSize

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
DSVersion GPO’nun (Group Policy Object) AD’deki (Active Directory) sürüm numarası Değiştirmeyin
SysvolVersion GPO’nun SYSVOL’deki (System Volume) sürüm numarası Değiştirmeyin
Where-Object koşulu Yalnızca uyuşmayanları listeler Değiştirmeyin

Tek domain controller’lı laboratuvarda çıktının büyük olasılıkla yalnızca Z - Test - Yetim GPC gibi SYSVOL’ü silinmiş GPO’lar için doldurulmasını bekleyin. Boş çıktı da uyuşmazlık yok demektir. Gerçek ortamda çok domain controller’lı bir yapıda bu liste doluysa önce replikasyonu inceleyin (repadmin /replsummary), GPO’yu değil.

Adım 5: Tüm GPO’ları yedeklemek ve geri yüklemek

Temizliğe girişmeden önce yedek alırız. GPMC’de bunun yolu şudur: sol ağaçta Group Policy Objects düğümüne sağ tıklayın ve Back Up All… seçin.

Açılan Back Up Group Policy Object penceresinde Location kutusuna C:\GPOYedek\Hijyen yazın. Description kutusu isteğe bağlıdır, bir açıklama girmeniz iyi olur. Ardından Back Up düğmesine basın.

İşlem bitince Backup penceresi her GPO için sonucu listeler. Laboratuvarımızda burada bir hata görürsünüz: Z - Test - Yetim GPC için Failed, altında da The system cannot find the path specified mesajı. Pencerenin sonunda 7 GPOs were successfully backed up. 1 GPOs were not backed up. yazar. Hata, Adım 1’de SYSVOL klasörünü sildiğimiz GPO’dan gelir: GPMC bu GPO’nun ayar dosyalarını bulamadığı için yedekleyemez. Diğer yedi GPO yedeklenmiştir. OK ile pencereyi kapatın.

Aynı işi PowerShell ile yapmak, zamanlanmış görev olarak her gece çalıştırmayı mümkün kılar. Burada Backup-GPO -All yerine her GPO’yu ayrı ayrı yedekleyen bir döngü kullanıyoruz. Nedenini aşağıdaki kutuda anlatıyoruz:

$yedek = "C:\GPOYedek\Hijyen"
New-Item -Path $yedek -ItemType Directory -Force | Out-Null
$sonuc = foreach ($g in Get-GPO -All) {
    try {
        Backup-GPO -Guid $g.Id -Path $yedek -Comment "Hijyen oncesi tam yedek" -ErrorAction Stop |
          Select-Object DisplayName, GpoId, @{n='BackupId'; e={$_.Id}}, CreationTime
    }
    catch {
        Write-Warning "Yedeklenemedi: $($g.DisplayName)"
    }
}
$sonuc | Format-Table -AutoSize -Wrap
"Yedeklenen: " + ($sonuc | Measure-Object).Count + " / " + (Get-GPO -All | Measure-Object).Count

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$yedek Yedeklerin yazılacağı klasör Üretimde yetkisi kısıtlanmış, başka bir sunucudaki ya da çevrimdışı yedeklenen bir paylaşım. Bu klasör GPO (Group Policy Object) ayarlarının tamamını içerir, korunmalıdır
foreach ($g in Get-GPO -All) Tüm GPO’ları tek tek dolaşır Değiştirmeyin. Yalnızca belirli GPO’ları yedeklemek için Get-GPO -Name "GPO adi" yazın
Backup-GPO -Guid $g.Id O an dolaşılan GPO’yu kimliğiyle yedekler Değiştirmeyin
-ErrorAction Stop Hatayı catch bloğuna düşürür. Yazılmazsa hata yakalanmaz Değiştirmeyin
-Comment Yedeğe not düşer. Geri yüklerken hangi yedek olduğunu anlamanızı sağlar Tarih ve neden içeren bir açıklama
@{n='BackupId'; e={$_.Id}} Yedeğin kimliği. Backup-GPO çıktısında bu değer Id adıyla gelir, GPO’nun kendi kimliği ise GpoId adındadır Değiştirmeyin
Write-Warning Yedeklenemeyen GPO’nun adını ekrana yazar Zamanlanmış görevde bu satırı günlüğe yazan ya da e-posta gönderen bir komutla değiştirin
Uyarı: Laboratuvarda önce Backup-GPO -All komutunu denedik. Komut altı GPO’yu yedekledi, yetim GPC’ye gelince DirectoryNotFoundException hatası verdi ve durdu. Sıradaki GPO (Z - Test - Ayarli Bagsiz) yedeklenmedi. Yani tek bir yetim GPC, tüm yedeği sessizce eksik bırakabilir. Bu yüzden her GPO’yu ayrı ayrı yedekleyip hatalıları listeleyen döngüyü kullanıyoruz. Üretimde bu döngünün sonundaki Yedeklenemedi uyarısını ciddiye alın: bu uyarı, Adım 4’teki taramanın bulduğu yetim GPC gibi bir sorunun işaretidir.
Not: Bölüm 7’deki baseline paketini bu klasöre koymayın. Yedek klasörü yalnızca Backup-GPO çıktılarını içersin. Aksi halde hangi yedeğin hangi amaçla alındığı karışır. GPMC ve PowerShell yedeklerini aynı klasöre art arda alırsanız her GPO için iki yedek oluşur. Karışmaması için bu bölümde yöntemlerden birini kullanın ya da arada klasörü temizleyin.

Yedeğin işe yaradığını görmek için bir geri yükleme testi yapıyoruz. Önce GPMC (Group Policy Management Console) yolunu adım adım izleyelim.

1. Manage Backups penceresini açın. Group Policy Objects düğümüne sağ tıklayın ve Manage Backups… seçin.

2. Yedeği seçin. Backup location kutusunda yedek klasörü (C:\GPOYedek\Hijyen) görünür. Listede yedeklenen yedi GPO yer alır, yetim GPC yoktur. Geri yüklemek istediğiniz yedeği (burada Z - Test - Ayarli Bagsiz) tıklayarak seçin, ardından Restore düğmesine basın. Aynı GPO’nun birden çok yedeği varsa Time Stamp sütunundan doğru olanı seçin. Show only the latest version of each GPO kutusunu işaretlerseniz yalnızca en yeni yedekler listelenir. Silinmiş bir GPO’yu da bu pencereden geri yükleyebilirsiniz..

3. Onaylayın. GPMC Do you want to restore the selected backup? (Seçili yedeği geri yüklemek istiyor musunuz?) diye sorar. Bu işlem GPO’nun mevcut ayarlarının üzerine yazar. OK düğmesine basın.

4. Sonucu kontrol edin. Restore penceresi işlemin ilerlemesini gösterir. Z - Test - Ayarli Bagsiz...Succeeded satırını görünce OK ile kapatın.

Aynı testi PowerShell ile de yapabiliriz, bu sefer sonucu da sayıyla görerek. Z - Test - Ayarli Bagsiz GPO’sundaki değeri bozuyor, yedekten geri getiriyoruz:

$yedek = "C:\GPOYedek\Hijyen"
$ad = "Z - Test - Ayarli Bagsiz"
$anahtar = "HKLM\SOFTWARE\Policies\HijyenTest"

"Once  : " + (Get-GPRegistryValue -Name $ad -Key $anahtar -ValueName "Deneme").Value
Set-GPRegistryValue -Name $ad -Key $anahtar -ValueName "Deneme" -Type DWord -Value 99 | Out-Null
"Bozuk : " + (Get-GPRegistryValue -Name $ad -Key $anahtar -ValueName "Deneme").Value

Restore-GPO -Name $ad -Path $yedek | Out-Null
"Sonra : " + (Get-GPRegistryValue -Name $ad -Key $anahtar -ValueName "Deneme").Value

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$ad Geri yüklenecek GPO’nun (Group Policy Object) adı Gerçek bir geri yüklemede ilgili GPO’nun adı
Restore-GPO -Path Yedek klasörü. Klasörde aynı GPO’nun birden çok yedeği varsa en yenisi seçilir Belirli bir yedek için -BackupId kullanın (Backup-GPO çıktısındaki BackupId)
99 Bozma testi için yazılan değer Değiştirmeyin

Beklenen çıktı: Once : 1, Bozuk : 99, Sonra : 1.

Önemli bir ayrıntı: Restore-GPO link’leri geri yüklemez. Yedek, GPO’nun ayarlarını ve ACL (Access Control List) güvenlik izinlerini içerir ama hangi OU’lara bağlı olduğunu içermez. Silinmiş bir GPO’yu geri yüklerseniz link’lerini elle yeniden kurmanız gerekir. Bu yüzden yedekle birlikte link envanterini de saklamak gerekir. Bunu Adım 6’da yapacağız.

Adım 6: Raporlar üretmek

GPMC’de tek bir GPO’nun raporu için GPO’ya sağ tıklayıp Save Report… seçilir, biçim olarak HTML (HyperText Markup Language) ya da XML seçilir ve dosya kaydedilir. Tüm GPO’lar için PowerShell kullanıyoruz:

$rapor = "C:\GPORapor"
New-Item -Path $rapor -ItemType Directory -Force | Out-Null

# 1) Tek dosyada tum GPO'larin HTML raporu
Get-GPOReport -All -ReportType Html -Path "$rapor\tum-gpo.html"

# 2) Her GPO icin ayri XML raporu (karsilastirma ve arsivleme icin)
Get-GPO -All | ForEach-Object {
    $dosya = ($_.DisplayName -replace '[\\/:*?"<>|]', '_')
    Get-GPOReport -Guid $_.Id -ReportType Xml -Path "$rapor\$dosya.xml"
}

# 3) Link envanteri (yedekten geri yuklenirse link'leri yeniden kurmak icin)
Get-GPO -All | ForEach-Object {
    $r = [xml](Get-GPOReport -Guid $_.Id -ReportType Xml)
    foreach ($l in $r.GPO.LinksTo) {
        [pscustomobject]@{ GPO = $_.DisplayName; Hedef = $l.SOMPath; Etkin = $l.Enabled; Zorunlu = $l.NoOverride }
    }
} | Export-Csv "$rapor\linkler.csv" -NoTypeInformation -Encoding UTF8

Get-ChildItem $rapor | Select-Object Name, Length | Format-Table -AutoSize

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$rapor Raporların yazılacağı klasör Düzenli çalışacaksa tarih içeren bir klasör adı (örneğin C:\GPORapor\2026-10)
-ReportType Html İnsanın okuyacağı rapor Makinenin işleyeceği çıktı için Xml
-replace ifadesi GPO (Group Policy Object) adındaki dosya adında geçersiz karakterleri _ yapar Değiştirmeyin
$l.SOMPath, $l.Enabled, $l.NoOverride Link’in bağlı olduğu yer, etkin olup olmadığı, zorunlu (Enforced) olup olmadığı Değiştirmeyin
Export-Csv ... -Encoding UTF8 Türkçe karakterleri bozmadan CSV (Comma-Separated Values) yazar Değiştirmeyin

HTML raporunu bir tarayıcıda açın. Her GPO için ayarlar, link’ler ve güvenlik izinleri tek sayfada görünür. XML raporlar zaman içinde alınıp birbiriyle karşılaştırılırsa (örneğin bir Git deposunda), bu GPO geçen ay nasıldı? sorusu cevaplanabilir.

Adım 7: Değişiklik takibi: kim, neyi, ne zaman değiştirdi?

GPO değişiklikleri AD nesnesi değişikliği olarak güvenlik günlüğüne düşer. Ancak bunun için domain controller’da Directory Service Changes denetiminin açık olması gerekir. Önce durumuna bakıyoruz:

auditpol /get /subcategory:"Directory Service Changes"

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Directory Service Changes AD (Active Directory) nesne değişikliklerini denetleyen alt kategori Değiştirmeyin. Windows Türkçe ise alt kategori adı farklı görünebilir, bu durumda auditpol /list /subcategory:* ile adını bulun

Çıktıda Success yazıyorsa denetim açıktır. Laboratuvarımızda ise No Auditing çıktı: denetim kapalıydı ve GPO değişiklikleri güvenlik günlüğüne hiç düşmüyordu. Çoğu ortamda bu ayar varsayılan olarak açık varsayılır, ama varsaymak yerine bakmak gerekir. Kapalıysa laboratuvarda şu komutla açın ve tekrar sorgulayın:

auditpol /set /subcategory:"Directory Service Changes" /success:enable
auditpol /get /subcategory:"Directory Service Changes"

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
/success:enable Başarılı AD (Active Directory) nesne değişikliklerini günlüğe yazar Değiştirmeyin. Başarısız denemeleri de istiyorsanız /failure:enable ekleyin

Bu komut yerel denetim ilkesini değiştirir ve laboratuvar için yeterlidir. Üretimde kalıcı olması için Default Domain Controllers Policy içinde Advanced Audit Policy Configuration, DS Access, Audit Directory Service Changes ayarını GPO (Group Policy Object) ile etkinleştirin. Aynı ayar bir GPO’dan geliyorsa onun değeri yerel ayarı ezer. Denetim yalnızca açıldığı andan sonraki değişiklikleri kaydeder, geçmişe dönük olay üretmez.

Şimdi bir değişiklik yapıp izini okuyoruz. Önce Z - Test - Ayarli Bagsiz GPO’sundaki değeri değiştirin, sonra son iki saatin GPO olaylarını listeleyin:

Set-GPRegistryValue -Name "Z - Test - Ayarli Bagsiz" -Key "HKLM\SOFTWARE\Policies\HijyenTest" -ValueName "Deneme" -Type DWord -Value 5 | Out-Null

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=5136,5137,5141; StartTime=(Get-Date).AddHours(-2)} -ErrorAction SilentlyContinue | ForEach-Object {
    $x = [xml]$_.ToXml()
    $d = @{}
    $x.Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
    if ($d.ObjectClass -eq 'groupPolicyContainer' -or $d.AttributeLDAPDisplayName -eq 'gPLink') {
        $guid = ($d.ObjectDN -split ',')[0] -replace '^CN=',''
        $ad = try { (Get-GPO -Guid $guid -ErrorAction Stop).DisplayName } catch { '(bulunamadi)' }
        [pscustomobject]@{
            Zaman     = $_.TimeCreated
            Olay      = $_.Id
            Kim       = $d.SubjectUserName
            GPO       = $ad
            Oznitelik = $d.AttributeLDAPDisplayName
            Deger     = $d.AttributeValue
        }
    }
} | Sort-Object Zaman | Format-Table -AutoSize -Wrap

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Id=5136,5137,5141 AD (Active Directory) nesnesinin değiştirilmesi (5136), oluşturulması (5137) ve silinmesi (5141) Değiştirmeyin
StartTime=(Get-Date).AddHours(-2) Bakılacak zaman aralığı Daha geniş bir aralık için AddDays(-7) gibi bir değer
groupPolicyContainer GPO (Group Policy Object) nesnelerini süzer Değiştirmeyin
gPLink OU’ya (Organizational Unit) bağlı GPO listesi değişikliklerini de yakalar Değiştirmeyin
$d.SubjectUserName Değişikliği yapan hesap Değiştirmeyin
$guid, $ad Olaydaki nesne yolundan GPO’nun kimliği (GUID (Globally Unique Identifier)) çıkarılır ve görünen ada çevrilir. GPO silinmişse (bulunamadi) yazar Değiştirmeyin
-ErrorAction SilentlyContinue Aralıkta hiç olay yoksa hata yazmaz Değiştirmeyin

Çıktıda Z - Test - Ayarli Bagsiz için versionNumber özniteliğinde, Administrator hesabıyla iki adet 5136 olayı görünür (laboratuvarımızda 196614 ve 196615). İki olay olmasının nedeni, Set-GPRegistryValue komutunun tek çağrıda sürüm sayısını iki kez artırmasıdır. versionNumber iki sayının birleşimidir: üst 16 bit kullanıcı, alt 16 bit bilgisayar sürümüdür. 196615 değerinde bilgisayar sürümü 7’dir. Denetimi az önce açtığımız için Adım 1’deki GPO oluşturma ve link işlemleri (5137, gPLink) listede yoktur. Denetim açıkken yapılan oluşturma, silme ve link değişiklikleri de bu listeye düşer.

Not: Bu olaylar hangi GPO’nun, kim tarafından, ne zaman değiştiğini söyler. Ama ayarın içeriğinin ne olduğunu söylemez. Çünkü ayar dosyaları SYSVOL’dedir ve dosya içeriği AD olaylarına girmez. İçerik karşılaştırması için Adım 6’daki XML raporları dönemsel olarak alıp birbiriyle karşılaştırmak gerekir. SYSVOL’de dosya düzeyinde izleme istiyorsanız ayrıca dosya sistemi denetimi (olay 4663) açmanız gerekir.

Adım 8: GPO düzenleme yetkilerini taramak

Bir GPO’yu düzenleyebilen herkes, o GPO’nun bağlı olduğu tüm bilgisayarlarda kod çalıştırabilir (Bölüm 6’da bunu saldırgan gözüyle görmüştük). Bu yüzden hijyen taramasının bir parçası da “kim düzenleyebiliyor?” sorusudur. GPMC’de bunun karşılığı, GPO’ya tıklayıp Delegation sekmesine bakmaktır. Tüm GPO’lar için PowerShell:

Get-GPO -All | ForEach-Object {
    $gpo = $_
    Get-GPPermission -Guid $gpo.Id -All |
      Where-Object { $_.Permission -notin 'GpoRead','GpoApply' } |
      ForEach-Object {
          [pscustomobject]@{ GPO = $gpo.DisplayName; Kim = $_.Trustee.Name; Tur = $_.Trustee.SidType; Yetki = $_.Permission }
      }
} | Sort-Object GPO, Kim | Format-Table -AutoSize -Wrap

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
-notin 'GpoRead','GpoApply' Yalnızca okuma ve uygulama dışındaki her izni listeler. Böylece GpoEdit, GpoEditDeleteModifySecurity ve GpoCustom hepsi yakalanır Değiştirmeyin. Yalnızca -in 'GpoEdit','GpoEditDeleteModifySecurity' gibi dar bir filtre yazmayın, özel izinleri kaçırır
$_.Trustee.SidType Yetkinin verildiği kimliğin türü (kullanıcı, grup, yerleşik hesap) Değiştirmeyin

Laboratuvarımızda Z - Test GPO’larında Domain Admins, Enterprise Admins ve SYSTEM tam kontrol (GpoEditDeleteModifySecurity) görünür. İki varsayılan GPO’da (Default Domain Policy, Default Domain Controllers Policy) Domain Admins ve Enterprise Admins ise GpoCustom olarak listelenir. Bu, standart bir izin seviyesine uymayan özel bir ACE (Access Control Entry) bileşimi demektir. Varsayılan GPO’larda bu normaldir. Filtreyi yalnızca GpoEdit ve GpoEditDeleteModifySecurity ile sınırlarsanız bu satırları ve başka yerlerdeki özel izinleri göremezsiniz.

Listede yalnızca beklediğiniz yönetici grupları (örneğin Domain Admins, Enterprise Admins, SYSTEM) olmalıdır. Tek tek kullanıcı adları ya da Authenticated Users gibi geniş gruplar görüyorsanız bu bir bulgudur.

Adım 9: Güvenli silme sırası

Kullanılmayan bir GPO’yu silmek, sil düğmesine basmak değildir. Silme geri alınamaz, ve silinen GPO bir yerde sessizce bir işi yapıyor olabilir.

Production (Üretim) ortamında şu sırayı izleyin:

  1. Yedek alın. Backup-GPO ile GPO’nun yedeğini ve link envanterini saklayın.
  2. Ayarları devre dışı bırakın. GPO’ya tıklayıp Details sekmesinde GPO Status değerini All settings disabled yapın. GPO artık hiçbir şey uygulamaz ama durur.
  3. Karantina adı verin. GPO’yu ZZ - SILINECEK - 2026-10 - Eski Ad gibi, tarihli bir adla yeniden adlandırın. İşi bozulan biri hemen hangi GPO diye sorar, siz de adından geri alırsınız.
  4. Bekleyin. En az bir tam iş döngüsü (genellikle bir ay, ay sonu işlemlerini kapsayacak şekilde) bekleyin.
  5. Link’i kaldırın. Sorun çıkmadıysa önce link’i silin.
  6. GPO’yu silin. Yedeği saklı olduğu için gerekirse geri yüklenebilir.

Laboratuvarda Z - Test - Devre Disi GPO’sunu bu sırayla siliyoruz (bekleme süresini atlıyoruz):

$ad = "Z - Test - Devre Disi"
$kiosk = "OU=Kiosk,OU=Bilgisayarlar,OU=LAB,DC=bakicubuk,DC=tech"

# 1) Yedek
Backup-GPO -Name $ad -Path "C:\GPOYedek\Hijyen" -Comment "Silme oncesi yedek" | Select-Object DisplayName, BackupId | Format-List

# 2) Ayarlari kapat (bu GPO zaten kapali, gercek hayatta burada kapatilir)
(Get-GPO -Name $ad).GpoStatus = "AllSettingsDisabled"

# 3) Karantina adi
$karantina = "ZZ - SILINECEK - 2026-10 - $ad"
Rename-GPO -Name $ad -TargetName $karantina | Out-Null

# 4) Gercek hayatta burada bir ay beklenir

# 5) Link'i kaldir
Remove-GPLink -Name $karantina -Target $kiosk | Out-Null

# 6) Once deneme, sonra gercek silme
Remove-GPO -Name $karantina -WhatIf
Remove-GPO -Name $karantina

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$ad Silinecek GPO’nun (Group Policy Object) adı Gerçek silmede ilgili GPO’nun adı
$kiosk GPO’nun bağlı olduğu OU’nun (Organizational Unit) DN’si (Distinguished Name). Birden çok yere bağlıysa her biri için Remove-GPLink çalıştırın Gerçek bağlantı yeri. Rapordaki linkler.csv dosyasından bakabilirsiniz
$karantina Tarih ve “silinecek” ibaresi içeren yeni ad Silme tarihinizi yazın
-WhatIf Komutu çalıştırmadan, ne yapacağını gösterir Gerçek silmeden önce her zaman bir kez çalıştırın

Silmenin geri alınabildiğini görmek için GPO’yu yedekten geri getirelim. Burada dikkat edilmesi gereken bir ayrıntı var: Restore-GPO -Name yalnızca var olan bir GPO’nun üzerine yükleme yapar. GPO silinmişse -Name ile denerseniz The GPO was not found hatası alırsınız:

Restore-GPO -Name "Z - Test - Devre Disi" -Path "C:\GPOYedek\Hijyen"

Silinmiş bir GPO’yu geri getirmek için yedeğin kimliğini (BackupId) kullanırız. Yedek klasöründeki her alt klasör bir yedektir ve adı BackupId değeridir. Hangi klasörün hangi GPO’ya ait olduğunu bkupInfo.xml dosyası söyler:

$yedek = "C:\GPOYedek\Hijyen"
$bul = Get-ChildItem $yedek -Directory | ForEach-Object {
    $xml = [xml](Get-Content (Join-Path $_.FullName "bkupInfo.xml"))
    [pscustomobject]@{ BackupId = $_.Name; GPO = $xml.BackupInst.GPODisplayName.InnerText; Zaman = $xml.BackupInst.BackupTime.InnerText }
} | Where-Object GPO -eq "Z - Test - Devre Disi" | Sort-Object Zaman
$bul | Format-Table -AutoSize

$id = ($bul | Select-Object -Last 1).BackupId
Restore-GPO -BackupId $id -Path $yedek | Select-Object DisplayName, Id | Format-List
Get-GPO -Name "Z - Test - Devre Disi" | Select-Object DisplayName, Id, CreationTime, GpoStatus | Format-List

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$yedek Yedek klasörü Yedeklerinizin bulunduğu klasör
bkupInfo.xml Her yedek klasöründe bulunan, yedeğin hangi GPO’ya (Group Policy Object) ait olduğunu ve ne zaman alındığını tutan XML (Extensible Markup Language) dosyası Değiştirmeyin
"Z - Test - Devre Disi" Yedeği aranan GPO’nun adı Geri yüklenecek GPO’nun yedekteki adı
Select-Object -Last 1 Zamana göre sıralı listeden en yeni yedeği seçer Belirli bir yedek için $id değerine o yedeğin BackupId değerini yazın
Restore-GPO -BackupId GPO silinmiş olsa bile yedekten yeniden oluşturur Değiştirmeyin

Laboratuvarımızda listede iki yedek göründü (Adım 5’te ve Adım 9’da alınanlar). Komut en yenisini geri yükledi, GPO aynı adla yeniden oluştu (CreationTime geri yükleme anıydı) ve GpoStatus AllSettingsDisabled olarak geldi. Yedekte olmayan şey link’tir: GPO geri gelir ama hiçbir OU’ya bağlı değildir, link’i elle yeniden kurmak gerekir (New-GPLink). linkler.csv dosyası bu yüzden saklanmalıdır. Yeniden oluşan GPO’nun kimliğinin eskisiyle aynı olduğunu varsaymayın. Link’leri ve izinleri geri kurarken ad yerine güncel kimliği kullanın.

Not: -WhatIf yalnızca bu komutu çalıştırsaydım şunu yapardım der, hedefin gerçekten var olup olmadığını denetlemez. Laboratuvarda GPO’yu sildikten sonra Remove-GPO -WhatIf yine de “What if: Remove the … GPO” yanıtı verdi. Bu yüzden -WhatIf çıktısını GPO’nun var olduğunun kanıtı sayma, önce Get-GPO ile bakın.

Adım 10: Laboratuvarı temizlemek

Önce hala var olan Z - Test - GPO’larını ve link’lerini kaldırıyoruz. Ardından yetim GPC, yetim GPT ve kırık link’i temizliyoruz. Bunu üç parçada yapıyoruz. Aynı PowerShell penceresini kullanın, çünkü değişkenler pencereye özeldir. Yeni bir pencerede çalıştırırsanız $kiosk ve $etki boş gelir.

Parça 1: Test GPO’larını ve yetim GPC’yi silmek

$kiosk = "OU=Kiosk,OU=Bilgisayarlar,OU=LAB,DC=bakicubuk,DC=tech"
$ad    = (Get-ADDomain).DistinguishedName
$etki  = (Get-ADDomain).DNSRoot

# Test GPO'larinin link'lerini kaldir, sonra GPO'lari sil
Get-GPO -All | Where-Object DisplayName -like "Z - Test -*" | ForEach-Object {
    Remove-GPLink -Name $_.DisplayName -Target $kiosk -ErrorAction SilentlyContinue | Out-Null
    Remove-GPO -Name $_.DisplayName -ErrorAction SilentlyContinue
}

# Silinememis kalan yetim GPC varsa AD tarafindan sil
Get-ADObject -SearchBase "CN=Policies,CN=System,$ad" -SearchScope OneLevel -Filter 'objectClass -eq "groupPolicyContainer" -and displayName -like "Z - Test -*"' |
  Remove-ADObject -Recursive -Confirm:$false

Get-GPO -All | Select-Object DisplayName

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$kiosk Test GPO’larının (Group Policy Object) bağlandığı OU (Organizational Unit) Adım 1’de kullandığınız OU
$ad, $etki Etki alanının DN’si (Distinguished Name) ve DNS (Domain Name System) adı Değiştirmeyin, etki alanından okunur
displayName -like "Z - Test -*" Silinecek GPO’ları ve yetim GPC’yi (Group Policy Container) yalnızca test önekiyle bulur Değiştirmeyin. Üretimde böyle bir toplu silme yazmayın

Son komut yalnızca Default Domain Policy, Default Domain Controllers Policy ve Seamless SSO Settings GPO’larını listelemelidir. Yetim GPC’li GPO çoğu zaman Remove-GPO ile silinemez, ikinci komut onu AD tarafından siler.

Parça 2: Yetim GPT klasörünü ve kırık link’i temizlemek

$sahteId = "{CED8D2B5-B398-4ABF-9C51-D06F9E6996B2}"
Remove-Item -Path "\\$etki\SYSVOL\$etki\Policies\$sahteId" -Recurse -Force

$gp = (Get-ADObject -Identity $kiosk -Properties gPLink).gPLink
$gp   # eski degeri bir yere kaydedin
$mevcut = (Get-GPO -All).Id | ForEach-Object { $_.Guid.ToUpper() }
$temiz = ([regex]::Matches($gp, '\[[^\]]+\]') | Where-Object {
    $_.Value -match '\{([0-9A-Fa-f\-]{36})\}' -and $matches[1].ToUpper() -in $mevcut
}).Value -join ''
if ($temiz) {
    Set-ADObject -Identity $kiosk -Replace @{ gPLink = $temiz }
} else {
    Set-ADObject -Identity $kiosk -Clear gPLink
}
(Get-ADObject -Identity $kiosk -Properties gPLink).gPLink

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$sahteId Adım 1’de oluşturduğumuz uydurma yetim GPT (Group Policy Template) klasörünün adı Kendi laboratuvarınızda Adım 1’de ekrana yazılan değeri süslü parantezlerle birlikte yazın
-Replace @{ gPLink = $temiz } OU’nun (Organizational Unit) link listesini yalnızca var olan GPO’larla (Group Policy Object) yeniden yazar. Hiç geçerli link kalmadıysa -Clear gPLink özniteliği boşaltır Değiştirmeyin. Başka bir OU’ya uygulamadan önce gPLink değerini kaydedin

Laboratuvarımızda $gp satırında GPO’su olmayan tek bir link göründü ([LDAP://cn={790D7BE1-...},cn=policies,cn=system,DC=bakicubuk,DC=tech;0]). Kırık link buydu. Komutlar sonunda gPLink boş döndü, yani OU’da geçerli link kalmadı.

Uyarı: İkinci parça OU’nun gPLink özniteliğini doğrudan yeniden yazar. Yalnızca laboratuvardaki Kiosk OU’sunda çalıştırın ve önce $gp değerini bir yere kaydedin. Kırık link’i temizlemenin daha güvenli yolu GPMC’dir: OU’ya tıklayın, bulunamayan satıra sağ tıklayıp Delete Link deyin.

Parça 3: Son kontrol

Get-GPO -All | Where-Object DisplayName -like "*Test*" | Select-Object DisplayName
Test-Path "\\$etki\SYSVOL\$etki\Policies\$sahteId"
(Get-ADObject -Identity $kiosk -Properties gPLink).gPLink

Kendi ortamınıza uyarlarken:

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Test-Path Sahte yetim GPT (Group Policy Template) klasörünün gerçekten silindiğini doğrular Değiştirmeyin. Sonuç False olmalıdır

Beklenen sonuç: ilk komut hiçbir şey yazmaz, Test-Path False döner, son komut boş bırakır.

İsterseniz laboratuvarın yedek ve rapor klasörlerini de siliniz. Üretimde bu klasörleri silmeyin:

Remove-Item "C:\GPOYedek\Hijyen","C:\GPORapor" -Recurse -Force -ErrorAction SilentlyContinue

4. Tespit ve Savunma: Neyi İzlemeli, Neyi Düzenli Yapmalı?

Hijyen bir kerelik temizlik değil, takvime bağlı bir iştir. Aşağıdaki olaylar GPO ortamındaki değişikliği görmenizi sağlar:

Olay Kimliği Günlük Ne Anlama Gelir Neden Önemli
5137 Security (domain controller) AD (Active Directory) nesnesi oluşturuldu Yeni bir GPO’nun (Group Policy Object) oluşturulduğunu gösterir. Kim oluşturdu, ne zaman?
5136 Security (domain controller) AD nesnesi değiştirildi GPO sürüm değişikliğini ve OU’daki (Organizational Unit) gPLink değişikliğini gösterir. Yeni bir link, bir GPO’nun beklenmedik bir yere bağlandığı anlamına gelebilir
5141 Security (domain controller) AD nesnesi silindi Bir GPO’nun silindiğini gösterir
4739 Security (domain controller) Etki alanı ilkesi değişti Parola ve kilitleme ilkesi değişikliklerini gösterir
4663 Security (domain controller) Bir nesneye erişildi (dosya sistemi denetimi açıksa) SYSVOL’deki (System Volume) GPO dosyalarının içeriğine erişimi ve yazmayı gösterir. Ayrıca açılması gerekir

Önlemleri öncelik sırasıyla şöyle sıralayabiliriz:

  1. Her GPO’nun bir sahibi ve bir gerekçesi olsun. GPO’nun Comment alanına neden var olduğunu, kimin istediğini ve tarihini yazın. Sahibi bilinmeyen GPO silinmeye adaydır.
  2. Adlandırma standardı kullanın. Bu seride U - Satis - Duvar Kagidi gibi kapsam, hedef ve amaç içeren adlar kullandık. Standart ad, taramaları kolaylaştırır.
  3. Çeyrekte bir hijyen taraması yapın. Adım 3, 4 ve 8’deki taramaları bir betiğe koyup üç ayda bir çalıştırın. Çıktıyı arşivleyin.
  4. Yedeği otomatikleştirin. GPO’ları tek tek yedekleyen döngüyü zamanlanmış görevle gece çalıştırın ve Yedeklenemedi uyarılarını günlüğe ya da e-postaya bağlayın. Yedekleri domain controller’ın kendisinde değil, ayrı bir yerde, kısıtlı yetkiyle saklayın. Yedek klasörü tüm ayarlarınızın kopyasıdır.
  5. Yedeği geri yükleyerek sınayın. Hiç sınanmamış yedek, yedek değildir. Yılda en az bir kez bir test GPO’sunu geri yükleyin.
  6. XML raporları arşivleyin. Dönemsel XML raporlar bir Git deposunda tutulursa iki tarih arasındaki fark komutla görülür. SYSVOL içeriği değişikliklerini yakalamanın en kolay yoludur.
  7. GPO olaylarını SIEM’e (Security Information and Event Management) alın. 5136, 5137 ve 5141 olaylarını ilgili nesne sınıfıyla süzün. Mesai dışında yapılan GPO değişikliklerini ve yeni link’leri uyarıya bağlayın.
  8. Düzenleme yetkisini düzenli gözden geçirin. Adım 8’deki taramayı her çeyrekte yapın. Geniş gruplara düzenleme yetkisi verilmişse kaldırın.
  9. Silmeyi sırayla yapın. Yedek, devre dışı, karantina adı, bekleme, link’in kaldırılması, silme. Doğrudan silmeyin.

5. Güvenlik Açısından Bu Bölümün Dersleri

  • Hijyen bir güvenlik konusudur. Unutulmuş, sahibi belirsiz bir GPO hem karışıklık hem saldırı yüzeyidir. Düzenleme yetkisi geniş bir GPO, unutulmuş olsa da bağlandığı her bilgisayara komut çalıştırabilir.
  • GPMC her şeyi göstermez. Yetim GPC, yetim GPT ve kırık link konsolda görünmeyebilir. Bunlar için AD ve SYSVOL’ü doğrudan karşılaştırmak gerekir.
  • Remove-GPO her link’i temizlemez. Laboratuvarda aynı domain’de bağlı bir GPO’yu sildiğimizde link de kalktı. Ama başka domain’de ya da site üzerinde duran link’ler ve elle bozulan gPLink kayıtları kırık kalabilir. Silmeden önce link’leri kendiniz kaldırın ve silmeden sonra taramayı çalıştırın.
  • Restore-GPO link’leri geri getirmez. Yedek ayarları ve izinleri saklar, bağlantı yerini saklamaz. Link envanterini ayrıca tutun.
  • Olay günlüğü “ne” değil “kim ve ne zaman” der. 5136 olayı GPO’nun değiştiğini ve değiştireni gösterir, ayar içeriğini göstermez. İçerik için dönemsel XML raporları karşılaştırın.
  • Tek bir yetim GPC tam yedeği bozabilir. Laboratuvarda Backup-GPO -All yetim GPC’ye gelince hata verip durdu ve ardındaki GPO yedeklenmedi. GPMC’nin Back Up All… işlemi ise hatalı GPO’yu atlayıp diğerlerini yedekledi ve sonunda kaç GPO’nun yedeklenemediğini yazdı. Yedeği her zaman sonuç sayısıyla doğrulayın.
  • Sınanmamış yedek yoktur. Geri yükleme provası yapmadan yedeğe güvenmeyin.
  • Silmeden önce kapatın. Bir GPO’nun gerçekten kullanılmadığını anlamanın en güvenli yolu, onu devre dışı bırakıp beklemektir.

6. Özet ve Seri Kapanışı

  1. GPO hijyeni; bağlı olmayan, boş ve devre dışı GPO’ların, yetim GPC ve GPT’lerin, kırık link’lerin ve sürüm uyuşmazlıklarının düzenli olarak bulunup temizlenmesidir.
  2. Get-GPOReport -ReportType Xml çıktısı; link sayısını ve ayar durumunu tüm GPO’lar için tek döngüde okumanın en pratik yoludur.
  3. Yetim GPC ve GPT, AD’deki CN=Policies,CN=System kapsayıcısı ile SYSVOL’deki Policies klasörünün karşılaştırılmasıyla bulunur. Kırık link’ler gPLink özniteliğinden bulunur.
  4. GPO’ları tek tek Backup-GPO ile yedekleyin ve hatalıları listeleyin, Restore-GPO ile geri yükleyin. Backup-GPO -All yetim bir GPC’de durabilir. Yedek link’leri içermez, link envanterini ayrıca saklayın.
  5. HTML, XML ve CSV (Comma-Separated Values) raporlar hem insan okumasını hem de dönemsel karşılaştırmayı sağlar.
  6. GPO değişikliklerinin izi 5136, 5137 ve 5141 olaylarında bulunur. Bunun için Directory Service Changes denetimi açık olmalıdır.
  7. GPO düzenleme yetkisi Get-GPPermission ile düzenli taranmalıdır.
  8. Silme sırası: yedek, devre dışı bırak, karantina adı, bekle, link’i kaldır, sil.

Serinin sekiz bölümünü tek tabloda toplayalım:

Bölüm Konu Akılda Kalacak Cümle
1 Temeller ve Mimari GPO (Group Policy Object) iki parçadır: AD’de (Active Directory) kapsayıcı, SYSVOL’de (System Volume) şablon
2 Policy ve Preferences Policy zorlar ve geri alır, Preferences ayarlar ve bırakır
3 İşlenme Sırası Son yazan kazanır: yerel, site, domain, OU (Organizational Unit)
4 Filtreleme ve Loopback Kapsam link ile, hedef güvenlik ve WMI (Windows Management Instrumentation) filtresiyle daraltılır
5 Yenileme ve Sorun Giderme Sorunu önce gpresult ve olay günlüğünde arayın
6 Saldırgan Gözünden Group Policy Yazma yetkisi olan GPO, tüm bilgisayarlarda kod çalıştırma yetkisidir
7 Security Baseline ile GPO Sıkılaştırma Baseline başlangıçtır. Önce test OU’su, istisna ayrı GPO
8 GPO Hijyeni ve Raporlama Her GPO’nun sahibi, gerekçesi, yedeği ve izi olmalı

Seriyi toparlayan tek bir fikir var: Group Policy güçlüdür, çünkü tek bir değişiklik binlerce bilgisayara ulaşır. Aynı nedenle onu yazmak kadar, korumak, izlemek ve temiz tutmak da yöneticinin işidir. Laboratuvarda yaptığımız her şeyi, kendi ortamınızda önce küçük bir test grubunda deneyin, yedeğini alın ve değişikliğin izini bırakın.

Seriyi buraya kadar takip ettiğiniz için teşekkürler.

Kısaltmalar

Yazıda geçen kısaltmaların açılımlarını ve kısa açıklamalarını aşağıdaki tabloda bir arada bulabilirsiniz.

Kısaltma Açılımı Açıklama
ACL Access Control List Bir nesne üzerinde kimin hangi izne sahip olduğunu tanımlayan erişim listesi
AD Active Directory Microsoft’un kullanıcı, bilgisayar ve grup gibi nesneleri merkezi olarak yöneten dizin hizmeti
CSV Comma-Separated Values Tabloyu virgül ya da noktalı virgülle ayrılmış düz metin olarak tutan dosya biçimi
DN Distinguished Name Bir nesnenin AD içindeki tam yolunu gösteren benzersiz ad
DNS Domain Name System Adları IP adreslerine çeviren ve domain controller bulmayı sağlayan hizmet
GPC Group Policy Container GPO’nun AD içinde tutulan parçası (sürüm, durum, CSE listesi)
GPMC Group Policy Management Console GPO oluşturma, link etme, raporlama ve yönetim konsolu
GPO Group Policy Object Ayarları içeren ve site, domain ya da OU’ya link edilen Group Policy nesnesi
GPT Group Policy Template GPO’nun SYSVOL içinde tutulan parçası (ayar dosyaları, script’ler)
GUID Globally Unique Identifier Nesneleri benzersiz şekilde tanımlayan 128 bitlik kimlik değeri
HTML HyperText Markup Language Web sayfası ve rapor biçimlendirme dili
OU Organizational Unit AD içinde nesneleri gruplamak ve GPO link etmek için kullanılan konteyner
SIEM Security Information and Event Management Günlükleri toplayıp ilişkilendiren ve uyarı üreten güvenlik izleme platformu
SYSVOL System Volume GPO dosyalarını ve logon script’lerini tutan, domain controller’lar arasında replike edilen paylaşım
UNC Universal Naming Convention Ağ kaynaklarını \\sunucu\paylaşım biçiminde gösteren yol yazımı
WMI Windows Management Instrumentation Windows sistem bilgilerini sorgulamak ve yönetmek için kullanılan altyapı
XML Extensible Markup Language Yapılandırılmış veri tutmak için kullanılan işaretleme dili

asw

===== Tablo 1: Sorun / Nasıl Oluşur / Neden Risklidir / Nasıl Bulunur | Bölüm: 1. GPO Hijyeni Nedir, Hangi Sorunlar Birikir? =====

Sorun Nasıl Oluşur Neden Risklidir Nasıl Bulunur
Bağlı olmayan GPO (Group Policy Object) GPO oluşturulur, hiçbir yere link edilmez ya da link sonradan kaldırılır Karışıklık yaratır. Biri yanlışlıkla bağlarsa beklenmedik ayarlar uygulanır Get-GPOReport çıktısında link sayısı 0
Boş GPO İçinde hiç ayar yoktur İşlenme süresini boşuna uzatır, ne işe yaradığı anlaşılmaz Rapordaki Computer ve User bölümleri boş
Ayarları devre dışı GPO Bilgisayar ve kullanıcı ayarları kapatılmıştır Bağlı görünür ama işlevsizdir. Bir gün yanlışlıkla açılabilir GpoStatus değeri AllSettingsDisabled
Yetim GPC (Group Policy Container) GPO’nun AD (Active Directory) parçası vardır, SYSVOL (System Volume) klasörü yoktur Ayarlar istemciye ulaşmaz, hata günlüklerinde “dosya bulunamadı” görülür AD ve SYSVOL listelerinin karşılaştırılması
Yetim GPT (Group Policy Template) SYSVOL klasörü vardır, AD nesnesi yoktur Eski ayarlar ve script’ler SYSVOL’de gereksiz yer kaplar ve bilgi sızdırabilir AD ve SYSVOL listelerinin karşılaştırılması
Kırık link Bağlı olduğu GPO silinmiş ama OU’daki (Organizational Unit) kayıt kalmıştır. Örneğin link başka bir domain’de ya da site üzerindeydi, ya da gPLink elle bozuldu GPMC’de (Group Policy Management Console) çoğu zaman görünmez. İstemciler her işlemede boşuna arar OU’ların gPLink özniteliğindeki GUID’lerin (Globally Unique Identifier) GPO listesiyle karşılaştırılması
Sürüm uyuşmazlığı AD ve SYSVOL’deki sürüm numaraları farklıdır (replikasyon sorunu) İstemciler eski ya da yarım ayar alır Get-GPO çıktısında DSVersion ve SysvolVersion farkı
Aşırı yetki Gereğinden fazla kişi GPO’yu düzenleyebilir Saldırgan bu GPO üzerinden tüm bilgisayarlara kod çalıştırabilir (Bölüm 6) Get-GPPermission taraması

===== Tablo 2: Adım / Ne Yapıyoruz / Nerede / Hangi Hesap | Bölüm: 2. Laboratuvar Planı =====

Adım Ne Yapıyoruz Nerede Hangi Hesap
1 Bilerek kirli bir ortam hazırlamak: test GPO’ları (Group Policy Object), yetim klasör, kırık link Domain controller (W25DC) Yönetici
2 Tüm GPO’ların envanterini çıkarmak Domain controller Yönetici
3 Bağlı olmayan, boş ve devre dışı GPO’ları bulmak Domain controller Yönetici
4 Yetim GPC (Group Policy Container), yetim GPT (Group Policy Template), kırık link ve sürüm uyuşmazlığını bulmak Domain controller Yönetici
5 Tüm GPO’ları yedeklemek, bir ayarı bozup geri yüklemek Domain controller Yönetici
6 HTML (HyperText Markup Language), XML (Extensible Markup Language) ve CSV (Comma-Separated Values) raporları üretmek Domain controller Yönetici
7 Değişiklik takibi: güvenlik günlüğünde GPO değişikliklerini okumak Domain controller Yönetici
8 GPO düzenleme yetkilerini taramak Domain controller Yönetici
9 Kullanılmayan bir GPO’yu güvenli sırayla silmek Domain controller Yönetici
10 Laboratuvarı temizlemek Domain controller Yönetici

===== Tablo 3: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$kiosk Test GPO’larının (Group Policy Object) bağlanacağı OU’nun (Organizational Unit) DN’si (Distinguished Name) Laboratuvarınızda var olan, zarar vermeyecek bir OU’nun DN’si. Yoksa Get-ADOrganizationalUnit -Filter * komutunun çıktısındaki DistinguishedName değerlerine bakın
Z - Test - Test GPO’larını ayırt eden ad öneki Değiştirmeyin, temizlik adımı bu önekle çalışır
HKLM\SOFTWARE\Policies\HijyenTest GPO’ya yazılan zararsız, uydurma bir kayıt defteri anahtarı Değiştirmeyin. Gerçek bir ayarı etkilemez
-LinkEnabled Yes Link’in etkin olmasını sağlar Değiştirmeyin

===== Tablo 4: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$etki Etki alanının DNS (Domain Name System) adı. Get-ADDomain kendisi bulur Değiştirmeyin
$policies SYSVOL (System Volume) içindeki GPO (Group Policy Object) klasörlerinin ana yolu UNC (Universal Naming Convention) yolu Değiştirmeyin
$kiosk Adım 1’in ilk bloğunda kullandığınız OU’nun (Organizational Unit) DN’si (Distinguished Name) Aynı değer
$sahteId Uydurma bir GPO kimliği. Her çalıştırmada yeni üretilir Değiştirmeyin. Ekrana yazılan değeri not edin
$eski Kiosk OU’sunun değiştirmeden önceki gPLink değeri. Geri dönmek için saklanır Değiştirmeyin. Ekrana yazılan değeri bir yere kaydedin
$sahte Kiosk‘a eklenen, karşılığında GPO bulunmayan uydurma kimlik Değiştirmeyin. Ekrana yazılan değeri not edin
cn=policies,cn=system,$ad GPO kimliklerinin AD’deki (Active Directory) kapsayıcı yolu. gPLink kayıtları bu biçimdedir Değiştirmeyin

===== Tablo 5: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Get-GPO -All Etki alanındaki tüm GPO’ları (Group Policy Object) getirir Değiştirmeyin
GpoStatus GPO’nun hangi tarafının (bilgisayar ya da kullanıcı) etkin olduğu Değiştirmeyin
CreationTime, ModificationTime Oluşturulma ve son değişiklik zamanı. Yıllardır değişmeyen GPO’lar şüpheli adaydır Değiştirmeyin

===== Tablo 6: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Get-GPOReport -ReportType Xml Her GPO’nun (Group Policy Object) ayrıntılı raporunu XML (Extensible Markup Language) olarak üretir Değiştirmeyin
$r.GPO.LinksTo Rapordaki link listesi. Boşsa GPO hiçbir yere bağlı değildir Değiştirmeyin
$r.GPO.Computer.ExtensionData Bilgisayar tarafındaki ayar grupları. Yoksa bilgisayar tarafında ayar yoktur Değiştirmeyin
AllSettingsDisabled Hem bilgisayar hem kullanıcı ayarları kapalı demektir Yalnızca bir tarafı kapalı olanları görmek için UserSettingsDisabled ya da ComputerSettingsDisabled yazın

===== Tablo 7: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
CN=Policies,CN=System,$ad GPC (Group Policy Container) nesnelerinin AD (Active Directory) içindeki kapsayıcısı Değiştirmeyin
groupPolicyContainer GPO’nun (Group Policy Object) AD nesne sınıfı Değiştirmeyin
\\$etki\SYSVOL\$etki\Policies GPT (Group Policy Template) klasörlerinin yolu Değiştirmeyin
{*} Yalnızca {GUID} biçimindeki klasörleri alır. PolicyDefinitions gibi klasörleri eler Değiştirmeyin

===== Tablo 8: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
gPLink OU (Organizational Unit) ya da etki alanı köküne bağlı GPO’ları (Group Policy Object) tutan AD (Active Directory) özniteliği Değiştirmeyin
$mevcut Etki alanında gerçekten var olan GPO kimlikleri Değiştirmeyin
\{([0-9A-Fa-f\-]{36})\} gPLink içinden GUID’leri (Globally Unique Identifier) ayıklayan düzenli ifade Değiştirmeyin
KIRIK Karşılığı olmayan link Değiştirmeyin

===== Tablo 9: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
DSVersion GPO’nun (Group Policy Object) AD’deki (Active Directory) sürüm numarası Değiştirmeyin
SysvolVersion GPO’nun SYSVOL’deki (System Volume) sürüm numarası Değiştirmeyin
Where-Object koşulu Yalnızca uyuşmayanları listeler Değiştirmeyin

===== Tablo 10: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$yedek Yedeklerin yazılacağı klasör Üretimde yetkisi kısıtlanmış, başka bir sunucudaki ya da çevrimdışı yedeklenen bir paylaşım. Bu klasör GPO (Group Policy Object) ayarlarının tamamını içerir, korunmalıdır
foreach ($g in Get-GPO -All) Tüm GPO’ları tek tek dolaşır Değiştirmeyin. Yalnızca belirli GPO’ları yedeklemek için Get-GPO -Name "GPO adi" yazın
Backup-GPO -Guid $g.Id O an dolaşılan GPO’yu kimliğiyle yedekler Değiştirmeyin
-ErrorAction Stop Hatayı catch bloğuna düşürür. Yazılmazsa hata yakalanmaz Değiştirmeyin
-Comment Yedeğe not düşer. Geri yüklerken hangi yedek olduğunu anlamanızı sağlar Tarih ve neden içeren bir açıklama
@{n='BackupId'; e={$_.Id}} Yedeğin kimliği. Backup-GPO çıktısında bu değer Id adıyla gelir, GPO’nun kendi kimliği ise GpoId adındadır Değiştirmeyin
Write-Warning Yedeklenemeyen GPO’nun adını ekrana yazar Zamanlanmış görevde bu satırı günlüğe yazan ya da e-posta gönderen bir komutla değiştirin

===== Tablo 11: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$ad Geri yüklenecek GPO’nun (Group Policy Object) adı Gerçek bir geri yüklemede ilgili GPO’nun adı
Restore-GPO -Path Yedek klasörü. Klasörde aynı GPO’nun birden çok yedeği varsa en yenisi seçilir Belirli bir yedek için -BackupId kullanın (Backup-GPO çıktısındaki BackupId)
99 Bozma testi için yazılan değer Değiştirmeyin

===== Tablo 12: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$rapor Raporların yazılacağı klasör Düzenli çalışacaksa tarih içeren bir klasör adı (örneğin C:\GPORapor\2026-10)
-ReportType Html İnsanın okuyacağı rapor Makinenin işleyeceği çıktı için Xml
-replace ifadesi GPO (Group Policy Object) adındaki dosya adında geçersiz karakterleri _ yapar Değiştirmeyin
$l.SOMPath, $l.Enabled, $l.NoOverride Link’in bağlı olduğu yer, etkin olup olmadığı, zorunlu (Enforced) olup olmadığı Değiştirmeyin
Export-Csv ... -Encoding UTF8 Türkçe karakterleri bozmadan CSV (Comma-Separated Values) yazar Değiştirmeyin

===== Tablo 13: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Directory Service Changes AD (Active Directory) nesne değişikliklerini denetleyen alt kategori Değiştirmeyin. Windows Türkçe ise alt kategori adı farklı görünebilir, bu durumda auditpol /list /subcategory:* ile adını bulun

===== Tablo 14: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
/success:enable Başarılı AD (Active Directory) nesne değişikliklerini günlüğe yazar Değiştirmeyin. Başarısız denemeleri de istiyorsanız /failure:enable ekleyin

===== Tablo 15: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

===== Tablo 16: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
-notin 'GpoRead','GpoApply' Yalnızca okuma ve uygulama dışındaki her izni listeler. Böylece GpoEdit, GpoEditDeleteModifySecurity ve GpoCustom hepsi yakalanır Değiştirmeyin. Yalnızca -in 'GpoEdit','GpoEditDeleteModifySecurity' gibi dar bir filtre yazmayın, özel izinleri kaçırır
$_.Trustee.SidType Yetkinin verildiği kimliğin türü (kullanıcı, grup, yerleşik hesap) Değiştirmeyin

===== Tablo 17: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$ad Silinecek GPO’nun (Group Policy Object) adı Gerçek silmede ilgili GPO’nun adı
$kiosk GPO’nun bağlı olduğu OU’nun (Organizational Unit) DN’si (Distinguished Name). Birden çok yere bağlıysa her biri için Remove-GPLink çalıştırın Gerçek bağlantı yeri. Rapordaki linkler.csv dosyasından bakabilirsiniz
$karantina Tarih ve “silinecek” ibaresi içeren yeni ad Silme tarihinizi yazın
-WhatIf Komutu çalıştırmadan, ne yapacağını gösterir Gerçek silmeden önce her zaman bir kez çalıştırın

===== Tablo 18: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

===== Tablo 19: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$kiosk Test GPO’larının (Group Policy Object) bağlandığı OU (Organizational Unit) Adım 1’de kullandığınız OU
$ad, $etki Etki alanının DN’si (Distinguished Name) ve DNS (Domain Name System) adı Değiştirmeyin, etki alanından okunur
displayName -like "Z - Test -*" Silinecek GPO’ları ve yetim GPC’yi (Group Policy Container) yalnızca test önekiyle bulur Değiştirmeyin. Üretimde böyle bir toplu silme yazmayın

===== Tablo 20: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
$sahteId Adım 1’de oluşturduğumuz uydurma yetim GPT (Group Policy Template) klasörünün adı Kendi laboratuvarınızda Adım 1’de ekrana yazılan değeri süslü parantezlerle birlikte yazın
-Replace @{ gPLink = $temiz } OU’nun (Organizational Unit) link listesini yalnızca var olan GPO’larla (Group Policy Object) yeniden yazar. Hiç geçerli link kalmadıysa -Clear gPLink özniteliği boşaltır Değiştirmeyin. Başka bir OU’ya uygulamadan önce gPLink değerini kaydedin

===== Tablo 21: Değer / Ne Anlama Gelir / Neyle Değiştirilmeli | Bölüm: 3. Uygulama: Kirli Ortamı Hazırlamak ve Temizlemek =====

Değer Ne Anlama Gelir Neyle Değiştirilmeli
Test-Path Sahte yetim GPT (Group Policy Template) klasörünün gerçekten silindiğini doğrular Değiştirmeyin. Sonuç False olmalıdır

===== Tablo 22: Olay Kimliği / Günlük / Ne Anlama Gelir / Neden Önemli | Bölüm: 4. Tespit ve Savunma: Neyi İzlemeli, Neyi Düzenli Yapmalı? =====

Olay Kimliği Günlük Ne Anlama Gelir Neden Önemli
5137 Security (domain controller) AD (Active Directory) nesnesi oluşturuldu Yeni bir GPO’nun (Group Policy Object) oluşturulduğunu gösterir. Kim oluşturdu, ne zaman?
5136 Security (domain controller) AD nesnesi değiştirildi GPO sürüm değişikliğini ve OU’daki (Organizational Unit) gPLink değişikliğini gösterir. Yeni bir link, bir GPO’nun beklenmedik bir yere bağlandığı anlamına gelebilir
5141 Security (domain controller) AD nesnesi silindi Bir GPO’nun silindiğini gösterir
4739 Security (domain controller) Etki alanı ilkesi değişti Parola ve kilitleme ilkesi değişikliklerini gösterir
4663 Security (domain controller) Bir nesneye erişildi (dosya sistemi denetimi açıksa) SYSVOL’deki (System Volume) GPO dosyalarının içeriğine erişimi ve yazmayı gösterir. Ayrıca açılması gerekir

===== Tablo 23: Bölüm / Konu / Akılda Kalacak Cümle | Bölüm: 6. Özet ve Seri Kapanışı =====

Bölüm Konu Akılda Kalacak Cümle
1 Temeller ve Mimari GPO (Group Policy Object) iki parçadır: AD’de (Active Directory) kapsayıcı, SYSVOL’de (System Volume) şablon
2 Policy ve Preferences Policy zorlar ve geri alır, Preferences ayarlar ve bırakır
3 İşlenme Sırası Son yazan kazanır: yerel, site, domain, OU (Organizational Unit)
4 Filtreleme ve Loopback Kapsam link ile, hedef güvenlik ve WMI (Windows Management Instrumentation) filtresiyle daraltılır
5 Yenileme ve Sorun Giderme Sorunu önce gpresult ve olay günlüğünde arayın
6 Saldırgan Gözünden Group Policy Yazma yetkisi olan GPO, tüm bilgisayarlarda kod çalıştırma yetkisidir
7 Security Baseline ile GPO Sıkılaştırma Baseline başlangıçtır. Önce test OU’su, istisna ayrı GPO
8 GPO Hijyeni ve Raporlama Her GPO’nun sahibi, gerekçesi, yedeği ve izi olmalı

===== Tablo 24: Kısaltma / Açılımı / Açıklama | Bölüm: Kısaltmalar =====

Kısaltma Açılımı Açıklama
ACL Access Control List Bir nesne üzerinde kimin hangi izne sahip olduğunu tanımlayan erişim listesi
AD Active Directory Microsoft’un kullanıcı, bilgisayar ve grup gibi nesneleri merkezi olarak yöneten dizin hizmeti
CSV Comma-Separated Values Tabloyu virgül ya da noktalı virgülle ayrılmış düz metin olarak tutan dosya biçimi
DN Distinguished Name Bir nesnenin AD içindeki tam yolunu gösteren benzersiz ad
DNS Domain Name System Adları IP adreslerine çeviren ve domain controller bulmayı sağlayan hizmet
GPC Group Policy Container GPO’nun AD içinde tutulan parçası (sürüm, durum, CSE listesi)
GPMC Group Policy Management Console GPO oluşturma, link etme, raporlama ve yönetim konsolu
GPO Group Policy Object Ayarları içeren ve site, domain ya da OU’ya link edilen Group Policy nesnesi
GPT Group Policy Template GPO’nun SYSVOL içinde tutulan parçası (ayar dosyaları, script’ler)
GUID Globally Unique Identifier Nesneleri benzersiz şekilde tanımlayan 128 bitlik kimlik değeri
HTML HyperText Markup Language Web sayfası ve rapor biçimlendirme dili
OU Organizational Unit AD içinde nesneleri gruplamak ve GPO link etmek için kullanılan konteyner
SIEM Security Information and Event Management Günlükleri toplayıp ilişkilendiren ve uyarı üreten güvenlik izleme platformu
SYSVOL System Volume GPO dosyalarını ve logon script’lerini tutan, domain controller’lar arasında replike edilen paylaşım
UNC Universal Naming Convention Ağ kaynaklarını \\sunucu\paylaşım biçiminde gösteren yol yazımı
WMI Windows Management Instrumentation Windows sistem bilgilerini sorgulamak ve yönetmek için kullanılan altyapı
XML Extensible Markup Language Yapılandırılmış veri tutmak için kullanılan işaretleme dili

asw

Bir yanıt yazın

Başa Dön