11.01.2025

Hafta numaraları

Türkiye'de çok kullandığımız birşey olmasa da yılın içinde kaçıncı hafta olduğumuz bilgisi bazen faydalı olabiliyor. Powershell'de bu işi doğrudan Get-Date'i formatlayarak yapabiliriz:

Get-Date -UFormat %V

İlk haftanın hangisi olacağı ölçütü var. Bazı kültürlerde yılın ilk haftası olarak ilk tam hafta (FirstFullWeek), diğerlerinde yılın ilk gününün olduğu hafta (FirstDay) ötekilerde ise ilk 4 veya daha günlük hafta olarak kabul edilir [1].

Türkçe Windows'da bunu öğrenmenin yolu:

$kultur = Get-Culture
$kultur.DateTimeFormat.CalendarWeekRule

FirstDay

Yani yılın ilk gününün olduğu hafta bizde yılın ilk haftası kabul ediliyor. 1 Ocak Pazar bile olsa ertesi gün 2 Ocak bizim için yılın ikinci haftası. Değiştirmek mi istiyoruz? Olur [2, 3]:

$kulturBilgisi = [System.Globalization.CultureInfo]::InvariantCulture
$takvim = $kulturBilgisi.calendar
$takvimYilinIlkHaftasi = [System.Globalization.CalendarWeekRule]::FirstFourDayWeek
$haftaninIlkGunu = [System.DayOfWeek]::Sunday
$suAn = Get-Date
$haftaNo = $takvim.GetWeekOfYear($suAn, $takvimYilinIlkHaftasi, $haftaninIlkGunu)
"ISO 8601 standardına göre hafta numarası: $weekNumber"

Bu satırlar da yılın ilk haftasının en az 4 günü olan bir hafta olması ve haftanın ilk günün Pazar olması kuralına göre hesaplar.

Eski günlerden kalma güzel bir çalışma da Scripting Guy'a ait.

10.01.2025

Security Identifer (SID) ve kullanıcı adı ilişkilendirme

Bir kullanıcı hesabından SID'yi bulmak için yerel hesaplarda

Get-LocalUser -Name metin | Format-List Name, SID

ya da tam tersi yönde SID'den sorgualama yapmak için ise

Get-LocalUser -SID "S-1-5..." | Format-List Name, SID

Active Directory ortamında ise (dikkat, buradaki Identity aslında kullanıcı adı)

Get-ADUser -Identity "metin" | Format-List SamAccountName, SID

veya tam tersi yönde SID'den kullanıcı isim sorgu için

Get-ADUser -Identity "S-1-5-..." | Format-List SamAccountName, SID

30.12.2024

Powershell muhtelif-2

Bir dosya içindeki satır sayısını bulmak için aşağıdaki iki satırdan biri kullanılabilir.

(select-string "^" dosya.txt | measure-object).count
(gc dosya.txt | measure -line).lines

Hatta bu dosyanın içinde toplam kaç harf veya kelme olduğun bulmak için

select-string "^" dosya.txt | measure-object -word -character

Bir klasörün (alt klasörler hariç) boyutunu bulmak için (alt klasörleri dahil etmek için Get-ChildItem'a -Recurse eklemek gerek)

(get-childitem d:\klasor | measure-object -property length -sum).sum

Komut satırından yeni bir dosya oluşturma

ni yenidosya.txt

Klasörü içeriğiyle birlikte silme (-force gizli ve readonly dosyaları silmeden önce için onay istememesi için)

ri d:\klasor -recurse -force

Bir dosyanın boş olup olmadığını kontrol etme [1]

if ([String]::IsNullOrWhiteSpace((Get-Content D:\dosya.txt))) { "boş" } else { "boş değil" }

Bir klasördeki dosyaların içinde geçen her Nisan kelimesini Mayıs ile değiştirmek [2]

dir *.txt -recurse | % { (gc $_).replace("Nisan","Mayıs") | sc $_.fullname }

İçinde Ağustos geçen dosyaları bulmak

dir *.txt -recurse | sls "Ağustos" -list | select path

İki dizeden sadece 2.sinde geçen öğeleri listele [3]

$dize2 | ? { $dize1 -notcontains $_ }

Ya da iki dizede de olan öğeleri listele (iki kümenin kesişim kümesi)

$dize1 |? { $dize2 -contains $_ }

İki dizenin birleşim kümesini listele

$dize1 + $dize2 | select -unique

XML verisi üzerinde işlem yapmak [4]

foreach ($element in ([xml]$icerik=gc D:\veri.xml)) { $element.loc = "NBA" }

$icerik.Save("veri2.xml")

Metnin içinde HTML etiketlerini kaldır [5]

$my_string -replace '<[^>]+>',''

Dizenin en küçük, en büyük veya dizenin ortalama değerini bulmak için

($dize | measure -maximum).maximum
($dize | measure -minimum).minimum
($dize | measure -average).average

Dizedeki her bir öğenin kaç kez kullanıldığını bulmak (histogram?)

$dize | group | sort count -desc | select name,count

Her öğenin kaç kere tekrarlandığı bilgisi fazlaysa ve sadece mükerrer öğeleri görmek istiyorsak  [6]

$dize | group | ? count -gt 1 | select name

Bilgisayarın saat dilimini görmek için [7]

[System.TimeZoneInfo]::Local.StandardName

Zamanı UTC'ye çevirmek için

(Get-Date).ToUniversalTime()

Herhangi bir zaman dilimine çevirmek için (bu komut, fonksiyonun ilk parametresinin hangi zaman diliminde olduğunu bilerek çevirir)

[TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), 'Eastern Standard Time')

Tüm zaman dilimlerini listelemek için

[TimeZoneInfo]::GetSystemTimeZones()

İşletim sisteminin kurulma tarihi (ki bu da 24H2 gibi büyük güncelleştirmeler sonrasında sıfırlanıyor)

(gcim win32_operatingsystem).InstallDate

Bir klasördeki dosyaların içinde adminstrator kelimesinin kaç kere geçtiğini bulmak:

sls administrator * | group path | sort count -desc |ft count, values -Autosize

26.12.2024

Spotify klavye kısayolları

Ortalama bir müzik severden daha fazla zamanımı müzik dinleyerek geçiriyorum. Bu sebeple Spotify kısayolları önemli. Spotify'da klavye kısayollarına ulaşmanın da bir kısayolu var: Shift+? (Türkçe-Q klavye düzeninde doğrudan bir soru işareti olmadığı için bu genelde Ğ'nin üzerine gelen * tuşu olmalı) [1]. Yanlışlıkla Shift+? ararken Ctrl+?'e bastıysak yazılarınız küçülmüş olabilir. Bu durumda Ctrl ile birlikte klavyenizin sağ bölümündeki tuş takımının olduğu yerdeki '+' işaretine basarak büyütebilir, veya aynı yerdeki '-'ye basarak tekrar küçültebiliriz. Eski haline döndürmek için Ctrl+0 kullanılabilir. 'Son durumda en çok kullandığım kısayollar şöyle:

Çalan şarkıyı görüntüle     Alt + Shift + J
Çalma listesinde bul        Ctrl + F
Ev sayfasına git            Alt + Shift + F
Beğendiğim şarkılara git    Alt + Shift + S
Kütüphane                   Alt + Shift + 0
Çalma listelerimiz          Alt + Shift + 1
Sanatçılarımız              Alt + Shift + 3
Albümlerimiz                Alt + Shift + 4
Sizin için                  Alt + Shift + M
Çevrim dışı/içi geçişi      Ctrl + Alt + O (o harfi)

25.12.2024

Beyin Jimnastiği

Şu haberi izlerken kendime bir görev edindim. Bir beyin jimnastiği de ben yapmak istedim. Caesar şifreleme yöntemine göre alfabemizdeki her harfin "5 kez ileri" kaydırılması ile elde edilen aşağıdaki kriptolanmış cümlenin şifresini çözmeye çalışacağım.

CEZES NĞNS LIÜ ES LIÜ CIÜHI

Bu kriptolu cümle nasıl elde ediliyor; kriptolanmamış cümledeki her harf (boşluk ve noktalama karakterleri hariç; sadece harfler) için alfabedeki konumuna göre bir endeks çıkarılıyor. Alfabemizdeki harfler ve her harfin konumu aşağıdaki gibi (alttaki sayılarl sadece birler basamağı):

ABCÇDEFGĞHIİJKLMNOÖĞRSŞTUÜVYZ
0    5    1    5    2    5  8

Örnek olarak 0'dan başlayan endeksli dizimizde S harfini kriptolamak için altındaki 21 endeksine 5 daha ilave edip 26. konuma karşılık gelen U harfini yazacağız. Şifrelerken endeks bilgisinin 28'i geçmesi durumunda modül işlemini yapacağız. Yani Y harfini kriptolamak için 27'ye 5 ekleyince sonuç 32 olacak. Alfabemizde 32 harf olmadığı için

32 mod 29 = 3

bize sıfır endeksli harf dizimizdeki 3. (endekslemeyi 1'den başlatırsak 4.) harf olan Ç'yi verecek. Powershell'de mod operatörü '%' işareti.

32 % 29 = 3

Şifre çözerken de endeks bilgisinden 5 çıkaracağız. Bu durumda sayının sıfırdan küçük bir sayıya düşerse de üstüne 28 ilave edeceğiz.

Normal şartlar altında powershell ile çalışırken karakter setimizi ISO-8859-9'a çevirme gibi bir yöntem bilmiyorum. Bunun için yukarıdaki gibi Türkçe alfabeyi bir değişkene atıyorum.

$abece="ABCÇDEFGĞHIİJKLMNOÖĞRSŞTUÜVYZ"

Daha sonra verilen bir harfin alfabenin kaçıncı endeksine karşılık geldiğini ve bir endekse hangi harfin karşılık geldiğini dönecek iki fonksiyona ihtiyacım olacağını düşünerek aşağıdaki 2 fonksiyonu oluşturuyorum. Birincisi bu dizide verilen bir harfin kaçıncı endekse karşılık geldiğini söyleyecek bir fonksiyon.


function konum {
    param([char]$harf)
    for($i=0;$i -lt 29;$i++) {
        if ($harf -eq $abece[$i]) {
             $i
        }
    }
}

İkincisi ise verilen bir endekteki harfi dönecek bir fonksiyon:

function donustur {
    param([int]$konum)
    if ($konum -lt 0) {
        $konum=29+$konum
    }
    elseif ($konum -gt 28) {
        $konum = $konum % 29
    }
    $abece[$konum]
}

Bu aşamada

    konum 'E'

gibi bir işlem bana 5 dönecek. Benzer şekilde

    donustur 5

gibi bir işlem 'E' harfini dönecek. Endeksin sıfırdan küçük veya 28'den büyük olması durumlarını bu fonksiyon içinde kontrol ediyorum.

Bu iki fonksiyonumuz hazırken, hedef şifrelenmiş cümlemizi de $hedef gibi bir değişkene attığımızı düşünerek aşağıdaki gibi bir hesaplamayla şifresi çözülmüş metni bulmayı deneyelim.

$sifresiz=""
for ($it=0;$it -lt ($trg.Length);$it++) {
    $chr = [char]$trg[$it]
    $z_konum = konum $chr
    $z_donus = $z_konum-5
    $z_chrdonus = donustur $z_donus
   
    if ($chr -eq 32) {
        $sifresiz += " "
    }
    else {
        $sifresiz += $z_chrdonus
    }
}

Bu işlemin sonucunda $sifresiz değişkenimizin içeriği

VATAN İÇİN HER AN HER VERDE

olarak çıktı.

14.12.2024

Manjaro büyük güncelleştirmeleri

Manjaro bir rolling distro. Yani Ubuntu veya Fedora gibi yılda 2 kez yayınlanan büyük sürüm güncellemeleri ile bir sürümden diğerine geçiş yok. Onun yerine sürekli güncel tutulan bir güncelleştirme yapısı var. Pratikte son kullanıcıyı etkileyen pek birşey yok.

/var/log/pacman.log dosyasına bakarak sistemimdeki büyük güncelleştirmeler ne zaman olmuş diye bulabilmem gerektiğini düşünüyorum. Belli bir süre IT dünyasında çalışınca log dosyalarına bağımlılık oluşuyor.

Önce manjaro-keyring paketinin güncelleştirmelerine bakarak en son büyük sistem güncelleştirmesinin ne zaman olduğunu veya bu yıl kaç kere olduğunu bulmaya çalıştım. Çok net bir sonuç vermedi. Çünkü manjaro-keyring illa büyük bir güncelleştirme ile birlikte gelmiyor.

Daha sonra manjaro-release paketini bu büyük güncelletirmelerle ilişkilendirmeyi denedim. Aslında mantıklıydı ama tam olarak yine sanki doğru sonuç vermiyor gibiydi.

En son girişimim belli bir tarihte yapılan paket güncelleştirme sayısına bakarak bir sonuç çıkartmak. Yani pacman.log dosyasında aynı tarih bilgisinden kaç tane geçtiğini sayarak ne kadar fazla paketin güncelleştirildiğini bularak bir sonuca ulaşmaya çalışmak. Bunu da sistemi ilk kurduğum günden bu yana değil de sadece 2024 yılı güncelleştirmelerinin içinde aramak istedim. Kullandığım komut dizisi şöyle:

grep -E '^\[2024-' /var/log/pacman.log | awk '{print $1}' | tr -d '[]' | awk -F 'T' '{print $1}' | sort | uniq -c | awk '$1 >= 200'

Burada kısaca ilk bölüm sadece içinde [2024 geçen satırları süzüyor. Daha sonra boşluk karakteri ile satırdaki diğer bilgilerden ayrılan tarih saat bilgisini alıp bu bilgiden köşeli parantez ("[" ve "]") temizliyor. Manjaro'da bu tarih saat bilgisi 2024-12-13T16:15:23 gibi olduğu için ve burada sadece tarih bilgileriyle ilgilendiğim için "T" karakterini bir ayraç olarak kullanıp bu ayraç karakterinden önce gelen tarih alanı çıkarttım. Daha sonra her tarih bilgisinin kaç kere geçtiğini uniq -c komutuyla sayıp, bu sayının 200'den fazla olanlarını süzdüm. Fena olmadı sanki.

pacman.log dosyasında geçen her satır güncellenen bir pakete ait değil; başka bilgiler de bu kayıt dosyasına düşülüyor. Bir sebeple sadece güncellenen dosyaların sayısı ile ilgileniyorsak ilk awk komutundan önceki bölüme bir de grep 'upgraded' eklemek gerek:

grep -E '^\[2024-' /var/log/pacman.log | grep 'upgraded' | awk '{print $1}' | tr -d '[]' | awk -F 'T' '{print $1}' | sort | uniq -c | awk '$1 >= 200' 

Sanırım burada kalan soru: büyük bir güncellemede kaç paket değişir?

5.12.2024

Bazı ilginç olay günlüğü kayıtlarına erişmek

Uzak masaüstü olay kayıtlarını görmek için

Get-WinEvent -FilterHashtable @{Logname="Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational";Id=1149}

En son kapanma ve açılma olaylarını görmek için (son 4 tanesi için, 12 başlama, 13 kapanma)

Get-WinEvent -FilterHashtable @{Logname="System";ProviderName="Microsoft-windows-Kernel-General";Id=12,13} -Max 4

En son beklenmedik şekilde sonlanan uygulamaları görmek için

Get-WinEvent -FilterHashtable @{Logname="Application";Id=1000,1002;ProviderName="Application*"} -Max 5

En son yapılan ağ bağlantılarına dair olayları görüntülemek için

Get-WinEvent -FilterHashtable @{Logname="Microsoft-Windows-NetworkProfile/Operational";Id=10000} -max 5

En son çalışan görev zamanlayıcısı olay kayıtlarına erişmek için

Get-WinEvent -FilterHashtable @{Logname="Microsoft-Windows-TaskScheduler"} -Max 4

Güç durumundaki değişiklikleri (güç adapteörünü takmak veya çıkarmak) görmek için

Get-WinEvent -FilterhashTable @{Logname="System";Id=105} -Max 6 

Arka planda başlayan ve duran hizmet olaylarına ait kayıtları görmek için

Get-WinEvent -FilterHashtable @{Logname="System";ProviderName="Service Control Manager";StartTime=(Get-Date).AddHours(-1)}