2026-10-22

SAPI.SPVoice ile Türkçe konuşan Windows

Powershell ile metni sese dönüştürebiliriz. Varsayılan olarak Tükrçe sesler seçilemiyor ama galiba bir çözümünü buldum.

Normalde şöyle yapılıyor. Önce bir SAPI.SPVoice nesnesi oluşturuluyor.

$SObj = New-Object -ComObject SAPI.SPVoice

Sonra "konuş" demek yeterli.

$SObj.Speak("Hello World")

Ama Türkçe yerelleştirmeli bir Windows 11 Professional'da bile Türkçe ses yok. Sesleri listelemek için

$SObj.GetVoices() | ForEach-Object { $_.GetDescription() }

komutu gerek. Ama benim bilgisayarımda burada sadece Zira (English) görünüyor. Buna rağmen

Ayarlar > Zaman ve dil > Dil ve bölge

altında "Dil" bölümünde Türkçe, metin okumak için listeleniyor. Ayrıca

Ayarlar > Erişilebilirlik > Ekran okuyucusu > Ekran okuyucusunun sesi > Ses seçin

bölümünde Tolga sesi de görünüyor ve seçili.

Biraz registry'yi inceleyince

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens

altında Tolga sesini buldum. Bunu kullanmak için

$ses_adi = "MSTTS_V110_trTR_Tolga"
$reg_yolu = "HKLM\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\$ses_adi"

reg copy $reg_yolu "HKLM\SOFTWARE\Microsoft\Speech\Voices\Tokens\$ses_adi" /s /f
reg copy $reg_yolu "HKLM\SOFTWARE\WOW6432Node\Microsoft\Speech\Voices\Tokens\$ses_adi" /s /f

kullanarak kullanılabilir Tolga token bilgisini ilgili yerlere kopyaladım. Bunun sonucunda

$SObj.GetVoices() | ForEach-Object { $_.GetDescription() }

kullanarak Tolga (Türkçe) sesini listeleyebildim. Ses seçimi yaparak bir konuşma yapan fonksiyon oluşturdum.

function Out-Speak {
    param(
    	[string]$text="Merhaba Dünyalı"
    )
    $SObj = New-Object -ComObject SAPI.SPVoice
    $SObj.voice = $SObj.GetVoices() | where {$_.GetDescription() -match "Tolga"}
    $SObj.Speak($text)
}

2026-10-21

Write-Progress

Powershell'de uzun süren görevlerin durumunu görüntülemeye yarayan bir "progress bar" gösterimi var. En basit haliyle işlerin ne durumda olduğunu göstermek için


...
Write-Progress -Activity "Aciliyor..."
...
Write-Progress -Activity "Isleniyor..."
...
Write-Progress -Activity "Kapaniyor..."
...

gibi bir kullanım mümkün. Sürecin neresinde olduğumuz konusunda genel bir fikir vermek için yeterli. Ama bu aşamada bir progress bar yok. Bunu yapabilmek için elimizdeki işin tümünün kaç birim olduğunu, şu bu işlerin ne kadarının işlendiğini bilmemiz gerek. Çok basit bir for döngüsü için


for ($i=0;$i -lt 10;$i++) {
	Write-Progress -Activity "Sayiyor..." -PercentComplete $($i*10)
    Start-Sleep 1
}

Çok hızlı saymasın diye, yavaşlatmak amacıyla Start-Sleep kullandım. Evet, bu bir ilerleme çubuğu verir, çünkü döngünün toplamda 10 kere tekrarlayacağı ve şu anda kaçıncı döngüde olduğumuz ($i) bilgisi elimizde var. Ama kafama birşey takıldı; ilerleme çubuğu ne zaman kayboluyor? -PercentComplete %100'e gelse bile kaybolmuyor. Ancak komut sonlandığında kayboluyor. Yani terminalde sadece

Write-Progress -Activity "Calisiyor..."

Yazıp enter'a basınca ilerleme çubuğu o kadar kısa bir sürede gösterilip kayboluyor ki göremiyorum bile. Peki, bir tuşa basılmasını bekleyen Read-Host ile kullansam?


Write-Progress -Activity "Calisiyor...";Read-Host

Faydasız, yine görünmedi. Peki Read-Host yerine Start-Sleep kullansam?


Write-Progress -Activity "Calisiyor...";Start-Sleep 1

Evet, şimdi 1 saniye boyunca bir ilerleme çubuğu görüntülendi. Buradan çıkan sonuç; -PercentComplete parametresi %100'e gelse bile görüntülenme devam ediyor, ancak console host kontrolü devralıncaya kadar. Klavye'den bir giriş yapılması gereken durumlarda progress bar kapanıyor. Ama bu kadar ile bitmiyor, Write-Progress'in bir de -Completed parametresi var. Bu sadece bu parametre progress bar'ı ekrandan kaldırabiliyor. Örnek:


Write-Progress -Activity "Calisiyor...";Start-Sleep 1;Write-Progress -Activity "Bitti" -Completed;Start-Sleep 2

Bunu çalıştırıp Enter'a basınca 1 saniye boyunca ekranda "Calisiyor..." yazıyor, sonrasında -Completed parametresi olan bir Write-Progress kullanımı olduğu için progress bar kayboluyor, 2 saniye de ekranda hiç progress bar gösterimi olmadan bekliyorum.

Write-Progress'in bundan biraz daha fazla ayrıntıya sahip parametreleri var. Örneğin -Activity parametresine ek bilgi sağlamak için -Status parametresi kullanılabilir. Bu parametre ile sağlanan bilgi, -Activity ile sağlanan bilginin altında görüntülenir.


Write-Progress -Activity "Calisiyor..." -Status "Dosya acildi"

gibi.

Aynı anda birden fazla progress bar gösterilmesi gereken durumlarda -Id paramteresi ile hangi progress bar'ın güncelleneceğini seçebiliriz.


for ($i=0; $i -lt 5; $i++) {
   Write-Progress -Id 1 -Activity "i degiskeni artiyor" -Status "i=$i" -PercentComplete $($i*10)
   for ($j=0; $j -lt 5; $j++) {
      Write-Progress -Id 2 -Activity "j degiskeni artiyor" -Status "j=$j" -PercentComplete $($j*10)
      Start-Sleep -Milliseconds 100
   }
}

Ama burada iki progress bar da aynı seviyede yer aldı. Birisinin (i) diğerinin (j) üstü olduğunu göstermek için -Parent parametresi var. Bunun yaptığı tek şey, aslında j döngüsüne ait olan Write-Progress'i soldan girintili bir şekilde göstermek. j'nin ilerlemesini gösteren progress bar'a ait Write-Progress'in -Parent parametresine, üstü olan i döngüsünün Write-Progress'inin Id'sini vermek gerek. Aşağıdaki gibi.


for ($i=0; $i -lt 5; $i++) {
   Write-Progress -Id 1 -Activity "i degiskeni artiyor" -Status "i=$i" -PercentComplete $($i*10)
   for ($j=0; $j -lt 5; $j++) {
      Write-Progress -Id 2 -Parent 1 -Activity "j degiskeni artiyor" -Status "j=$j" -PercentComplete $($j*10)
      Start-Sleep -Milliseconds 100
   }
}

2026-10-20

VS Code ve powershell remoting

Uzak bir bilgisayara

Enter-PSSession -Computername sunucu01

ile bağlanıp çalışıyorum. Bazen uzaktaki bilgisayarda bir metin dosyasını düzenlemek istiyorum. Yeni çıkan edit aracı çok güzel, ama powershell remoting ile çalıştıramadım. Üstelik de sunucularda yok.

Bu işe bir çözüm ararken farkettim [1, 2] ki uzak bilgisayardaki bir dosyayı yerel bilgisayarda kurulu VS Code ile düzenleyebiliyorum.

Tek yapmam gereken VS Code'un kendi terminalinden uzaktaki bilgisayara bağlanıp

psedit dosya.ps1

komutunu vermek. Uzaktaki dosya çalıştığım bilgisayarda geçici bir klasöre aktarılıp VS Code ile açılıyor. Kaydettiğimde de tekrar uzaktaki bilgisayara aktarılıyor.

Burada VS Code'un powershell terminali konusu biraz kritik. VS Code'un powershell eklentisi yüklü olmalı. Bazen VS Code penceresinin içinde birden fazla powershell terminali açılmış olabiliyor. Bu durumda hangisinin eklentiye ait olan terminal olduğunu görebilmek için

$host.name

komutunun çıktısının

Visual Studio Code Host

olması gerek.

2026-10-19

flatpak uygulamalarını terminalden çalıştırma

Windows'da bir dosyayı VS Code ile açmak için

code dosya.txt

demek yeterli. Fedora'da VS Code'un açık kaynaklı sürümünü, flatpak ile kurdum; code-oss. Ama terminalden ne code ne de code-oss kullanarka doğrudan ulaşamıyorum. Flatpak ile kurulan uygulamarlın çalışması için

flatpak run com.visualstudio.code-oss

yapmak gerekiyor.

Daha kısa bir yol olarak bir alias oluşturabilirim. Bash için .bashrc dosyasına, zsh için .zshrc dosyasına öyle bir satır gerekli:

alias code='flatpak run com.visualstudio.code-oss'

Bunun sonucunda her yerden

code dosya.txt

yazmak yeterli.

Başka bir seçenek de flatpak export klasöründeki dosyaya kısayol oluşurmak. Flatpak kurulumu export konumu

~/.local/share/flatpak/exports/bin/

veya

/var/lib/flatpak/exports/bin

olabilir. Henüz yoksa ~/.local/bin klasörü oluşturup içine şu şekilde bir kısayol oluşurabilirim.

ln -s /var/lib/flatpak/exports/bin/com.visualstudio.code-oss ~/.local/bin/codeoss

2026-10-17

Siber savaşlar

El Cezire (Al Jazeera) youtube kanalı, yayınladığı bir videoda topluca siber saldırıya maruz kaldıklarını açıkladı. İlginç olan şu ki kimse ne bir zararlı yazılım yüklemişti ne de gönderilen mesajların içindeki kötü niyetli bir bağlantıya tıklamıştı. Tek yaptıkları masum haber sitelerinde gezinmekti.

El Cezire'den Muhammet Hasan'ın anlattıklarına göre telefonlara ve bilgisayarlara kurulan zararlı yazılım bir İsrail firması olan Candiru tarafından geliştirilmiş. Kelimenin tam anlamıyla kurulduğu cihazı tam olarak ele geçiren ve tespit edilmesi çok zor olan bu zararlı yazılımın sisteme bulaşması için zararlı içeriği gizleyen bir reklamın olduğu sayfada dolaşmak yeterli. Daha önce olduğu gibi hedef kitlenin dışında başka sistemlere de kurulmuş olması olasılıklar dahilinde. Ama açıklamayı yapan Muhammet Hasan'a göre hedef kitlenin seçimi daha "cerrahi bir müdahale ile" yapılmış. Bu noktada işe başka bir İsrail firması devreye giriyor: DiscoverTech. El Cezire çalışanlarının IP adresleri tespit edilmiş ve zararlı yazılım bu şekilde "noktasal" olarak kurulmuş.

El Cezire teknoloji takımı güzel bir iş çıkarıp gelen şikayetleri dikkate almış ve Kanada merkezli güvenlik şirketi Citizen Lab ile çalışarak bu işi ortaya çıkarmışlar. Zaten tetikte oldukları ve çok dikkatli davrandıkları söyleniyor. Ama buna rağmen basit bir "gezinme" bile buna sebep olmuş.

Stuxnet ve Pegasus gibi gelişmeler zaten kan dondurucuydu. Buna rağmen bu gelişme beni yine de şaşırttı.

---

https://threatlandscape.io/blog/citizen-lab-adfection-discover-tech-targeted-ads-zero-click-spyware
https://www.theguardian.com/technology/2026/oct/15/israeli-firm-digital-ads-enabling-installation-of-zero-click-spyware-researchers-say
https://www.reuters.com/legal/litigation/israeli-firm-used-online-ads-run-vast-spy-operation-researchers-say-2026-10-15/
https://citizenlab.ca/research/how-discover-tech-turned-targeted-ads-into-a-pipeline-for-spyware/
https://www.instagram.com/p/DemIB5cDgpA/

2026-10-15

Test-Connection -AsJob

Powershell'in ping eşdeğeri Test-Connection ile bir hedefe olan bağlantımı deniyorum.

Test-Connection -Computername 192.168.1.72 -Count 100

Bu şekilde, varsayılan gecikme/bekleme süresi olarak 1 saniye arayla 100 ICMP paketi gönderecek. Yani komutun tamamlanması ~ 100 sn sürecek. Bu cepte.

Bir de bunu arka planda çalıştırmak için kullanılan -AsJob parameteresi var. Bunu kullanarak bu işlemi arka planda gerçekleştirmek istedim.

Test-Connection -Computername 192.168.1.72 -Count 100 -AsJob

Ekrana arka planda çalışacak görevin kimliğini ve adını yazdı.

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
5      Job5            WmiJob          Running       True            .                    Test-Connection

Daha birkaç saniye geçtikten sonra Get-Job ile duruma baktım ve görev tamamlanmış:

Get-Job -Id 5
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
5      Job5            WmiJob          Completed     True            .                    Test-Connection

Emin olamadım, 100 tane ICMP paketi gerçekten gönderilmiş midir?

Wireshark'ı açıp ICMP filtresi ile tekrar başlattım ve evet, 100 ICMP echo request, 100 tane de echo reply ile 200 paket yakaladı. İlk paketin gönderilmesinden son paketin alınmasına kadar geçen süre de 1 saniyeden çok daha kısaydı. Bu gerçeği belgeleyen bir kaynak bulamadım ama konu çevrim içi ortamlarda konuşulmuş (1, 2).

Ne kadar sürdüğünü bulmak için Measure-Command kullanılabilir.


Measure-Command { Test-Connection -ComputerName bosbdc10 -Count 10 -Delay 1 -AsJob | wait-Job } | select -ExpandProperty totalmilliseconds 

2026-10-14

System Partition vs Boot Partition

Windows'da işletim sisteminin (yani \Windows klasörünün) yüklü olduğu disk bölümü Boot Partition (önyükleme bölümü) olarak adlandırılır.

EFI verilerinin tutulduğu disk bölümü ise System partition (sistem bölümü) olarak adlandırılır.

Sistemdeki disk bölümlerini ayrıntılı görebilmek için


gcim win32_volume | ? FileSystem | ft Label, DriveLetter, BootVolume, FileSystem, SystemVolume

Bu komutun BootVolume sütununda True olan önyükleme bölümü, SystemVolume sütununda True olan da sistem bölümüdür.