8.06.2023

pacman.log

Uzun bir süredir Manjaro kurulu olan bir bilgisayarım var. Diskini değiştirdim, diskte yer azaldı, temizlik yaptım, ama pacman.log dosyasını hiç temizlemedim. 4 seneden fazla bir zamandır kullanıyormuşum:

$ head -5 /var/log/pacman.log

İlk satırdaki tarih ilk güncelleme yaptığım tarih.

5 farklı sürüm LTS çekirdek kurmuşum:

$ grep -E 'installed linux[[:digit:]]{2,3}[[:blank:]]' /var/log/pacman.log | wc -l

5

Bütün çekirdek güncellemeleri bu kadar değil. Güncellemeler 248 kez olmuş:

$ grep -E 'upgraded linux[[:digit:]]{2,3}[[:blank:]]' /var/log/pacman.log | wc -l

248

80 kez pacman ile kurulum yapmışım:

$ grep "Running 'pacman -S " /var/log/pacman.log | grep -v "pacman -S -" | wc -l

80

Kaç kez "büyük" sistem güncellemesi yaptığımı bulamadım. Ama sanıyorum her güncelleme öncesinde manjaro-keyring yükseltiliyor. Buradan belki şu komut ile bir yerlere varsabilir miyiz

$ grep "upgraded manjaro-keyring" /var/log/pacman.log

Ayrıca pacman.log'larından şunları da öğrendim. Eğer pacman -Syu yapıyorsam loglarda

[PACMAN] Running 'pacman -Syu'

satırı geçiyor. Eğer pamac update yapıyorsam loglarda

[PAMAC] synchronizing package lists

geçiyor. Eğer grafik arayüzden octopi kullanıyorsam da loglarda

[PACMAN] Running '/usr/bin/pacman -S --noconfirm

geçiyor. Bunların sonucunda pacman.log dosyam 3,5 MB civarında.

2.06.2023

Uzaktan winget kurulumu

Etki alanındaki makinelerde bile winget varsayılan olarak kurulu gelmiyor, şu an için. Kurmak için şu adresten kurulum paketini indirmek gerek.Uzaktan kurulum yapacağım için Microsoft Store'dan indirmek bir seçenek değil.

Kurulum paketimizin adı Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle gibi birşey olacak. Bunu hedef makinemizin D:\ sürücüsünün köküne koyduğumuzu varsayalım. Daha sonra bir uzak powershell bağlantısı gerçekleştirmemiz lazım.

PS> etsn uzakpc

Bu aşamadan sonra varsayılan olarak uzaktaki PC'nin C:\Users\<kullaniciadi>\Documents gibi bir konumunda oturumumuz başlayacak. Önce

[uzakpc] C:\Users\metin\Documents\> cd D:

gibi bir komutla kurulum dosyamızın olduğu konuma geçiş yaptım. Daha sonra da Add-AppxPackage ile kurulumu başlattım.

[uzakpc] D:\Add-AppxPackage -Path .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

Bu komut hiçbir mesaj göstermeden tamamlandı. Sonrasında

[uzakpc] D:\> winget list

ile algılanan paketleri sorgulamak istediğimde önce anlaşılmaz birkaç bozuk satırdan sonra şöyle bir  hata verdi:

The `msstore` source requires that you view the following agreements before using.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. "US").

Do you agree to all the source agreements terms?
[Y] Yes  [N] No: An unexpected error occurred while executing the command:
0x8a150042 : Error reading input in prompt

Ama Y veya N'ye basmama izin vermeden çıktı. Uzaktan bu prompt sorununu nasıl halledebilirim diye winget'in parametrelerine bakarken

 --disable-interactivity   Disable interactive prompts

parametresini farkettim. winget'i bu parametre ile çalıştırmayı denediğimde de asıl sorun ortaya çıktı:

[uzakpc] D:\winget list --disable-interactivity

The `msstore` source requires that you view the following agreements before using.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. "US").

One or more of the source agreements were not agreed to. Operation cancelled. Please accept the source agreements or remove the corresponding sources.
 

Bu konu ile yaptığım aramada da şu sayfada winget'in yardımında (/? ile ulaşılan) listelenmeyen iki parametersini buldum:

--accept-package-agreements

--accept-source-agreements

Benim durumumda bu sanki "source agreements" ile ilgili görünüyordu. Bu sebeple ikinci paremetre ile şansımı denedim:

[uzakpc] D:\> winget list --accept-source-agreements

ve sonuca ulaştım.

30.05.2023

Scheduled Tasks vs Scheduled Jobs

Bir süredir gördüğüm ama farklarını bilmediğim iki farklı tip cmdlet seti arasındaki farkları, okuduğum eski ama çok güzel bir yazı aracılığıyla öğrendim; Powershell camiasına uzun yıllar "Microsoft Scripting Guy" lakabıyla değerli katkılarda bulunmuş Ed Wilson'ın yazılarından biri ile.

Powershell'de zamanlanmış görevler oluşturmak istersek karşımızda ScheduledTasks ve ScheduledJobs adında iki farklı kavram oluyor. Task ve Job kelimeleri Türkçe'de "görev"e karşılık geliyor. Bu sebeple anlatırken İngilizceleri üzerinden anlatacağım.

Windows ile birlikte gelen Görev Zamanlayıcısı arayüzü, Task olarak gruplanan görevlerin zamanlanması için bir araç. Geniş bir kullanım yelpazesi var. ps1 uzantılı powershell dosyaları da çalıştırılabilir, exe uzantılı çalıştırılabilir programlar da çalıştırılabilir.

Jobs ise Powershell'e özgü bir kavram. Terminal kavramında arkaplan görevleri vardır. Çalışması uzun zaman alacak komutları arka planda çalıştırmak isteyebiliriz. Bu zaman diliminde diğer komutun işlemini bitirmesini beklemeden başka işlemler de yapabiliriz. Bu sırada arkaplanda çalışan Job'ları takip edilebilir, bittiğinde sonuçları ve çıktılarını gözlemleyebiliriz. Hatta bazı cmdlet'lerin -AsJob parametersi vardır; çalışmayı arkaplanda yürütmek için. Scheduled Jobs ise bu tip arkaplan görevlerinin bir uzantısı gibi.

PS> $j = Invoke-Command -ComputerName localhost, Server01, Server02 -Command {Get-Date} -AsJob

Bu komutla sunucular üzerinde Get-Date komutunu yürütme işlemi arkaplanda yürütülür. Daha sonra

PS> $j

Id Name   PSJobTypeName State      HasMoreData   Location
-- ----   ------------- -----      -----------   --------
3  Job3   RemotingJob   Failed     False         localhost,Server...

komutu ile görevin durumu görüntülenebilir. Hatta 3 farklı sunucu bize çıktı ürettiği için bu arkaplan görevinin ayrıntıları için

PS> Get-Job -IncludeChildJobs

Id  Name   PSJobTypeName State      HasMoreData   Location    Command
--  ----   ------------- -----      -----------   --------    -------
3   Job3   RemotingJob   Failed     False         localhost,Server...
4   Job4                 Completed  True          localhost   Get-Date
5   Job5                 Failed     False         Server01    Get-Date
6   Job6                 Completed  True          Server02    Get-Date

yazılarak alt görevler listelenebilir. Daha sonra her birinin çıktılarını görmek için

PS> Receive-Job -Name Job6 -Keep | Format-Table ComputerName,
>> DateTime -AutoSize
ComputerName DateTime
------------ --------
Server02     Thursday, March 13, 2008 4:16:03 PM

yazılabilir. ScheduledJobs aslında, bu arkaplan görevlerinin otomasyonu için ScheduledTask atlyapısı ile birlikte Poweshell için oluşturulmuş bir modül. Jobs ile ilgili modülün adı PSScheduledJob. Bu modülün içindeki cmdlet'lere bakmak için

PS> gcm -m PSScheduledJob

yazabiliriz. Oluşturulan Scheduled Jobs nesnelerine dosya sistemi üzerinden C:\Users\<kullaniciadi>\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs klasöründen erişebiliriz.

Zamanlanmış görevleri Powershell'den yönetmek için geliştirilen modül ise ScheduledTasks. Bu modül ile birlikte gelen cmdlet'lere de bakalım:

PS> gcm -m ScheduledTasks

Jobs sadece Poweshell komutları veya ps1 uzantılı dosyaları çalıştırmak üzere tasarlanmış. Tasks için böyle bir kısıtlama söz konusu değil. taskschd.msc ile eriştiğimizi MMC snap-in'i ile hem Task'ları hem de Job'ları yönetebiliriz. Ama bu snap in ile sadece Task oluşturabiliriz. Powershell ile oluşturulmuş Job'lara ise taskschd.msc içinden Görev Zamanlayıcı Kitaplığı>Microsoft>Windows>Powershell yolundan ulaşabiliriz.

Bir örnek olması açısından Powershell yardım kitaplığını güncelleyecek bir Job yaratalım. Bunu her oturum açtığımızda, 30 dakikalık rastgele gecikme sonrasında çalışacak şekilde ayarlayalım. İlk iş önce bir zamanlayıcı (trigger) yaratmak:

PS> $t = New-JobTrigger -AtLogon -RandomDelay 00:30:00

Sonra da zamanlayıcı kullanarak yeni bir Job kaydedelim.

PS> Register-ScheduledJob -Name "YardimGuncelle" -Trigger $t -ScriptBlock {Update-Help -Force}

Bu Job'ın dosya sisteminde ve tasksch.msc'deki görünümleri aşağıdaki gibi oldu.

 


 Benzer bir şekilde bir de Task oluşturalım. Yine zamanlayıcıdan başlayalım.

PS> $t1 = New-ScheduledTaskTrigger -AtLogon -RandomDelay 00:30:00

Task'lar sadece powershell komut veya betikleri olmadıkları için eylem nesnesi oluşturmalıyız.

PS> $a1 = New-ScheduledTaskAction -Execute powershell.exe -Argument "-ExecutionPolicy RemoteSigned -Command 'Update-Help -Force'"

Nihayet bu iki nesneyi de birleştirip bir Task olarak kaydedelim.

PS> Register-ScheduledTask -TaskName "YardimGuncelle2" -Trigger $t1 -Action $a1

Mevcut Job'ları veya Task'ları sorgulamak için ise sırasıyla

PS> Get-ScheduledJob

ve

PS> Get-ScheduledTask

cmdlet'leri kullanılabilir.

İki modül arasında işlevsellik farkları var. Örneğin Job'lar için kaçırılan görevlerin tekrar çalıştırılması gibi bir seçenek yok, Task'lar için var. Bunu sağlayan da New-ScheduledTaskSettingsSet cmdlet'inin -StartWhenAvailable parametresi.

24.05.2023

Windows 10 ve üstü sistemlerde açık kalma süresi (uptime) belirleme

Bir süredir hayatımızda hızlı başlatma var.

Varsayılan olarak açık geliyor, sürekli eklenen yeni bileşenlerin Windows'un açılışını daha da yavaşlatmaması için bulunan bir çözüm. Ama bunun sonucunda da bir bilgisayara eski yöntemlerle ne kadardır açık diye baktığımızda beklenmedik uzun süreler görebiliyoruz. Bilgisayar aslında kapat komutuyla eskiden olduğu gibi kapanmıyor, uyku moduna alınıyor.

Buraya kadar giriş kısmıydı. Gelişmeye geçelim. Bir bilgisayarın ne kadar süredir açık olduğunu sorgulamak için genelde WMI (veya CIM) sorgusu ile Win32_OperatingSystem sınıfından LastBootUpTime değeri okunur. Örneğin:

PS> Get-CimInstance -ClassName Win32_OperatingSystem | Select LastBootUpTime

gibi. Bu, en son açılış zamanını verirdi, eskiden. Bunu şu andaki saat-tarih bilgisinden çıkararak ne kadar süredir açık olduğu bilgisine ulaşırdık.

Her ne kadar bilgisayarın gerçek "açık kalma süresi" bu olsa da yine de kullanıcının başlat menüsünden kapatma ve sonrasında güç düğmesine basarak bilgisayarı açma alışkanlığına göre açılış ve kapanış geçmişi öğrenmek istersek şu yazımda belirttiğim sistem olaylarından Kernel-General, 1 olayını dikkate alabiliriz. Ancak bu olay açılış haricinde de oluşabiliyor. Bunu ayırt etmek için de Reason=2 koşuluna dikkat etmek gerek.


Yani:

PS> Get-WinEvent -ComputerName uzakpc -FilterHashtable @{Logname="System";Id=1;ProviderName="*Kernel-General"} | where {$_.properties[3].Value -eq 2} | Select-Object -First 1

gibi bir sorgu ile bu olayı tespit edip buradan TimeCreated alanı ile en son açılış anını belirliyorum. Ayrıntılar sekmesinde görüntülenen verilerden Reason, properties[3]'e den gekliyor (sıfır endeksli). Hızlı başlatma durumunda işletim sisteminin kapanmasına karşılık gelen olay da Kernel-Power 107 olayı. Bu iki olay olay kayıtlarında arka arkaya geliyor.

Bu arada herhangi bir makinede hızlı açılış/başlatma (fast boot) etkin mi değil mi diye bakmak için

PS> (gp "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power")."HiberbootEnabled"

Bu komut 1 dönüyorsa hızlı başlatma etkindir, 0 dönüyorsa değildir.

22.05.2023

Outlook adres defteri indirme hatası

Yeni oluşturulan hesaplar Outlook adres defterinde görüntülenmiyorsa Gönder/Al sekmesinden Gönder/Al Gruplarından "Adres defterini indir.." seçilir. Ama burada da aşağıdaki gibi bir 0x8004010f hatası alıyorsak Exchange sunucu tarafında bazı kontroller yapmak gerekir.

Yüksek olasılıkla Exchange sunucuda bir varsayılan adres defterimiz vardır. GlobalWebDistributionEnabled ve WebDistributionEnabled özelliklerini kontrol edelim:

PS> Get-OfflineAddressBook | fl Name,GlobalWebDistributionEnabled,WebDistributionEnable

Benim sunucumda bu

Name                         : Default Offline Address Book (Ex2013)
GlobalWebDistributionEnabled : False
WebDistributionEnable        : True

olarak döndü. Bu durumda burada ve şurada söylendiği gibi bu dağıtılabilirlik özelliklerini etkinleştirmek gerek:

PS> Get-OfflineAddressBook | Set-OfflineAddressBook GlobalWebDistributionEnabled $true

Benim durumumda sadece GlobalWebDistributionEnabled devredışı olduğu için onu etkinleştirdim.

21.05.2023

Poweshell ile download edilecek içeriğin boyutunu indirmeden önce öğrenmek

Varsayalım ki uzak web sunucu üzerinde bir içeriğimiz var:

https://live.sysinternals.com/files/SysinternalsSuite.zip

İndirmeden önce boyutunu öğrenmek isityoruz.

Şu yöntem kullanılabilir:

(iwr -uri "https://live.sysinternals.com/files/SysinternalsSuite.zip" -Method Head).Headers.'Content-Length'

18.05.2023

Çalışan bir süreç hizmete mi ait?

Get-Process ile çalışan süreçleri listeleyebiliy, süreç bazında ayrıntılara erişebiliyoruz. Peki bu süreçlerden herhangi biri halen çalışmakta olan bir hizmete mi ait? Get-Process'in döndüğü verilerin içinde bu ilişkiyi görebileceğimiz bir alan yok. Ama eski adı WMI (Windows Management Instrumentation)  veya yeni adı CIM (Common Information Model) olan yöntemle mümkün. Örneğin Get-CIMInstance ile Get-Service'ten daha fazla veriye erişmek mümkün:

Get-CIMInstance Win32_Service

Çalışan her hizmete ait sürecin adı ve süreç kimliği (process ID) gibi veriler görülebilir. Örneğin uzaktaki sunucuda gördüğüm lsass süreci, 820 kimliği ile çalışıyor. Peki bu süreç herhangi bir hizmetle ilişkili midir?

Elimde hem süreç adı hem de süreç kimliği varken iki farklı sorgu yapabilirim:

Get-CIMInstance Win32_Service | Where-Object ProcessId -eq 820

ya da aliasları kullanarak (biraz da format-table ile çıkışı düzenleyerek)

gcim Win32_Service | where Name -eq "lsass" | ft DisplayName, Name, ProcessId, State, Status, ExitCode -AutoSize

DisplayName                      Name     ProcessId State   Status ExitCode
-----------                      ----     --------- -----   ------ --------
Kerberos Key Distribution Center Kdc            820 Running OK            0
CNG Key Isolation                KeyIso         820 Running OK            0
Netlogon                         Netlogon       820 Running OK            0
Active Directory Domain Services NTDS           820 Running OK            0
Security Accounts Manager        SamSs          820 Running OK            0

Sonuçta bu sürece bağlı birden fazla hizmetimizin olduğunu gördük.