Windows ortamlarında servis yönetimi, her sistem yöneticisinin günlük rutininin ayrılmaz bir parçası. Servisler durdu mu? Neden durdu? Nasıl başlatacaksın? Bu soruların cevabını çoğu zaman GUI üzerinden arayıp zaman kaybedebilirsin. Ama sc.exe komutunu bir kez doğru öğrendin mi, artık servisleri saniyeler içinde yönetirsin. Bu yazıda sc komutunu en ince ayrıntısına kadar ele alacağız, gerçek dünya senaryolarıyla pekiştireceğiz.
SC Komutu Nedir?
sc.exe (Service Control), Windows’un yerleşik servis yönetim aracıdır. Windows XP’den bu yana sistemlerde bulunur ve Windows Server ortamlarında servis oluşturma, silme, başlatma, durdurma ve yapılandırma gibi tüm işlemleri komut satırından yapmanı sağlar.
services.msc GUI aracının aksine sc, betiklerde kullanılabilir, uzak sistemlere bağlanabilir ve çok daha ayrıntılı çıktılar üretir. Bir sistem yöneticisi olarak otomasyon yapıyorsan, sc senin en yakın dostun olacak.
Önemli bir not: PowerShell’de sc yazarsan, Set-Content cmdlet’inin alias’ına düşersin. PowerShell içinden kullanmak istiyorsan sc.exe diye tam adıyla çağır. Biz bu yazıda klasik CMD ortamını baz alacağız.
Temel Sözdizimi
sc [sunucu_adi] [komut] [servis_adi] [parametreler]
Uzak bir sunucuya bağlanmak için sunucu adını \SunucuAdi formatında belirtirsin. Yerel sistemde çalışıyorsan bu kısmı atlarsın.
Servis Durumunu Sorgulamak
Bir servise ne olduğunu öğrenmek istiyorsun, ilk başvuracağın komut query olacak.
sc query spooler
Bu komut sana Print Spooler servisinin durumunu gösterir. Çıktıda şunları görürsün:
- SERVICE_NAME: Servisin kısa adı
- TYPE: Servis tipi (kendi sürecinde mi, paylaşımlı mı çalışıyor)
- STATE: Servisin durumu (RUNNING, STOPPED, PAUSED gibi)
- WIN32_EXIT_CODE: Son hata kodu
- CHECKPOINT: Uzun süren işlemlerde ilerleme sayacı
- WAIT_HINT: Beklenen maksimum süre
Sistemdeki tüm servislerin listesini görmek istiyorsan:
sc query type= all
Dikkat et, type= ile all arasında boşluk var. Bu boşluk önemli, unutursan komut hata verir. Sadece çalışan servisleri listelemek için:
sc query state= running
Sadece durmuş servisleri görmek için:
sc query state= stopped
Servis Detaylarını Görmek
query komutu genel durumu verir ama bir servisin tam yapılandırmasını görmek istiyorsan qc (query config) kullanırsın:
sc qc wuauserv
Bu komut Windows Update servisinin şu bilgilerini listeler:
- START_TYPE: Başlatma tipi (AUTO_START, DEMAND_START, DISABLED)
- BINARY_PATH_NAME: Servis çalıştırılabilir dosyasının yolu
- LOAD_ORDER_GROUP: Yüklenme grubu
- TAG: Yükleme sırası etiketi
- DISPLAY_NAME: Servisin görünen adı
- DEPENDENCIES: Bu servise bağımlı olan diğer servisler
- SERVICE_START_NAME: Servisin hangi hesap altında çalıştığı
Gerçek bir senaryoyu düşün: Bir servis sürekli duruyorsa ve nedenini anlamaya çalışıyorsun. İlk adım sc query ile durumu kontrol etmek, ikinci adım sc qc ile yapılandırmayı incelemek. Hangi hesap altında çalıştığını, hangi servislere bağımlı olduğunu bilmeden sorunu bulamazsın.
Servisi Başlatmak ve Durdurmak
Temel operasyonlardan başlayalım. Bir servisi başlatmak için:
sc start "Servis Adi"
Örneğin DHCP Client servisini başlatmak için:
sc start dhcp
Servisi durdurmak için:
sc stop dhcp
Bazı servisler “duraklama” özelliğini destekler. Bu özellik desteklenen servisleri durdurmadan askıya alabilirsin:
sc pause spooler
sc continue spooler
Ancak her servis pause/continue desteklemez. Servisin bunu destekleyip desteklemediğini öğrenmek için sc query çıktısındaki CONTROLS_ACCEPTED alanına bakarsın.
Servis Oluşturmak
Bu bölüm işlerin gerçekten güzelleştiği yer. Bazen bir uygulamayı servis olarak kaydetmen gerekiyor. Bunun için sc create kullanırsın:
sc create "MyApp" binpath= "C:Appsmyapp.exe" start= auto displayname= "My Application Service"
Yine dikkat et, binpath= yazdıktan sonra boşluk bırakman gerekiyor. Bu sc komutunun garip bir sözdizimi kuralı, çok kişiyi yanıltıyor.
Daha kapsamlı bir örnek:
sc create "BackupService" binpath= "C:Toolsbackup.exe --service" start= delayed-auto displayname= "Nightly Backup Service" obj= "NT AUTHORITYLocalService" password= ""
Bu komutta kullandığın parametreler:
- binpath=: Servis çalıştırılabilirinin tam yolu, varsa argümanlar da buraya eklenir
- start=: Başlatma tipi (auto, manual, disabled, delayed-auto)
- displayname=: Servis yöneticisinde görünecek isim
- obj=: Servisin çalışacağı kullanıcı hesabı
- password=: Belirtilen hesabın şifresi
delayed-auto başlatma tipi, sistem açılışında tüm kritik servisler yüklendikten sonra servisin başlamasını sağlar. Sunucu boot zamanını kısaltmak istiyorsan, özellikle kritik olmayan servisleri bu modda çalıştırabilirsin.
Servis Yapılandırmasını Değiştirmek
Var olan bir servisin yapılandırmasını değiştirmek için sc config kullanırsın. Diyelim ki bir servisin başlatma tipini değiştirmen gerekiyor:
sc config wuauserv start= disabled
Bu komut Windows Update’i devre dışı bırakır. Geri açmak istediğinde:
sc config wuauserv start= auto
Bir servisin çalıştığı hesabı değiştirmek istiyorsun:
sc config "MyService" obj= "DOMAINServiceAccount" password= "P@ssw0rd123"
Servis açıklamasını güncellemek için sc description kullanırsın:
sc description "MyApp" "Bu servis gece yedeklemelerini yonetir."
Servis Silmek
Artık ihtiyaç duymadığın bir servisi kaldırmak için sc delete kullanırsın:
sc delete "MyApp"
Eğer servis çalışıyorsa önce durdurman gerekir:
sc stop "MyApp"
sc delete "MyApp"
Önemli uyarı: Sistem servislerini silmek işletim sistemini bozabilir. sc delete komutunu kullanmadan önce ne yaptığından emin ol. Yanlışlıkla kritik bir servisi silersen sistemi kurtarman çok zahmetli olabilir.
Hata Durumunda Yapılacak İşlemleri Ayarlamak
Bu, çoğu sysadmin’in bilmediği ama çok işe yarayan bir özellik. Windows servisleri çöktüğünde ne yapılacağını belirleyebilirsin. sc failure komutuyla hata sonrası aksiyonları tanımlarsın:
sc failure "MyApp" reset= 86400 actions= restart/5000/restart/10000/reboot/60000
Bu komutu parçalayalım:
- reset=: Hata sayacının kaç saniye sonra sıfırlanacağı (86400 = 1 gün)
- actions=: Birinci, ikinci ve üçüncü hatada yapılacak aksiyonlar
- restart/5000: Servisi 5 saniye sonra yeniden başlat
- reboot/60000: Sunucuyu 60 saniye sonra yeniden başlat
Aksiyonlar slash ile ayrılmış aksiyon/gecikme_ms çiftleridir. Kullanabileceğin aksiyonlar:
- restart: Servisi yeniden başlatır
- reboot: Sistemi yeniden başlatır
- run: Belirtilen programı çalıştırır
- none: Hiçbir şey yapma
Eğer “run” aksiyonu kullanmak istiyorsan, çalıştırılacak komutu da belirtmen gerekir:
sc failure "MyApp" reset= 86400 actions= restart/5000/restart/10000/run/0 command= "C:Scriptsnotify_admin.bat"
Bu sayede servis üçüncü kez çöktüğünde admin’e bildirim gönderen bir script çalıştırabilirsin.
Uzak Sunucularda Servis Yönetimi
Datacenter’da onlarca sunucu varsa her birine RDP açmak istemezsin. sc komutu uzak sunuculara bağlanabilir:
sc \WebSunucu01 query iis_admin
sc \WebSunucu01 stop iis_admin
sc \WebSunucu01 start iis_admin
Uzak sunucuda yönetici yetkisine sahip olman gerekiyor. Farklı bir kullanıcı adıyla bağlanmak istiyorsan önce net use ile bağlantı kurabilirsin:
net use \WebSunucu01IPC$ /user:DOMAINadmin P@ssword123
sc \WebSunucu01 query spooler
Birden fazla sunucuda aynı işlemi yapmak için basit bir batch döngüsü yazabilirsin:
@echo off
for %%S in (Sunucu01 Sunucu02 Sunucu03 Sunucu04) do (
echo %%S uzerinde spooler durduruluyor...
sc \%%S stop spooler
timeout /t 3 /nobreak >nul
sc \%%S start spooler
echo %%S uzerinde spooler yeniden baslatildi.
)
echo Tum sunucularda islem tamamlandi.
Bu döngü dört sunucuda Print Spooler servisini sırayla yeniden başlatır. Patch sonrası servisleri restart etmen gerektiğinde bu tür scriptler hayat kurtarır.
Gerçek Dünya Senaryosu: Periyodik Servis Kontrolü
Bir üretim ortamında belirli servislerin çalışıp çalışmadığını kontrol eden ve gerektiğinde uyarı veren bir script şöyle görünebilir:
@echo off
setlocal enabledelayedexpansion
set LOG_FILE=C:Logsservis_kontrol_%date:~-4,4%%date:~-7,2%%date:~-10,2%.log
echo Servis Kontrol Raporu - %date% %time% >> %LOG_FILE%
echo ================================ >> %LOG_FILE%
for %%S in (spooler wuauserv W32Time Dnscache) do (
sc query %%S | find "RUNNING" >nul 2>&1
if !errorlevel! == 0 (
echo [OK] %%S servisi calisiyor >> %LOG_FILE%
) else (
echo [HATA] %%S servisi calismıyor - yeniden baslatiliyor >> %LOG_FILE%
sc start %%S >> %LOG_FILE% 2>&1
timeout /t 5 /nobreak >nul
sc query %%S | find "RUNNING" >nul 2>&1
if !errorlevel! == 0 (
echo [DUZELTILDI] %%S servisi basarıyla baslatildi >> %LOG_FILE%
) else (
echo [KRITIK] %%S servisi baslatilamadi - Manuel mudahale gerekli >> %LOG_FILE%
)
)
)
echo ================================ >> %LOG_FILE%
echo. >> %LOG_FILE%
Bu script’i Task Scheduler’a ekleyerek her 15 dakikada bir çalıştırabilirsin. Log dosyasından da geçmişe dönük analiz yapabilirsin.
Gerçek Dünya Senaryosu: Uygulama Güncelleme Sırasında Servis Yönetimi
Bir uygulama güncellemesi yapıyorsun ve servisleri belirli bir sırada durdurman, dosyaları değiştirmen ve sonra geri başlatman gerekiyor:
@echo off
echo Uygulama guncellemesi basliyor...
echo 1. Frontend servisi durduruluyor...
sc stop FrontendSvc
timeout /t 10 /nobreak >nul
echo 2. API servisi durduruluyor...
sc stop ApiSvc
timeout /t 10 /nobreak >nul
echo 3. Backend servisi durduruluyor...
sc stop BackendSvc
timeout /t 15 /nobreak >nul
echo 4. Dosyalar kopyalaniyor...
xcopy /E /Y /I "C:Stagingv2.0*" "C:Production"
echo 5. Backend servisi baslatiliyor...
sc start BackendSvc
timeout /t 20 /nobreak >nul
echo 6. API servisi baslatiliyor...
sc start ApiSvc
timeout /t 10 /nobreak >nul
echo 7. Frontend servisi baslatiliyor...
sc start FrontendSvc
timeout /t 10 /nobreak >nul
echo 8. Tum servisler kontrol ediliyor...
sc query BackendSvc | find "RUNNING"
sc query ApiSvc | find "RUNNING"
sc query FrontendSvc | find "RUNNING"
echo Guncelleme tamamlandi.
SC ile ERRORLEVEL Kullanımı
Servis operasyonları sonrası hata kodu kontrolü yapmak, güvenilir scriptler yazmanın temelidir. sc komutu başarısız olduğunda ERRORLEVEL değeri 0’dan farklı döner:
sc start "MyService"
if %errorlevel% neq 0 (
echo HATA: Servis baslatılamadi. Hata kodu: %errorlevel%
exit /b %errorlevel%
)
echo Servis basarıyla baslatildi.
Yaygın hata kodları:
- 1060: Belirtilen servis mevcut değil
- 1062: Servis başlatılmamış durumda (stop komutu için)
- 1056: Servis zaten çalışıyor
- 5: Erişim reddedildi, yönetici yetkisi gerekiyor
Servis Bağımlılıklarını Yönetmek
Bir servisin başka servislere bağımlı olmasını ayarlayabilirsin. Bu, başlangıç sırasını kontrol etmek için kullanışlıdır:
sc config "MyApp" depend= RPCSS/LanmanWorkstation
Bu komut MyApp servisinin RPCSS ve LanmanWorkstation servislerine bağımlı olduğunu belirtir. Sistem bu iki servis başlamadan MyApp‘i başlatmaya çalışmaz.
Mevcut bağımlılıkları görüntülemek için sc qc çıktısındaki DEPENDENCIES satırına bakarsın. Bağımlılıkları kaldırmak istiyorsan:
sc config "MyApp" depend= /
Servis Güvenlik Tanımlayıcıları
İleri düzey bir konu olarak servis güvenlik tanımlayıcılarına da değinelim. sc sdshow ile bir servisin güvenlik ayarlarını görebilirsin:
sc sdshow spooler
SDDL (Security Descriptor Definition Language) formatında çıktı alırsın. Bu çıktı karmaşık görünür ama ACL bilgilerini içerir. Güvenlik tanımlayıcısını değiştirmek için sc sdset kullanırsın, ancak bu işlemi yapmadan önce SDDL sözdizimini iyi anlamanı öneririm.
Sık Yapılan Hatalar
Yıllar içinde en sık gördüğüm hataları paylaşayım:
Boşluk sorunları: sc config komutlarında = işaretinden sonra boşluk bırakmayı unutmak. Bu hata geri dönüp baktığında gülünç görünür ama saatlerce vakit aldırabilir.
PowerShell’de sc yazmak: PowerShell konsolunda sc yazarsan Set-Content‘e düşersin. Mutlaka sc.exe yaz veya CMD kullan.
Servis adı ile görünen adı karıştırmak: “Print Spooler” görünen ad, spooler ise servis adı. sc komutlarında her zaman kısa servis adını kullan.
Silmeden önce durdurmayı atlamak: Çalışan bir servisi silmeye çalışırsan sistem siler ama servis marker’ını “pending delete” olarak işaretler. Sistemi yeniden başlatmadan sorunlar yaşayabilirsin.
Uzak sunucu yetkisi: Uzak sunucuda servis yönetimi yaparken o sunucuda yerel admin yetkisine ihtiyacın var. Domain Admin olmak yetmeyebilir, çünkü bazı sistemlerde yerel admin ile domain admin hakları farklılaştırılmış olabilir.
Sonuç
sc.exe komutu, Windows servis yönetiminin omurgasıdır. GUI’den çok daha hızlı, betiklere entegre edilebilir ve uzak sistemlerle çalışabilir. Bir sysadmin olarak bu komutu gerçekten özümsedin mi, rutin operasyonların büyük kısmını otomatize edebilirsin.
Özellikle şu alanlarda sc senin iş yükünü ciddi ölçüde azaltır: toplu sunucu yönetimi, uygulama deployment scriptleri, servis sağlık kontrolleri ve hata sonrası otomatik kurtarma mekanizmaları. Konfigürasyon yönetimi araçlarıyla (Ansible, Puppet gibi) çalışmıyorsan bile, iyi yazılmış sc tabanlı batch scriptler sana büyük esneklik sağlar.
Pratik tavsiyem: Önce test ortamında dene, servis isimlerini her zaman doğrula ve kritik operasyonlarda log tut. Üretime geçmeden önce sc qc ile yapılandırmayı gözden geçirmek küçük ama çok değerli bir alışkanlık.