31.07.2024

Windows Defender'dan kurtulmak

Son dönemde Windows 11'in daha "hafif" sürümü olan 24H2 IoT LTSC sürümünü gördüm. Denemek istedim. Ancak alıştığımız Windows 11'den biraz farklı. Üzerinde Microsoft Store uygulaması gelmiyor. Sıradan bir Windows 11 bilgisayarda bulunan Virus ve Tehdit Koruması (Virus & Threat Protection) uygulaması yok (bu aslında sadece arka planda çalışan Windows Defender Antivirus'un durumunu görüntülemek ve ayarlarını değiştirmek için bir uygulama. Yoksa Defender Antivirus var ve çalışıyor). Bu ve bunun gibi yan uygulamaları kurmak istediğimde başarısız oldum. Denemek için Windows Defender'ı (antivirus) durdurmak istedim, onu da şu adımlarla yaptım.

Öncelikle bilgisayarı güvenli kipte açtım. Güvenli kipte açabilmek için msconfig'i çalıştırıp önyükleme sekmesinde önyükleme seçeneklerinden "güvenli önyüklemeyi" seçip alttaki ayarı en azda bıraktım.

Yeniden başlatıp C:\Programdata\Microsoft\Windows Defender klasörünün altındaki Platform klasörünün sahibini SYSTEM'den Administrators grubuna değiştirdim. Bağlantısını verdiğim LazyAdmin sayfasında bunu sadece Administrator kullanıcısı olarak göstermiş, ama benim sistemimde Administrator devre dışıydı. Administrators grubuna üye olan kendi kullanıcımla bunu yapabilmek için bu küçük değişikliği yaptım. Sonra bu klasörün yetkilerine SYSTEM ve TrustedInstaller kullanıcılarına ait satırları sildim, sadece Administrators grubuna ait bir tam yetki bıraktım.

Bu aşamadan sonra bazı Windows Defender hizmetlerini devre dışı bırakmak için kayıt defteri düzenleyicisini (regedit) açarak HKLM\SYSTEM\CurrentControlSet\Service anahtarı altında aşağıdaki hizmetlere ait Start değişkenlerinin değerini 4 (devre dışı) yapmak:

  • Sense
  • WdBoot
  • WdFilter
  • WdNisDrv
  • WdNisSvc
  • WinDefend

Benim yaptığım hatayı yaparak wd ile başlayan hizmetlerin tümünün (Wdf01000 gibi) başlamasını devreden çıkarmayın. Bu hatayı yaparsanız Wdf01000'ın varsayılan başlangıç değeri 0. Ve bunu değiştirmek için USB veya DVD'den açarak

reg load HKLM\Temp C:\Windows\System32\config\SYSTEM

ile SYSTEM hive'ını yüklemek ve Wdf01000'ın start'ını 0 yaparak 

reg unload HKLM\Temp

yaptıktan sonra yeniden başlatmak gerek. Bu hatayı yapmayanlar zaten bir sonraki açılışta Defender'i devre dışı bulacaklar.

PS> Get-Service  Sense, WdBoot, WdFilter, WdNisSvc, WdNisSvc, WinDefend
Status   Name               DisplayName
------   ----               -----------
Stopped  Sense              Windows Defender Gelişmiş Tehdit Ko...
Stopped  WdBoot             Microsoft Defender Virüsten Koruma ...
Stopped  WdFilter           Microsoft Defender Virüsten Koruma ...
Stopped  WdNisDrv           Microsoft Defender Virüsten Koruma ...
Stopped  WdNisSvc           Microsoft Defender Antivirus Networ...
Stopped  WinDefend          Microsoft Defender Antivirus Service

komutu ile hizmetlerin durduğu görülebilir. Tamamen deneme amaçlı yaptığım bu kurulumda elim değmişken Dosvc, wuausrv ve BITS hizmetlerini de durdurmayı tercih ettim.

20.07.2024

Crowdstrike strikes back

Dün, 19 Temmuz 2024, bir çok firma için bir siber felaket gibiydi. Havayolları, bankalar, hastaneler, büyük basın kuruluşları... Hepsi ya hizmet veremediler, ya da hizmetlerinde kesintiler yaşandı. Uçak seferleri durdu, ameliyatlar iptal edildi, TV yayınları durdu. Herkes dünya çapında mavi ekran yaşayan Windows'ları görünce Microsoft kaynaklı olduğunu düşündü. Ama bugünkü suçlumuz Crowdstrike.

Bütün internet bu konu ile ilgili haberlerle dolu [1],[2]. Önemli konu şu ki, bu ne ilk ne de son olacak. Daha önce bu olayın benzerini benim hatırladığım McAfee ve Avira ile de yaşamıştık. Bilişim dünyası bu gibi olaylara hazır değil mi acaba? Bu gibi olaylara hazır olunabilir mi? Güncellemelerin önce küçük bir grup üzerinde denenmesi ve sorun yaşanmaması sonrasında diğer sistemlere uygulanabilmesi yeni kavramlar değil, ama bunların bir uzman tarafından her gün yapılması çok pratik değil. Belki bunları önümüzdeki günlerde otomatik olarak yapan sistemler tasarlanabilir. Aynı şey işletim sistemi güncellemeleri (Windows, Linux, vs) için de gerekli. Ama güncellemeleri kapatmak hiç bir zaman çözüm olarak düşünülmemeli.

---

[1] https://www.bbc.com/news/articles/cp4wnrxqlewo
[2] https://edition.cnn.com/2024/07/19/tech/crowdstrike-update-global-outage-explainer/index.html

19.07.2024

Get-ChildItem ve -Exclude parametresi

Bazen bir dosya aramak için -Path, -Recurse, -Include parametrelerini kullanmak yetmez, bir de -Exclude kullanmak gerekir. Örneğin Windows klasörünün altında sysdm.cpl dosyasını arıyorum, ama WinSxS klasörünün altındaki kopya(lar|s)ını listelemek istemiyorum. O amaçla aşağıdaki komutlardan herhangi birini kullandığımda hiç sonuca ulaşamıyorum.

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "C:\Windows\WinSxS"
Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "C:\Windows\WinSxS*"
Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -Exlude "*WinSxS*"

Çünkü, Exclude parametresi bunun için tasarlanmamış. Sadece dosya isimlerinde bir kıyaslama yapabiliyor. Aynı -Include'da olduğu gibi. Alternatif çözümler mevcut. Örneğin

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse | where-Object {$_.FullName -notlike "*WinSxS*"}

Ama bu şekilde aslında Get-ChildItem bütün WinSxS alt klasörünü tarıyor, ama çıkan sonuçarın içinde WinSxS geçiyorsa bunlar ekrana yazılmıyor. Bu istediğim birşey değil, ama daha iyisini bulamadım.

Windows klasörünün altında bazı yüksek güvenlikli alt klasörler olduğu için ekranın kırmızı hata mesajları ile dolmasını engellemek için -ErrorAction SilentlyContinue (veya kısaca -EA silent) kullanılabilir.

Get-ChildItem -Path C:\Windows -Include sysdm.cpl -Recurse -ErrorAction SilentlyContinue | 
	Where-Object {$_.FullName -notlike "*WinSxS*"}

Bunu uzun bulanlar için (ki ben de buluyorum) alias'lar ve kısaltmalar var

dir C:\Windows sysdm.cpl -r -ea silent | ? fullName -notlike "*WinSxS*"

18.07.2024

WinSxS, sfc ve dism

Uzun dönem Windows kullanıcıları, sistem klasörlerinin (genellikle C:\Windows) altında WinSxS adında bir klasörün olduğunu görmüşlerdir. Bu klasör korunan ve içeriği administrator ile bile değiştirilemeyen bir yapıya sahiptir. Kurulumdaki bütün sistem dosyalarının asılları bu klasörün altındadır. Kullanımdaki kopyası ise aslında bir kopya değil, dosyanın aslına bir harlink'tir. Örnek olarak explorer.exe'ye bakalım.

C:\> dir C:\Windows\explorer.exe | fl FullName, LinkType, Target

FullName : C:\Windows\explorer.exe
LinkType : HardLink
Target   : {C:\Windows\WinSxS\amd64_microsoft-windows-explorer...

Bu klasördeki bütün dosyaları görmek için

dir * -file | ft Name, LinkType

kullanabiliriz. Evet, bu güvenlik önlemlerine karşı kötü niyetli yazılımların da karşı yöntemleri var. Herşeye rağmen hardlink bozulabilir, sistem dosyası kötü bir kopya ile değiştirilebilr. Hatta WinSxS klasörü altındaki dosya bile değiştirilebilir. Sistemimizde beklenmeyen bir durum olduğunda her kaynakta ilk yapılması gereken

sfc /scannow

olarak önerilmiş. Arka planda bu komut, sistem dosyalarını tarar, bütünlüğünü, denetler ve güvenilir bir katalogdaki özelliklere (imza, hash vs) sahip olup olmadığını kontrol eder. Ayrıca hardlink'inin doğru olup olmadığına da bakar. Sonra eğer burada bir sorun algılarsa WinSxS altındaki doğru dosyaya olan hardlink'i tekrar oluşturarak onarmaya çalışır. WinSxS altında bir dosyanın birden fazla sürümü olabilir. Bütün sürümler yinw WinSxS klasöründe saklanır. O yüzden en son güncelleme ile gelen sürüme hardlink oluşturulması önemli.

WinSxS klasöründe bir bozulma olmuşsa sfc bu aşamada yetersiz kalır. Bu bozulmayı onarmak için kullanılacak araç dism. Dism'in kafa karıştıran 3 farklı komutu var:

  • CheckHealth
  • ScanHealth
  • RestoreHealth

Bu 3 komutu, bir disk taramasındaki işlemlere benzeterek açıklamaya çalışacağım.

Diskimizde bir sorun olduğunu anlamak için bir tarama yapmak istiyoruz. Ama hızlı olmasını istiyoruz. Bütün diski taramak çok zaman ve enerji alan bir işlem. Aslında diskte işlem yaparken hata ile karşılaşan bir program var mı diye baksak olmaz mı? Bunun için önce evenlog'a bakıyoruz, herhangi bir program buraya disk ile ilgili hata olayı yazmış mı diye. Bu CheckHealth'a karşılık gelen bir işlem. Bütün WinSxS klasöründeki dosyaları taramak da çok zaman ve enerji alan bir işlem olduğu için kaydı düşülen bir sorun var mı, ona bakıyoruz. Bu işlemde bir düzeltme işlemi uygulanmıyor. Örnek kullanım:

DISM /Online /Cleanup-Image /CheckHealth

İkinci komut ScanHealth, daha çok diskte bir düzeltme işlemi yapmadan taramaya benziyor. Sistem açıkken diskte onarım yapmak istemiyorsak, sadece hata var mı yok mu bize onu söylesin diyorsak bu işlem uygulanabilir. Yine bu adımda da diskte bir düzeltme yapılmayacak. Örnek kullanım:

DISM /Online /Cleanup-Image /ScanHealth

Üçüncü komut RestoreHealth ise aktif olarak diskte hataları bul ve düzelt komutu gibi. Bütün WinSxS klasörü taranır, bulunan hatalar (ISO dosyasından veya internetten) bozulmamış kopyalar kullanılarak düzeltilir. Örnek kullanım:

DISM /Online /Cleanup-Image /RestoreHealth

Dism, bunun yanı sıra açık olan Windows kurulumu üzerinde de işlem yapabilir, DVD veya USB'den boot edilerek disklerden birindeki kurulum üzerinde de çalışabilir. /ONLINE anahtarı şu an çalışan sistem üzerinde işlem yapılmasını söylüyor.

Dism'in bunun dışında çok güzel kullanımları var. Örneğin WinSxS klasörümüzün boyutu çok büyüdüyse ve eski  sürümlere ait dosyaları silmek istersek (kesinlikle elle yapılmaması gereken bir işlem) aşağıdaki komut kullanılabilir.

Önce mevcut WinSxS (component store - Windows Side-by-side) boyutunu kontrol edelim:

C:\> dism /online /cleanup-image /analyzecomponentstore

Deployment Image Servicing and Management tool
Version: 10.0.22621.2792

Image Version: 10.0.22631.3880

[===========================99.6%========================= ]

Component Store (WinSxS) information:

Windows Explorer Reported Size of Component Store : 14.29 GB

Actual Size of Component Store : 13.35 GB

    Shared with Windows : 7.30 GB
    Backups and Disabled Features : 6.05 GB
    Cache and Temporary Data :  0 bytes

Date of Last Cleanup : 2024-07-15 12:24:43

Number of Reclaimable Packages : 3
Component Store Cleanup Recommended : Yes

The operation completed successfully.

Eski ve kullanılmayan (superseded) sürümleri silelim

Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase

Bu komut sonrasında da kurulmuş güncellemerin kaldırılması imkansız hale gelir. Görece daha "hafif" bir temizlik için /ResetBase olmadan kullanabiliriz.

Bir service pack ile eski duruma düşmüş dosyaları silmek için (service pack'in kaldırılmasını imkansız hale getirir)

Dism.exe /online /Cleanup-Image /SPSuperseded

dism'in kullanımına benzer olarak Powershell'in de Repair-WindowsImage cmdlet'i var, aşağıdaki gibi kullanımı mümkün:

Repair-WindowsImage -CheckHealth
Repair-WindowsImage -ScanHealth
Repair-WindowsImage -RestoreHealth

Bir sistemde kurulu olan güncellemeleri listelemek için

dism /online /Get-Packages /Format:Table

Şu an açık olan sistemde bunu elde etmenin başka yolları da var. Ama DVD veya USB'den açılmış sistem üzerinde aynısını yapabilmek için

dism /image:D:\ /Get-Packages /Format:Table

Burada /image:D:\ Windows'un bulunduğu sürücüyü göstermeli.

Karşılaşılan sorunlar ile ilgili şu videoya bakılabilir.

17.07.2024

Windows'da istenilen boyutta dosya oluşturmak

Amacım, Windows kullanarak diskte anlık olarak istenilen boyutta bir dosya oluşturmak. Bununla ilgili yöntemleri zaten, konunun bilir kişileri [1] adresinde özetlemiş. Ben de onları bir kez daha burada toparlamak istedim.

Yöntemlerden birisi fsutil kullanmak. 1 MB boyutunda file1.txt dosyasını, mevcut klasörde oluşturmak için, boyutu byte cinsinden vermek gerek:

fsutil file createnew file1.txt 1048576

Powershell (.Net kütüphanesi) kullanarak oluşturmak için yöntem şöyle:

[io.file]::Create("file2.txt").SetLength(1MB).Close

Sysinternals aracı contig'i kullanmak da bir seçenek:

contig64 -n testfile (1MB)

Bu da olmadıysa son yöntem olmasa da bu yazının son önerisi diskpart ile vdisk oluşturmak:

DISKPART
CREATE VDISK FILE="C:\file3.txt" MAXIMUM=1 TYPE=FIXED

Burada dikkat edilecek MAXIMUM parametresi ile verilen dosya boyutunun megabyte cinsinden veri olması gerek. Ayrıca FILE parametresi ile kısmi değil tam dosya yolu verilmeli. Bu yöntem, kullanımı en zor yöntem.

Gördüğüm kadarıyla bu yöntemlerin hepsi içine birşey yazmadan oluşturuyor. Her dosyaya bir veri kaydedilmemiş olsa da dosya boyutu ile diskte yer kapladığı alan bölümleri aynı, 1MB.


 Bir de sparse (seyrek, aralıklı) dosya denen bir kavram var. Önceki yöntemlerin hiçbirinin sparse dosya oluşturmadığı söylenmiş. Bir dosyanın sparse olup olmadığını anlamak için

fsutil sparse queryflag file1.txt

ve bir sparse dosya oluşturmak için

fsutil sparse setflag file2.txt
fsutil Sparse SetRange file2.txt 0 1048576

Bu şekilde oluştup fsutil sparse queryflag ile sorgulayınca dosya tipi sparse olarak görüntülendi.

C:\> fsutil sparse queryflag file2.txt
This file is set as sparse
[1] https://stackoverflow.com/questions/982659/quickly-create-large-file-on-a-windows-system

5.07.2024

Zamanlanmış görevler ile yeniden başlatma ayarlamak

Daha önce şu yazımda tek satırlık powershell komutları ile bir sunucuyu yeniden başlatma fikirleri paylaşmıştım.

Daha iyi bir fikrim var.

Yeniden başlatma zamanlamasını kendi bilgisayarımdan yapmak istiyorum. Tek tek yeniden başlatılacak bilgisayarlara uzak masaüstü veya uzak PSSsession bağlantıları ile değil. Aşağıdaki gibi schedule-restart.ps1 dosyasını oluşturuyorum.

param(    
    [string]$Computername,
    [string]$ScheduledTime="23:00"
)
Invoke-Command -Computername $Computername -ScriptBlock {
    $trig1 = New-JobTrigger -At $ScheduledTime -Once
    $obj1 = Register-ScheduledJob -Trigger $trig1 -Name "YenidenBaslatma" -ScriptBlock {Restart-Computer -Force}
    "Görev oluşturuldu: $($obj1.Name)"
    "Zaman : $($trig1.At)"
}

Bu betikle uzaktaki bir bilgisayar için yeniden başlatma görevi oluşturmak istediğimde şu şekilde bir kullanım yeterli:

.\schedule-restart.ps1 -ComputerName uzakpc

Varsayılan yeniden başlatma zamanı saat 23:00. Eğer değer vermezsek bu saatte, -ScheduledTime ile değer verirsek başka bir saatte yeniden başlatılacak. Zamanlama bir kez, bugün için geçerli olacak. Yani tekrarlama yok.

Peki bu isimde bir görev daha varsa ne olur? Bir önceki seferden oluşturduğum bir zamanlanmış görev varsa bir tane daha oluşturmayacaktır. İsmini farklı seçerek bir görev daha oluşturabilirim, ama bu durumda gereksiz görev kalabalığı olur. Aşağıda kırmızı ile vurguladığım bölüm, önce aynı isimle bir görev olup olmadığını kontrol ediyor, sonra bunu silmeyi öneriyor.

param(    
    [string]$Computername,
    [string]$ScheduledTime="23:00"
)
$bSilme = $false 
Invoke-Command -Computername $Computername -ScriptBlock {
$prev1 = Get-ScheduledJob -Name "YenidenBaslatma" -EA Silent
    if ($prev1) {
$resp1 = Read-Host "Aynı isimde bir görev daha var. Silinsin mi (N/y)?"
if ($resp1 -eq "Y" -or $resp1 -eq "y") {
try {
Unregister-ScheduledJob -InputObject $prev1
}
catch {
$_.ErrorDetails.Message
}
}
else {
"Silmemeyi sectigin icin yeni gorev olusturulmayacak"
$bSilme = $true
}
    }
else {

        $trig1 = New-JobTrigger -At $ScheduledTime -Once
        $job1 = Register-ScheduledJob -Trigger $trig1 -Name "YenidenBaslatma" -ScriptBlock {Restart-Computer -Force}
        "Görev oluşturuldu: $($job1.Name)"
        "Zaman : $($trig1.At)"
    }
}

Takıntılı olanlar, bu görevi daha karmaşık sonuçlar yaratmadan silmek isteyebilir. Bunun için de bir delete-restartjob.ps1 betiği oluşturdum.

param(    
    [string]$Computername
)
Invoke-Command -Computername $Computername -ScriptBlock {
    $job1 = Get-ScheduledJob -Name "YenidenBaslatma" -EA Silent
    if ($job1) {
        $trig1 = $job1 | Get-JobTrigger
        "Bulunan gorev: $($job1.Name)"
        "Zamanlamasi : $($trig1.At)"
        $resp1 = Read-Host "Bu gorev silinsin mi (N/y)?"
        if ($resp1 -eq "Y" -or $resp1 -eq "y") {
            $job1 | Unregister-Scheduled 
        }
        else {
            "Silinme iptal edildi." 
        }
    
    else {
        "Silinecek yeniden baslatma gorevi bulunamadi" 
    
İyileştirmenin sonu yok. Daha neler eklenebilir, neler...