20.03.2024

Powershell ile anlık olarak en fazla işlemci kullanan süreci bulmak

Her konuda olduğu gibi bilişimde de kavram karmaşaları oluyor. Bellekte olduğu gibi işlemci kullanımında da bir kavram karışıklığı var. En çok işlemci kullanan süreci belirlememiz gerekseydi anlık olarak mı bir ölçüm yapardık yoksa bilgisayarın açıldığı tarihten itibaren mi?

Poweshell'in Get-Process cmdlet'i bize sadece toplam işlemci kullanım süresini veriyor. Anlık olarak en çok işlemci kullanan süreci bulmak istersek Get-Process işimizi görmez.

Get-Process * | 
    Sort-Object -Property CPU -Descending | 
        Select-Object -First 10

Bu amaçla yaptığım kısa bir araştırmada Windows'un sayaçlarının (counter) kullanılabileceğini gördüm. Performans İzleyicisi (Performance Monitor) ile görüntülenen verilerin kaynağı olan sayaçlar, powershell ile Get-Counter cmdlet'i ile okunabiliyor. Yüzlerce sayaca sahip Windows'da hangi sayacı kullanacağımızı seçmek için şöyle bir arama yapabiliriz:

Get-Counter -ListSet *Process*

Ya da doğrudan performans izleyiciyi açarak buradan istediğimiz sayacı seçebiliriz. Dikkat edilmesi gereken bir konu, Türkçe Windows sürümlerinde sayaç isimlerinin de Türkçe olması. Script'i bir makinede geliştirip sunucuda çalıştırınca hatalar üretebilir. Ben tüm komutları İngilizce sayaç isimleri ile kullanacağım.

Benim bu amaçla kullanacağım sayaç "\İşlemci(*)\% İşlemci Zamanı" (ya da İngilizce işletim sistemlerinde "\Process(*)\% Processor Time". Ama bu şekilde Get-Counter tüm süreçlerin toplam anlık yüzdesini veriyor.

Get-Counter -Counter "\Process(*)\% Processor Time"

Ayrı ayrı süreçlerın anlık işlemci kullanım oranlarını görebilmek için ise bu komutun döndüğü [PerformanceCounterSampleSet] nesnesinin CounterSamples dizisini genişletmek gerek. Bu dizinin içinde her sürecin işlemci kullanımı CookedValue değeri içinde geliyor. Sonra bu değere göre dizmeli (Sort-Object -Property CookedValue -Descending) ve en çok değere sahip 10 (Select-Object -First 10) tanesini listelemeliyim:

Get-Counter -Counter "\Process(*)\% Processor Time" | 
    Select-Object -ExpandProperty CounterSamples |
        Sort-Object -Property CookedValue -Descending |
            Select-Object -First 10 

Bu en çok işlemci kullanımına sahip ilk 10. Ama burada görmek istemeyeceğimiz değerleri süzmek için Where-Objet {$_.InstanceName -notin ("_total","idle","system") kullanabiliriz.

Get-Counter -Counter "\Process(*)\% Processor Time" | 
    Select-Object -ExpandProperty CounterSamples |
        Where-Object {$_.InstanceName -notin ("_total","idle","system")} | 
            Sort-Object -Property CookedValue -Descending |
                Select-Object -First 10

Bu bize anlık olarak en fazla işlemci kullanım oranına sahip 10 süreci verir. İlgilendiğimiz bir süreç varsa ve bu sürecin anlık işlemci kullanım oranıyla ilgileniyorsak, örneğin yazdırma biriktiricisi (print spooler) için şöyle bir script olabilir:

Get-Counter '\Process(*)\% Processor Time' | 
    Select-Object -ExpandProperty CounterSamples | 
        where {$_.InstanceName -eq "spoolsv"}

Bu işler daha kolay olamaz mıydı?

Hiç yorum yok: