GUI olmadan bir Windows Server yönetmek ilk başta biraz ürkütücü gelebilir. Fare tıklamaları olmadan, rengarenk arayüzler olmadan, sadece bir komut satırı penceresi ile karşı karşıyasın. Ama bu yazıyı okuduktan sonra Server Core’un aslında ne kadar güçlü ve yönetilebilir bir platform olduğunu göreceksin. Üstelik daha az saldırı yüzeyi, daha az kaynak tüketimi ve daha istikrarlı bir sistem kazanıyorsun. Haydi başlayalım.
Windows Server Core Nedir ve Neden Tercih Edilmeli
Windows Server Core, GUI bileşenleri kaldırılmış, yalnızca komut satırı ile yönetilen bir Windows Server kurulum seçeneğidir. Microsoft bu yaklaşımı Windows Server 2008’den itibaren sunuyor ve her geçen sürümle daha olgunlaşıyor.
Peki neden birisi kasıtlı olarak GUI’dan vazgeçsin? Birkaç somut neden var:
- Daha az saldırı yüzeyi: Yüzlerce GUI bileşeni yüklü değilse, yama gerektiren, güvenlik açığı barındırabilecek bileşen sayısı dramatik şekilde azalır
- Düşük kaynak tüketimi: Ortalama 1-2 GB daha az RAM kullanımı, disk alanında da ciddi tasarruf
- Zorunlu otomasyon: GUI olmayınca her şeyi script ile yapmak zorundasın, bu da tekrar edilebilir ve belgelenmiş bir altyapı anlamına gelir
- Daha az yeniden başlatma: Güncellemeler daha hızlı uygulanır, reboot sayısı azalır
Özellikle Hyper-V host’ları, dosya sunucuları, DNS/DHCP sunucuları ve web sunucuları için Server Core ideal bir seçimdir.
Kurulum Sonrası İlk Adımlar
Kurulumu bitirip ilk açılışta seni karşılayan şey bir komut istemi penceresi. Panik yok. İlk yapman gereken birkaç temel ayar var.
Bilgisayar Adını Değiştirme
# Mevcut bilgisayar adını görüntüle
hostname
# PowerShell ile yeniden adlandır
Rename-Computer -NewName "SRV-CORE-01" -Restart
IP Adresi Yapılandırması
DHCP yerine statik IP atamak production ortamında şart. Önce ağ adaptörünü bul, sonra yapılandır:
# Ağ adaptörlerini listele
Get-NetAdapter
# Statik IP ata (InterfaceIndex'i kendi değerinle değiştir)
New-NetIPAddress -InterfaceIndex 2 -IPAddress 192.168.1.50 -PrefixLength 24 -DefaultGateway 192.168.1.1
# DNS sunucusu tanımla
Set-DnsClientServerAddress -InterfaceIndex 2 -ServerAddresses ("192.168.1.10","192.168.1.11")
# Ayarları doğrula
Get-NetIPConfiguration
Domain’e Katılma
Sunucuyu domain’e almak çoğu kurumsal ortamda ilk işlerden biri:
# Domain'e katıl ve yeniden başlat
$credential = Get-Credential
Add-Computer -DomainName "sirket.local" -Credential $credential -Restart
# Katılımı doğrula
(Get-WmiObject Win32_ComputerSystem).Domain
Firewall ve Uzak Yönetim
Server Core’u uzaktan yönetebilmek için WinRM’i aktif etmen gerekiyor:
# WinRM'i başlat ve yapılandır
Enable-PSRemoting -Force
# Güvenlik duvarı kurallarını kontrol et
Get-NetFirewallRule | Where-Object {$_.DisplayName -like "*Remote*" -and $_.Enabled -eq "True"} | Select-Object DisplayName, Direction, Action
Rol ve Özellik Yönetimi
GUI olmadan rol ekleyip kaldırmak çocuk oyuncağı. Install-WindowsFeature cmdlet’i senin en iyi arkadaşın.
Temel Rol Kurulumları
# Kullanılabilir tüm rolleri listele
Get-WindowsFeature | Where-Object {$_.InstallState -eq "Available"} | Select-Object Name, DisplayName
# IIS Web Server kurulumu
Install-WindowsFeature -Name Web-Server -IncludeManagementTools -IncludeAllSubFeature
# Hyper-V kurulumu
Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart
# DNS Server kurulumu
Install-WindowsFeature -Name DNS -IncludeManagementTools
# DHCP Server kurulumu
Install-WindowsFeature -Name DHCP -IncludeManagementTools
# Dosya Sunucusu rolleri
Install-WindowsFeature -Name FS-FileServer, FS-DFS-Namespace, FS-DFS-Replication
# Kurulu rolleri kontrol et
Get-WindowsFeature | Where-Object {$_.InstallState -eq "Installed"} | Select-Object Name, DisplayName
Birden fazla sunucuya aynı konfigürasyonu uygulamak için önce bir sunucudan yapılandırmayı dışa aktar:
# Mevcut kurulu rolleri XML'e aktar
Get-WindowsFeature | Where-Object {$_.Installed -eq $true} | Export-Clixml -Path "C:Tempinstalled_features.xml"
# Başka bir sunucuda içe aktar ve kur
$features = Import-Clixml -Path "\dosyasunucusushareinstalled_features.xml"
$featureNames = $features | Select-Object -ExpandProperty Name
Install-WindowsFeature -Name $featureNames -IncludeManagementTools
Uzaktan Yönetim Senaryoları
Server Core’un gerçek gücü uzaktan yönetilebilirliğinde. Kendi masaüstünden tüm server’ları yönetebilirsin.
RSAT ile GUI Araçları Kullanmak
Windows 10/11 iş istasyonunda RSAT araçlarını kurunca, uzaktaki Server Core’u sanki önünde oturuyor gibi yönetebilirsin. Ama biz sysadminler script yazmanın tadını çıkaralım.
PSRemoting ile Toplu Yönetim
# Birden fazla sunucuya aynı anda bağlan
$sunucular = @("SRV-CORE-01", "SRV-CORE-02", "SRV-CORE-03")
# Paralel komut çalıştırma
Invoke-Command -ComputerName $sunucular -ScriptBlock {
$os = Get-WmiObject Win32_OperatingSystem
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
[PSCustomObject]@{
Sunucu = $env:COMPUTERNAME
UptimeSaat = [math]::Round((Get-Date - $os.ConvertToDateTime($os.LastBootUpTime)).TotalHours, 1)
DiskBosGB = [math]::Round($disk.FreeSpace / 1GB, 2)
RAMBosGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
}
}
Bu script gerçek dünyada çok işe yarıyor. Sabah işe gelince tüm sunucuların anlık durumunu tek komutla görebiliyorsun.
Servis ve Process Yönetimi
Servis İzleme ve Yönetim Scripti
Kritik servislerin çalışıp çalışmadığını düzenli kontrol etmek ve sorun varsa uyarı almak için pratik bir script:
# Kritik servisleri izle ve gerekirse yeniden başlat
$kritikServisler = @("W32Time", "DNS", "DHCP", "Netlogon", "SamSs")
$logDosyasi = "C:Logsservis_kontrol_$(Get-Date -Format 'yyyyMMdd').log"
foreach ($servis in $kritikServisler) {
$s = Get-Service -Name $servis -ErrorAction SilentlyContinue
if ($null -eq $s) {
$mesaj = "$(Get-Date -Format 'HH:mm:ss') - UYARI: $servis servisi bulunamadi"
Add-Content -Path $logDosyasi -Value $mesaj
continue
}
if ($s.Status -ne "Running") {
$mesaj = "$(Get-Date -Format 'HH:mm:ss') - HATA: $servis durdu. Yeniden baslatiliyor..."
Add-Content -Path $logDosyasi -Value $mesaj
try {
Start-Service -Name $servis
$mesaj = "$(Get-Date -Format 'HH:mm:ss') - BASARILI: $servis yeniden baslatildi"
} catch {
$mesaj = "$(Get-Date -Format 'HH:mm:ss') - KRITIK: $servis baslatılamadı! Hata: $_"
}
Add-Content -Path $logDosyasi -Value $mesaj
} else {
Add-Content -Path $logDosyasi -Value "$(Get-Date -Format 'HH:mm:ss') - OK: $servis calisiyor"
}
}
Bu scripti Windows Task Scheduler’a ekleyerek her 15 dakikada bir çalıştırabilirsin. Scheduled task oluşturmak için:
# Scheduled task oluştur
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NonInteractive -ExecutionPolicy Bypass -File C:ScriptsServisKontrol.ps1"
$trigger = New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Minutes 15) -Once -At (Get-Date)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 5) -RestartCount 3
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "KritikServisKontrol" -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Description "Kritik servisleri 15 dakikada bir kontrol eder"
Disk ve Depolama Yönetimi
Disk Yapılandırma Scripti
Yeni bir disk eklendiğinde onu hazırlamak için tekrar eden işlemleri otomatize etmek büyük zaman kazandırır:
# Yeni eklenen diski bul, başlat ve biçimlendir
function Initialize-NewDisk {
param(
[Parameter(Mandatory)]
[char]$DriveHarfi,
[string]$DiskEtiketi = "Data",
[string]$DosyaSistemi = "NTFS"
)
# Başlatılmamış diskleri bul
$rawDiskler = Get-Disk | Where-Object {$_.PartitionStyle -eq "RAW"}
if ($rawDiskler.Count -eq 0) {
Write-Host "Baslatilacak yeni disk bulunamadi." -ForegroundColor Yellow
return
}
foreach ($disk in $rawDiskler) {
Write-Host "Disk $($disk.Number) islemde: $([math]::Round($disk.Size / 1GB))GB" -ForegroundColor Cyan
# GPT ile başlat
Initialize-Disk -Number $disk.Number -PartitionStyle GPT
# Yeni bölüm oluştur
$partition = New-Partition -DiskNumber $disk.Number -UseMaximumSize -DriveLetter $DriveHarfi
# Biçimlendir
Format-Volume -DriveLetter $DriveHarfi -FileSystem $DosyaSistemi -NewFileSystemLabel $DiskEtiketi -Confirm:$false
Write-Host "Disk basariyla hazırlandi: $DriveHarfi`:" -ForegroundColor Green
}
}
# Kullanım örneği
Initialize-NewDisk -DriveHarfi 'D' -DiskEtiketi "Veri_Diski" -DosyaSistemi "NTFS"
Güvenlik Yapılandırması
Server Core kullanmanın güvenlik avantajlarından tam anlamıyla yararlanmak için birkaç temel hardening adımı uygulamak gerekiyor.
Temel Güvenlik Yapılandırmaları
# Gereksiz servisleri devre dışı bırak
$gereksizServisler = @(
"XblAuthManager", # Xbox Live kimlik doğrulama
"XblGameSave", # Xbox oyun kaydetme
"XboxNetApiSvc", # Xbox ağ servisi
"WSearch", # Windows Search (sunucuda gereksiz)
"Fax", # Fax servisi
"TabletInputService" # Tablet girdi servisi
)
foreach ($servis in $gereksizServisler) {
$s = Get-Service -Name $servis -ErrorAction SilentlyContinue
if ($null -ne $s) {
Stop-Service -Name $servis -Force -ErrorAction SilentlyContinue
Set-Service -Name $servis -StartupType Disabled
Write-Host "$servis devre disi birakildi" -ForegroundColor Yellow
}
}
# NTLMv1'i devre dışı bırak
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlLsa" -Name "LmCompatibilityLevel" -Value 5 -Type DWord
# SMBv1'i kapat (EternalBlue açığına karşı)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Confirm:$false
# Güvenlik duvarı profillerini yapılandır
Set-NetFirewallProfile -Profile Domain -DefaultInboundAction Block -DefaultOutboundAction Allow
Set-NetFirewallProfile -Profile Private -DefaultInboundAction Block -DefaultOutboundAction Allow
Set-NetFirewallProfile -Profile Public -DefaultInboundAction Block -DefaultOutboundAction Allow
Write-Host "Temel guvenlik yapilandirmasi tamamlandi" -ForegroundColor Green
Olay Günlüğü İzleme
Güvenlik olaylarını izlemek için basit ama etkili bir script:
# Son 24 saatteki başarısız oturum açma denemelerini raporla
$baslangic = (Get-Date).AddHours(-24)
$hataliGirisler = Get-WinEvent -FilterHashtable @{
LogName = "Security"
Id = 4625
StartTime = $baslangic
} -ErrorAction SilentlyContinue
if ($hataliGirisler) {
Write-Host "Son 24 saatte $($hataliGirisler.Count) basarisiz giris denemesi" -ForegroundColor Red
$hataliGirisler | ForEach-Object {
$xml = [xml]$_.ToXml()
$kullanici = $xml.Event.EventData.Data | Where-Object {$_.Name -eq "TargetUserName"} | Select-Object -ExpandProperty "#text"
$kaynak = $xml.Event.EventData.Data | Where-Object {$_.Name -eq "IpAddress"} | Select-Object -ExpandProperty "#text"
[PSCustomObject]@{
Zaman = $_.TimeCreated
KullaniciAdi = $kullanici
KaynakIP = $kaynak
}
} | Group-Object KaynakIP | Sort-Object Count -Descending | Select-Object -First 10 | Format-Table Name, Count -AutoSize
} else {
Write-Host "Son 24 saatte basarisiz giris denemesi yok" -ForegroundColor Green
}
Güncelleme Yönetimi
Server Core’da Windows Update’i komut satırından yönetmek için PSWindowsUpdate modülünü kullanabilirsin:
# PSWindowsUpdate modülünü kur
Install-Module -Name PSWindowsUpdate -Force -SkipPublisherCheck
# Mevcut güncellemeleri listele
Get-WindowsUpdate
# Tüm güncellemeleri indir ve kur (yeniden başlatma olmadan)
Install-WindowsUpdate -AcceptAll -IgnoreReboot -Verbose
# Yalnızca güvenlik güncellemelerini kur
Install-WindowsUpdate -Category "Security Updates" -AcceptAll -AutoReboot
# Uzak sunuculara güncelleme dağıt
Invoke-WUJob -ComputerName "SRV-CORE-01","SRV-CORE-02" -Script {
Import-Module PSWindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot
} -Credential (Get-Credential) -RunNow
SConfig Aracı
Server Core ile gelen gizli bir silah: SConfig. Bir metin menüsü sunan bu araç, temel yapılandırma işlerini biraz daha erişilebilir kılıyor. Özellikle ilk kurulumda çok işe yarıyor.
# SConfig'i başlat
SConfig
SConfig ile şunları yapabilirsin:
- 1: Domain veya çalışma grubuna katılma
- 2: Bilgisayar adını değiştirme
- 3: Uzak yönetimi etkinleştirme veya devre dışı bırakma
- 4: Windows Update yapılandırması
- 5: Windows Update ayarları
- 6: İndirme ve yükleme güncellemeleri
- 7: Uzak masaüstünü etkinleştirme veya devre dışı bırakma
- 8: Ağ ayarları
- 9: Tarih ve saat
- 10: Telemetri ayarları
- 11: Windows Aktivasyonu
- 12: Oturumu kapat
- 13: Yeniden başlat
- 14: Kapat
Yeni başlayanlara ve hızlı değişiklik yapmam gerektiğinde ben de SConfig’e başvuruyorum. Utanılacak bir şey değil.
Performans İzleme
Server Core’da performans takibi yaparken GUI araçları olmasa da PowerShell ile oldukça detaylı veriler toplayabilirsin:
# Kapsamlı sistem performans raporu
function Get-SunucuRaporu {
$os = Get-WmiObject Win32_OperatingSystem
$cpu = Get-WmiObject Win32_Processor
$diskler = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"
$network = Get-NetAdapter | Where-Object {$_.Status -eq "Up"}
Write-Host "=== SUNUCU PERFORMANS RAPORU ===" -ForegroundColor Cyan
Write-Host "Sunucu: $($env:COMPUTERNAME)" -ForegroundColor White
Write-Host "Tarih: $(Get-Date -Format 'dd.MM.yyyy HH:mm')" -ForegroundColor White
Write-Host ""
# Uptime
$uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime)
Write-Host "Uptime: $($uptime.Days) gun $($uptime.Hours) saat" -ForegroundColor Green
# CPU
$cpuYuk = (Get-Counter "Processor(_Total)% Processor Time").CounterSamples.CookedValue
Write-Host "CPU Kullanim: $([math]::Round($cpuYuk, 1))%" -ForegroundColor $(if($cpuYuk -gt 80){"Red"}elseif($cpuYuk -gt 60){"Yellow"}else{"Green"})
# RAM
$toplamRAM = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2)
$bosRAM = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
$kullanilanRAM = $toplamRAM - $bosRAM
$ramYuzde = [math]::Round(($kullanilanRAM / $toplamRAM) * 100, 1)
Write-Host "RAM: $kullanilanRAM/$toplamRAM GB ($ramYuzde% dolu)" -ForegroundColor $(if($ramYuzde -gt 85){"Red"}elseif($ramYuzde -gt 70){"Yellow"}else{"Green"})
# Diskler
Write-Host ""
Write-Host "DISKLER:" -ForegroundColor Cyan
foreach ($disk in $diskler) {
$toplamGB = [math]::Round($disk.Size / 1GB, 1)
$bosGB = [math]::Round($disk.FreeSpace / 1GB, 1)
$dolulukYuzde = [math]::Round((($toplamGB - $bosGB) / $toplamGB) * 100, 1)
$renk = if($dolulukYuzde -gt 90){"Red"}elseif($dolulukYuzde -gt 75){"Yellow"}else{"Green"}
Write-Host " $($disk.DeviceID) - $bosGB/$toplamGB GB bos ($dolulukYuzde% dolu)" -ForegroundColor $renk
}
}
Get-SunucuRaporu
Gerçek Dünya Senaryosu: Web Sunucusu Hazırlama
Diyelim ki production ortamı için sıfırdan bir IIS web sunucusu hazırlaman gerekiyor. Tüm öğrendiklerimizi bir araya getiren gerçekçi bir senaryo:
# Web sunucusu tam kurulum scripti
param(
[Parameter(Mandatory)]
[string]$SiteName,
[int]$Port = 80,
[string]$PhysicalPath = "C:InetpubSites"
)
# IIS ve gerekli bileşenleri kur
$iisOzellikleri = @(
"Web-Server",
"Web-Common-Http",
"Web-Static-Content",
"Web-Default-Doc",
"Web-Http-Errors",
"Web-Asp-Net45",
"Web-CGI",
"Web-Http-Logging",
"Web-Request-Monitor",
"Web-Http-Tracing",
"Web-Security",
"Web-Basic-Auth",
"Web-Windows-Auth",
"Web-Filtering",
"Web-Mgmt-Tools"
)
Write-Host "IIS kuruluyor..." -ForegroundColor Cyan
Install-WindowsFeature -Name $iisOzellikleri -IncludeManagementTools | Out-Null
Write-Host "IIS kurulumu tamamlandi" -ForegroundColor Green
# Site dizinini oluştur
$sitePath = Join-Path $PhysicalPath $SiteName
if (-not (Test-Path $sitePath)) {
New-Item -ItemType Directory -Path $sitePath -Force | Out-Null
}
# IIS'te yeni site oluştur
Import-Module WebAdministration
New-WebSite -Name $SiteName -Port $Port -PhysicalPath $sitePath -Force
# Default site'i kaldır
Remove-WebSite -Name "Default Web Site" -ErrorAction SilentlyContinue
# Uygulama havuzu yapılandır
$appPool = "AppPool_$SiteName"
New-WebAppPool -Name $appPool
Set-ItemProperty "IIS:AppPools$appPool" -Name processModel.idleTimeout -Value ([TimeSpan]::FromMinutes(0))
Set-ItemProperty "IIS:AppPools$appPool" -Name recycling.periodicRestart.time -Value ([TimeSpan]::Zero)
# Site'yi uygulama havuzuna bağla
Set-ItemProperty "IIS:Sites$SiteName" -Name applicationPool -Value $appPool
Write-Host "Site '$SiteName' port $Port uzerinde hazir: $sitePath" -ForegroundColor Green
Write-Host "Uygulama havuzu: $appPool" -ForegroundColor Green
Sonuç
Windows Server Core ilk bakışta korkutucu görünebilir ama aslında sysadmin’in en büyük yardımcısı. GUI olmadan çalışmak seni otomasyon yapmaya zorluyor ve bu zorunluluk zamanla büyük bir avantaja dönüşüyor. Bugün yazdığın bir script, yarın onlarca sunucuya aynı anda uygulanabilen bir altyapı aracı haline geliyor.
Bu yazıda ele aldığımız konuları özetlersek: İlk kurulum ve temel yapılandırma adımlarından başlayarak rol yönetimi, uzaktan yönetim senaryoları, servis izleme, disk yönetimi, güvenlik sertleştirme, güncelleme yönetimi ve performans izlemeye kadar kapsamlı bir yol haritası çizdik. Her konuda verilen script örnekleri gerçek ortamlarda kullanılabilir, ihtiyacına göre uyarlayabileceğin başlangıç noktaları.
Eğer hala “GUI olmadan nasıl yaparım?” diye düşündüğün anlar olursa, şunu hatırla: Grafik arayüzler kolaylık değil, gizlilik yaratır. Bir butona tıkladığında arka planda ne olduğunu bilmiyorsun. PowerShell ile her adımı gördüğünde, anladığında ve kontrol ettiğinde gerçek anlamda sisteme hakim oluyorsun. İşte bu yüzden Server Core seveni Server Core’u bırakmak istemez.