Registry düzenlemesi denince çoğu sysadmin’in aklına hemen regedit.exe gelir. Ama production ortamında yüzlerce makineye aynı registry değişikliğini uygulamanız gerektiğinde, fareyle tıklaya tıklaya saçlarınızın döküleceğini çok geçmeden fark edersiniz. PowerShell, registry yönetimini hem hızlı hem de tekrarlanabilir hale getiren araçlarla dolu. Bu yazıda registry’nin PowerShell ile nasıl yönetileceğini, gerçek dünya senaryolarıyla birlikte ele alacağız.
Registry’yi PowerShell Gözüyle Anlamak
PowerShell, registry’ye dosya sistemi gibi davranır. Bu yaklaşım son derece zekice tasarlanmış çünkü cmdlet’leri zaten biliyorsunuz: Get-Item, Set-Item, New-Item, Remove-Item. Registry sürücüleri (PSDrive) sayesinde HKLM ve HKCU gibi hive’lara doğrudan erişebilirsiniz.
PowerShell’in varsayılan olarak tanımladığı registry sürücülerini görmek için:
Get-PSDrive -PSProvider Registry
Bu komut size HKLM (HKEY_LOCAL_MACHINE) ve HKCU (HKEY_CURRENT_USER) sürücülerini gösterir. Fakat dikkat, HKEY_CLASSES_ROOT, HKEY_USERS ve HKEY_CURRENT_CONFIG gibi hive’lara erişmek için bunları önce mount etmeniz gerekir:
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS
Bu sürücüler PowerShell oturumu kapandığında kaybolur. Kalıcı olmasını istiyorsanız -Persist parametresini ekleyin.
Temel Registry Okuma İşlemleri
Key ve Value Okumak
Bir registry key’ini listelemek için Get-Item kullanırsınız. Ama dikkat, Get-Item key’i döndürür, içindeki value’ları değil. Value’ları okumak için ya Get-ItemProperty ya da Get-ItemPropertyValue tercih edilir.
# Bir key'in tüm property'lerini oku
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion"
# Sadece belirli bir value'yu oku
Get-ItemPropertyValue -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion" -Name "ProductName"
# Bir key altındaki tüm subkey'leri listele
Get-ChildItem -Path "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionRun"
Gerçek dünyada sıkça kullanılan bir senaryo: Domain’deki tüm makinelerde hangi uygulamaların “Run” key’ine eklendiğini kontrol etmek. Birisi izinsiz bir şey eklemiş mi? Hemen anlarsınız.
Registry Value Tiplerini Anlamak
Registry’de farklı veri tipleri var ve PowerShell bu tipleri doğru şekilde yönetmenizi bekliyor:
- String (REG_SZ): Normal metin değerleri
- ExpandString (REG_EXPAND_SZ): %SystemRoot% gibi ortam değişkeni içeren değerler
- Binary (REG_BINARY): Ham binary veri
- DWord (REG_DWORD): 32-bit integer
- QWord (REG_QWORD): 64-bit integer
- MultiString (REG_MULTI_SZ): Çok satırlı string dizisi
Değer Yazma ve Güncelleme
Yeni Değer Oluşturmak
New-ItemProperty cmdlet’i yeni bir registry value oluşturur. Tip belirtmezseniz PowerShell bunu String olarak oluşturur, bu yüzden her zaman -PropertyType parametresini kullanın:
# Basit string değer ekle
New-ItemProperty -Path "HKLM:SOFTWAREMyApp" `
-Name "InstallPath" `
-Value "C:Program FilesMyApp" `
-PropertyType String `
-Force
# DWORD değer ekle (örneğin bir feature flag)
New-ItemProperty -Path "HKLM:SOFTWAREMyApp" `
-Name "EnableFeatureX" `
-Value 1 `
-PropertyType DWord `
-Force
-Force parametresi çok önemli: Key yoksa oluşturur, value zaten varsa üzerine yazar. Bunu kullanmazsanız var olan değerde hata alırsınız.
Mevcut Değeri Güncellemek
# Var olan değeri güncelle
Set-ItemProperty -Path "HKLM:SOFTWAREMyApp" `
-Name "Version" `
-Value "2.1.0"
# Çoklu değerleri tek seferde güncelle
$settings = @{
"EnableLogging" = 1
"LogLevel" = "Verbose"
"MaxRetry" = 3
}
foreach ($key in $settings.Keys) {
Set-ItemProperty -Path "HKLM:SOFTWAREMyAppSettings" `
-Name $key `
-Value $settings[$key]
}
Key Oluşturma ve Silme
Yeni Key Oluşturmak
New-Item cmdlet’i registry key oluşturur. İç içe geçmiş key’leri oluştururken dikkatli olun; üst key yoksa hata alırsınız:
# Tek key oluştur
New-Item -Path "HKLM:SOFTWAREMyCompany" -Force
# İç içe key'leri tek seferde oluştur
New-Item -Path "HKLM:SOFTWAREMyCompanyMyAppSettings" -Force
# Key oluştur ve hemen value ekle
New-Item -Path "HKLM:SOFTWAREMyCompanyMyApp" -Force |
New-ItemProperty -Name "Version" -Value "1.0" -PropertyType String
Key ve Value Silmek
# Bir value'yu sil
Remove-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name "OldSetting"
# Bir key'i ve içindeki her şeyi sil
Remove-Item -Path "HKLM:SOFTWAREMyAppOldFeature" -Recurse -Force
# Birden fazla value'yu sil
"Setting1", "Setting2", "Setting3" | ForEach-Object {
Remove-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name $_ -ErrorAction SilentlyContinue
}
Gerçek Dünya Senaryosu 1: Toplu Makine Konfigürasyonu
Diyelim ki 50 Windows Server’da IE Enhanced Security Configuration’ı devre dışı bırakmanız gerekiyor. Bu klasik bir senaryo ve elle yapmak saatler alır.
$servers = Get-Content "C:servers.txt"
$adminIESCPath = "HKLM:SOFTWAREMicrosoftActive SetupInstalled Components{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
$userIESCPath = "HKLM:SOFTWAREMicrosoftActive SetupInstalled Components{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
foreach ($server in $servers) {
try {
Invoke-Command -ComputerName $server -ScriptBlock {
param($adminPath, $userPath)
# Admin için IESC kapat
Set-ItemProperty -Path $adminPath -Name "IsInstalled" -Value 0 -Type DWord
# User için IESC kapat
Set-ItemProperty -Path $userPath -Name "IsInstalled" -Value 0 -Type DWord
Write-Host "[$env:COMPUTERNAME] IESC devre disi birakildi" -ForegroundColor Green
} -ArgumentList $adminIESCPath, $userIESCPath -ErrorAction Stop
}
catch {
Write-Warning "[$server] Hata: $($_.Exception.Message)"
}
}
Bu script, Invoke-Command ile remote makinelerde registry değişikliği yapıyor. WinRM’in aktif olduğundan emin olun tabii.
Gerçek Dünya Senaryosu 2: Registry Backup ve Restore
Production’da değişiklik yapmadan önce her zaman backup alın. PowerShell ile registry export/import işlemi:
function Backup-RegistryKey {
param(
[string]$KeyPath,
[string]$BackupFolder = "C:RegBackups"
)
# Backup klasörü yoksa oluştur
if (-not (Test-Path $BackupFolder)) {
New-Item -ItemType Directory -Path $BackupFolder | Out-Null
}
# Tarihli backup dosyası oluştur
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$keyName = ($KeyPath -split "\")[-1]
$backupFile = Join-Path $BackupFolder "$keyName`_$timestamp.reg"
# reg.exe ile export al (PowerShell'in native export'undan daha güvenilir)
$regPath = $KeyPath -replace "HKLM:\", "HKEY_LOCAL_MACHINE" `
-replace "HKCU:\", "HKEY_CURRENT_USER"
reg export $regPath $backupFile /y 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "Backup alindi: $backupFile" -ForegroundColor Green
return $backupFile
} else {
Write-Error "Backup alinamadi!"
return $null
}
}
# Kullanim
$backupFile = Backup-RegistryKey -KeyPath "HKLM:SOFTWAREMyApp"
# Restore etmek icin
# reg import $backupFile
Registry’de Arama Yapmak
Registry içinde belirli bir değer veya key aramak için Get-ChildItem ile recursive gezinme kullanılır. Ama dikkat, bu işlem çok yavaş olabilir, özellikle HKLM’nin tamamında arama yapıyorsanız:
function Search-Registry {
param(
[string]$StartPath,
[string]$SearchValue,
[switch]$SearchInNames,
[switch]$SearchInValues
)
Get-ChildItem -Path $StartPath -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
$key = $_
try {
$properties = Get-ItemProperty -Path $key.PSPath -ErrorAction SilentlyContinue
if ($properties) {
$properties.PSObject.Properties | Where-Object {
$_.Name -notmatch "^PS" # Built-in PS property'leri atla
} | ForEach-Object {
$match = $false
if ($SearchInNames -and $_.Name -like "*$SearchValue*") {
$match = $true
}
if ($SearchInValues -and $_.Value -like "*$SearchValue*") {
$match = $true
}
if ($match) {
[PSCustomObject]@{
KeyPath = $key.PSPath
Name = $_.Name
Value = $_.Value
}
}
}
}
}
catch { }
}
}
# Belirli bir uygulamanin kurulum yolunu ara
Search-Registry -StartPath "HKLM:SOFTWARE" `
-SearchValue "MyApp" `
-SearchInNames `
-SearchInValues
Registry ACL Yönetimi
Registry key’lerinde yetki yönetimi de bazen gerekli olur. Özellikle uygulamaların registry’ye yazabilmesi için gereken izinleri PowerShell ile ayarlayabilirsiniz:
# Mevcut ACL'yi gör
$acl = Get-Acl -Path "HKLM:SOFTWAREMyApp"
$acl.Access | Select-Object IdentityReference, RegistryRights, AccessControlType
# Yeni izin ekle (örneğin "DOMAINAppServiceAccount" hesabına okuma/yazma)
$acl = Get-Acl -Path "HKLM:SOFTWAREMyApp"
$identity = "DOMAINAppServiceAccount"
$rights = [System.Security.AccessControl.RegistryRights]::ReadKey -bor `
[System.Security.AccessControl.RegistryRights]::WriteKey
$inheritanceFlags = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit
$propagationFlags = [System.Security.AccessControl.PropagationFlags]::None
$type = [System.Security.AccessControl.AccessControlType]::Allow
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
$identity, $rights, $inheritanceFlags, $propagationFlags, $type
)
$acl.SetAccessRule($rule)
Set-Acl -Path "HKLM:SOFTWAREMyApp" -AclObject $acl
Write-Host "Registry izni basariyla ayarlandi." -ForegroundColor Green
Gerçek Dünya Senaryosu 3: Registry ile Uygulama Envanteri
Kurulu uygulamaların listesini çıkarmak, özellikle lisanslama ve güvenlik audit’leri için kritik. Windows, kurulu uygulamaları birkaç farklı registry path’inde tutar:
function Get-InstalledSoftware {
param(
[string[]]$ComputerName = $env:COMPUTERNAME
)
$uninstallPaths = @(
"HKLM:SOFTWAREMicrosoftWindowsCurrentVersionUninstall*",
"HKLM:SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall*"
)
foreach ($computer in $ComputerName) {
if ($computer -eq $env:COMPUTERNAME) {
foreach ($path in $uninstallPaths) {
Get-ItemProperty -Path $path -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName } |
Select-Object @{N="Computer";E={$computer}},
DisplayName,
DisplayVersion,
Publisher,
InstallDate
}
} else {
Invoke-Command -ComputerName $computer -ScriptBlock {
param($paths)
foreach ($path in $paths) {
Get-ItemProperty -Path $path -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName } |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
}
} -ArgumentList (, $uninstallPaths) |
Select-Object @{N="Computer";E={$computer}},
DisplayName, DisplayVersion, Publisher, InstallDate
}
}
}
# Tum sunucularda kurulu yazilim envanteri al
$servers = "Server01", "Server02", "Server03"
$software = Get-InstalledSoftware -ComputerName $servers
$software | Export-Csv -Path "C:ReportsSoftwareInventory.csv" -NoTypeInformation -Encoding UTF8
Write-Host "Toplam $($software.Count) uygulama kaydi bulundu." -ForegroundColor Cyan
Registry ile Windows Ayarlarını Otomatize Etmek
Sık yapılan Windows güvenlik ayarlarını registry üzerinden otomatize eden bir script:
function Set-WindowsHardening {
param(
[switch]$WhatIf
)
$settings = @(
# SMBv1'i devre disi birak
@{
Path = "HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters"
Name = "SMB1"
Value = 0
Type = "DWord"
Desc = "SMBv1 devre disi"
},
# RDP Network Level Authentication
@{
Path = "HKLM:SYSTEMCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp"
Name = "UserAuthentication"
Value = 1
Type = "DWord"
Desc = "NLA zorunlu kilindi"
},
# Autorun devre disi
@{
Path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesExplorer"
Name = "NoDriveTypeAutoRun"
Value = 255
Type = "DWord"
Desc = "Autorun devre disi"
}
)
foreach ($setting in $settings) {
if ($WhatIf) {
Write-Host "[WhatIf] $($setting.Desc) uygulanacak: $($setting.Path)" -ForegroundColor Yellow
continue
}
try {
# Key yoksa olustur
if (-not (Test-Path $setting.Path)) {
New-Item -Path $setting.Path -Force | Out-Null
}
Set-ItemProperty -Path $setting.Path `
-Name $setting.Name `
-Value $setting.Value `
-Type $setting.Type `
-ErrorAction Stop
Write-Host "[OK] $($setting.Desc)" -ForegroundColor Green
}
catch {
Write-Warning "[HATA] $($setting.Desc): $($_.Exception.Message)"
}
}
}
# Once WhatIf ile test et
Set-WindowsHardening -WhatIf
# Sonra gercekten uygula
# Set-WindowsHardening
Registry Değişikliklerini İzlemek
Kritik registry key’lerinde yapılan değişiklikleri gerçek zamanlı izlemek için WMI veya FileSystemWatcher‘ın registry muadili olan RegistryKey.OpenSubKey ile monitoring yapabilirsiniz. Basit ama etkili bir yöntem şöyle:
function Watch-RegistryKey {
param(
[string]$KeyPath = "HKLM:SOFTWAREMyApp",
[int]$IntervalSeconds = 30,
[int]$Duration = 300
)
$snapshot = @{}
$endTime = (Get-Date).AddSeconds($Duration)
Write-Host "Registry izleme basliyor: $KeyPath" -ForegroundColor Cyan
Write-Host "Sure: $Duration saniye, Kontrol araligi: $IntervalSeconds saniye`n"
while ((Get-Date) -lt $endTime) {
$current = Get-ItemProperty -Path $KeyPath -ErrorAction SilentlyContinue
if ($current) {
$current.PSObject.Properties | Where-Object { $_.Name -notmatch "^PS" } | ForEach-Object {
$name = $_.Name
$value = $_.Value
if ($snapshot.ContainsKey($name)) {
if ($snapshot[$name] -ne $value) {
$changeTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Warning "[$changeTime] DEGISIKLIK TESPIT EDILDI!"
Write-Host " Key : $KeyPath" -ForegroundColor Red
Write-Host " Name : $name" -ForegroundColor Red
Write-Host " Eski : $($snapshot[$name])" -ForegroundColor Yellow
Write-Host " Yeni : $value" -ForegroundColor Green
}
}
$snapshot[$name] = $value
}
}
Start-Sleep -Seconds $IntervalSeconds
}
Write-Host "`nIzleme tamamlandi." -ForegroundColor Cyan
}
Watch-RegistryKey -KeyPath "HKLM:SOFTWAREMyApp" -IntervalSeconds 10 -Duration 600
Dikkat Edilmesi Gereken Noktalar
Registry ile çalışırken bazı tuzaklardan kaçınmak gerekir:
- 64-bit vs 32-bit: 64-bit Windows’ta 32-bit uygulamalar
HKLM:SOFTWAREWOW6432Nodealtına yazılır. Hangi uygulamaya hitap ettiğinizi bilin. - Yetki sorunları: HKLM altındaki bazı key’ler için Administrator yetkisi gerekir. Script’lerinizi “Run as Administrator” ile çalıştırın.
- Remote Registry servisi: Uzak makinelerde
Invoke-Commandyerine doğrudan HKLM path’i kullanıyorsanız Remote Registry servisinin çalışıyor olması lazım. - Test Et, Sonra Uygula:
-WhatIfve-Confirmparametrelerini kullanın. Production’da deneme yanılma yapamazsınız. - Backup: Her değişiklikten önce backup alın. Yukarıdaki
Backup-RegistryKeyfonksiyonunu kullanma alışkanlığı edinin. - ErrorAction: Registry’de olmayan bir path okumaya çalışmak hata fırlatır.
ErrorAction SilentlyContinueveyaTest-Pathile kontrol edin.
Sonuç
PowerShell ile registry yönetimi, başlangıçta karmaşık görünse de temelde dosya sistemi mantığına benziyor. Get-Item, Set-Item, New-Item, Remove-Item gibi bildiğiniz cmdlet’leri zaten kullanıyorsunuz. Asıl güç, bu işlemleri scriptlerle otomatize edip onlarca veya yüzlerce makineye aynı anda uygulayabilmekten geliyor.
Gerçek hayatta en çok kullandığım senaryolar şunlar: toplu güvenlik hardening, uygulama envanteri çıkarma, deploy sonrası konfigürasyon doğrulama ve audit amaçlı registry snapshot alma. Bu yazıdaki fonksiyonları kendi ortamınıza uyarlayıp iç toolbox’ınıza ekleyebilirsiniz.
Son olarak şunu hatırlatmakta fayda var: Registry, Windows’un kalbidir. Yanlış bir değişiklik sistemi kullanılamaz hale getirebilir. Her zaman backup alın, önce test ortamında deneyin ve değişikliklerinizi dokümante edin. PowerShell’in gücünü sorumlu şekilde kullandığınızda, registry yönetimi artık korkulacak bir şey olmaktan çıkıp elinizin altındaki güçlü bir araca dönüşür.