Bir klasörün altındaki tüm alt klasörler ve dosyaların sahibini, üst klasörün sahibi ile değiştirmek istiyorum. Aşağıdaki gibi bir betik işe yaradı.
Burada anlatılanlar benim küçük/büyük sorunlarımı çözerken izlediğim adımlardır. İlerde bu bilgilere kendim her yerden erişeyim diye, veya benzer sorunları yaşayan başkaları da erişebilsin diye burada biriktiriyorum. Bu adımları uygulamak, hata yapmamak ve doğabilecek herhangi bir hasar sizin kendi sorumluluğunuzdadır. Yazar(lar) veya yazılardaki bağlantıların sahipleri hiçbir şekilde oluşabilecek hata/hasarlardan dolayı sorumlu tutulamazlar.
Bir klasörün altındaki tüm alt klasörler ve dosyaların sahibini, üst klasörün sahibi ile değiştirmek istiyorum. Aşağıdaki gibi bir betik işe yaradı.
Üzerinde zaten Windows 11 yüklü olan bir bilgisayara Debian kurdum. Üzerinde SATA SSD bir disk vardı. Kurulum tamamlandıktan sonra os-prober'ın devreye girip bir grub menüsü oluşturmasını, Debian ve Windows'un bu menüde yerlerinin olmasını bekledim. Ama olmadı. Windows görülmedi. Bunun önce Windows'un BitLocker'ı ile ilgili olduğunu düşündüm. Sonra şifrelenmemiş bir EFI bölümünün bu iş için yeterli olduğunu hatırladım. Acaba EFI bölümü kurulum sırasında biçimlendirilerek sadece Debian'ın mı dosyaları kalmıştı? Hayır, Windows'un ekledikleri de yerinde duruyordu. Bu durumda grub menüsünde elle bir müdahale gerekecek.
Debian açıkken önce EFI bölümünün UUID'sini öğrendim.
sudo blkid /dev/sda1
bu satırın sonucunda bana verilen UUID'yi kopyalayarak /etc/grub.d/40_custom dosyasını açarak içine şu satırları ekledim
menuentry "Windows Boot Manager" {
insmod part_gpt
insmod fat
search --no-floppy --fs-uuid --set=root 1234-ABCD
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}ardından
sudo update-grub
yaparka grub menüsünü güncelledim ve sorun çözüldü.
Grafik arayüz ile bulmanın yöntemleri var, görev yöneticisi, msinfo32 vs. Ama ben powershell ile bulmak istiyorum. İlk aklıma gelen win32_processor sınıfı. Bunun atlında L2 ve L3 miktarı var, ama L1 yok.
gcim win32_processor | select L1CacheSize, L2CacheSize, L3CacheSize
L1CacheSize L2CacheSize L3CacheSize
----------- ----------- -----------
5120 8192 Bakmam gereken sınıf Win32_CacheMemory. Bu cmdlet bir dizi dönüyor. Dizinin her bir elemanı bir önbellek (tampon) seviyesine ait. Şöyle bir ifade ile tüm bilgileri elde edebildim:
gcim win32_cachememory | ft DeviceID, CacheType, Level, InstalledSize, PurposeDeviceID CacheType Level InstalledSize Purpose
-------- --------- ----- ------------- -------
Cache Memory 0 4 3 192 L1 Cache
Cache Memory 1 3 3 128 L1 Cache
Cache Memory 2 5 4 5120 L2 Cache
Cache Memory 3 5 5 8192 L3 Cache Purpose alanında da görülebilir ama Level=3 olan satırlar L1, Level=4 olan L2 ve Level=5 olan L3 önbellek miktarı. L1 kendi içinde iki farklı bölümden oluşuyor. CacheType=3 ve CacheType=4 alanlarının toplamını bulmamız gerek, yani 192+128 = 320 ve bu sayıların tümü KB cinsinden.
1 KB'ın kaç byte'a karşılık geldiği konusu duruma göre değişiyor[1]. Burada görüyoruz ki
1 KB = 1024 B
---
İster sistem sürücüsü olsun, ister taşınabilir disk, NTFS dosya sistemine sahip her disk bölümü formatlandığı (ya da dosya sisteminin oluşturulduğu) tarihi bir yerde tutar. Bunları edinmenin birkaç yolu var.
Daha önce bu konuyu Process Monitor ile bulmanın yolunu öğrenmiştim. Ancak her seferinde procmon'u bulmak, süzgeçleri oluşturmak ve bu veriyi okumasını beklemek, özellikle uzak bir bilgisayar söz konusuysa hiç pratik değil. Bu durumda kullanılabilecek diğer bilgi kaynakları:
1. Birimin kök klasörünün oluşturulma tarihi
gi C: | fl
ya da uzun hali
(Get-Item -Path "C:").CreationTime
2. Master File Table öğesinin oluşturulma tarihine bakmak
gi 'C:\$MFT' -force | fl
Burada $MFT'nin önündeki dolar işareti Powershell'de özel karakter olduğu için çift tırnak yerine tek tırnak kullanmak gerek. Hedefimiz sistem ve gizli dosya olduğu için de -force kullandım.
3. NtQueryVolumeInformationFile() kullanmak. Bu daha zor bir işlem. Bunu yazacak C# ve Windows Internals bilgim yoktu, Claude'a yazdırdım :) Denedim, çalıştı. Çelişkili veriler olması durumunda en güvenilir verinin bu yöntem olduğunu düşünüyorum.
Bir bilgisayarda bu yükseltmenin hangi tarihte yapıldığını görmem gerekti. Ama olay günlüğü kayıtları o kadar eski değildi. Ama yeni farkettim ki C:\Windows\Panther klasöründe setupact.log ve setuperr.log dosyaları gibi bazı dosyalar, Windows 10'dan Windows 11'e yükseltme aşamasında oluşturuluyor. Bu dosyanın içeriğinde geçen tarih verileri veya dosyanın oluşturulma tarihi bize yükseltmenin tarihi ile ilgili bilgi verebilir.
Aynı klasörde bulunan C:\Windows\Panther\CompatData_*.xml veya C:\Windows\Panther\DiagTrack*.xml gibi dosyaların da oluşturulma tarihleri baz alınabilir.
Yükseltmenin hemen sonrasında bir Windows.old klasörü varsa bu klasör de bize yükseltmenin tarih ve saatini söyleyebilirdi ama bu kısa bir süre sonra temizlendiği için ulaşmak imkansız.
Bir yükseltme olduysa (25H2 gibi büyük güncelleştirmeler bu değeri değiştirebilir) Windows kayıt defterindeki InstallDate ve InstallTime değerleri de bize bir ipucu verebilir. Bu değerleri çözmek için aşağıdaki yöntemler kullanılabilir.
İlave birkaç tarih, component based servicing (CBS) dosyasını oluşturulma tarihi olabilir.
Bir veri de DISM.log dosyası olabilir.
Yükseltmenin üzerinden çok zaman geçtiyse, hatta 25H2 gibi güncelleştirmeler de yüklendiyse bu veriler tutarlı bir şekilde aynı sonucu vermeyebilir. Bu durumda sağ duyular kullanılarak, belki de en eski tarih geçerli kabul edilebilir. Bilgisayar zaten Windows 11 ile geldiyse bu yöntemler anlamını yitirir.
Kurulumunu da powershell ile tamamladığım IIS sunucuma, şu şekilde bir powershell oturumu ile uzaktan bağlıyım.
Enter-PSSession -Computername IISsunucu1
Sunucu bilgisayar üzerinde kurulu IIS sistelerini görmek için iki benzer cmdlet var:
Get-Website
ve
Get-IISSite
İkisi de benzer çıktı üretiyor, benzer işlevselliğe sahip. Birincisi WebAdministration modülünün bir parçası. İkincisi ise IISAdministration modülünün bir parçası. İkincisinin daha yeni bir modül olduğu söyleniyor. Ama yeni modülde tüm cmdlet'lerin karşılıkları yok.
Yüksek olasılıkla sunucunuzda birden fazla IIS sitesi olacak. Bu komutlar da size bir dizi (array) nesnesi dönecek. Bu dizinin Name, ID, Physical Path, Bindings gibi alanları olacak. Genellikle bu listelenen sitelerden biri ile ilgileniyor oluruz. İstediğimiz siteyi Name alanı ile süzebiliriz.
Get-IISSite -Name site1
Nesnenin derinlerinden site loglarının saklandığı konumu çekmek için
$s1.LogFile.Directory
kullanabilirim.
Bir siteyi durdurmak veya yeniden başlatmak için
Stop-IISSite -Name site1
Start-IISSite -Name site1
kullanılabilir. Mevcut durum zaten Get-IISSite cmdlet'inin state alanında görünüyor.
Sunucumda IP tabanlı kısıtlama/izin modülü kurulumu merak ettim.
Get-WindowsFeature Web-IP-Security
şöyle bir sonuç döndü:
Display Name Name Install State
------------ ---- -------------
[ ] IP and Domain Restrictions Web-IP-Security AvailableKurulu değilmiş. Kurmak için
Install-WindowsFeature Web-IP-Security
kullandım.
IIS'te IP kısıtlaması iki farklı şekilde olabilir; verilen IP adreslerine izin verip geri kalan her bağlantıyı engellemek veya tam tersi verilen IP adreslerini engellemek, geri kalan her bağlantıya izin vererek. Mevcut durumda sitemizin hangi yapıda olduğunu görelim:
(Get-WebConfigurationProperty `
-Filter "system.webServer/security/ipSecurity" `
-PSPath "IIS:\" `
-Location "site1" `
-Name allowUnlisted).Value
allowUnlisted, listede olmayanlara izin verilsin mi sorusunu yanıtlar. True dönüyorsa sitemiz listede olmayanlara izin veren, yani listedeki IP adreslerini engelleyen durumdadır. False dönüyorsa listedekilere izin verir, geri kalanı engeller. Şimdi listemizi görelim.
Get-WebConfiguration `
-Filter "system.webServer/security/ipSecurity/add" `
-PSPath "IIS:\" `
-Location "site1" | Select-Object ipAddress, subnetMask, allowed
Diyelim ki IIS'in ayarı belirtilen IP adreslerini engellemek, diğer herkese izin vermek yönünde. Bunu tam tersi olarak değiştirmek için
Set-WebConfigurationProperty `
-Filter "system.webServer/security/ipSecurity" `
-Name "allowUnlisted" `
-Value $false `
-PSPath "IIS:\" `
-Location "site1"
gibi bir ifade kullanmalıyım.
Engellenen bir IP adresi ekleme yolu
Add-WebConfigurationProperty `
-Filter "system.webServer/security/ipSecurity" `
-PSPath "IIS:\" `
-Location "site1" `
-Name "." `
-Value @{
ipAddress = "192.168.1.100"
allowed = $false
}
ya da izin verilen bir IP ekleme yolu
Add-WebConfigurationProperty `
-Filter "system.webServer/security/ipSecurity" `
-PSPath "IIS:\" `
-Location "site1" `
-Name "." `
-Value @{
ipAddress = "192.168.1.101"
allowed = $true
}
Powershell ile bir pencereye klavye vuruşları göndermek mümkün. Bunu bir animasyon ile yapmak istedim. 3 not defteri süreci oluşturup, her birinin içine birer cümle ekleyip, sonra da bunları kapatmak istiyorum.
Açılan bir not defteri penceresinin içine bir kelime yazmak için
kullanmam gerek. Ama bunu kullanmak için önce
eklemeliyim. Kapatırken de bir not defteri sürecini diğerinden ayırt etmek için pencerenin başlığına göre ayırt etmek için
gibi bir şey kullanmak istiyorum. Kapatırken Alt+F4 komutunun karşılığını
ile göndermek, bu sorunun cevabını "Hayır" ile cevaplamak için "n" kısayolunu da
ile göndermek istiyorum. Her not defteri penceresinin içeriği olacak kelimeleri de aşağıdaki gibi bir değişkene koydum.
Hepsini tek bir betiğe koyunca:
Kapatmak için pencere başlığına göre Alt+F4 göndermek istedim, ama Türkçe yerelleştirme dışında herhangi bir durumda AppActivate çalışmayacaktır. Bu durum için try - finally ile bütün not defteri süreçlerini sonlandırdım.