Skript zum Messen der CPU-Last für Windows
Moin Kollegen,
ich suche nach einem Skript, welches ich alle 10 Minuten vom Taskplaner aus starten lassen will, um auf einigen Servern (2008R2/2012R2) die CPU-Nutzung aufzuzeichnen.
Auf http://stackoverflow.com/questions/6298941/how-do-i-find-the-cpu-and-ra ... fand ich
was schon nahezu perfekt ist. Leider listet es nicht die 32-Bit-Prozesse mit auf. Kann mir jemand sagen, ob ich das mit einem Skript hinbekomme, oder muss ich ein zweites von der 32-Bit-Powershell.exe starten und die Ergebnisse verheiraten?
ich suche nach einem Skript, welches ich alle 10 Minuten vom Taskplaner aus starten lassen will, um auf einigen Servern (2008R2/2012R2) die CPU-Nutzung aufzuzeichnen.
Auf http://stackoverflow.com/questions/6298941/how-do-i-find-the-cpu-and-ra ... fand ich
Get-Counter -ComputerName localhost '\Process(*)\% Processor Time' `
| Select-Object -ExpandProperty countersamples `
| Select-Object -Property instancename, cookedvalue `
| Sort-Object -Property cookedvalue -Descending | Select-Object -First 20 `
| ft InstanceName,@{L='CPU';E={($_.Cookedvalue/100).toString('P')}} -AutoSize
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 305733
Url: https://administrator.de/contentid/305733
Ausgedruckt am: 25.11.2024 um 01:11 Uhr
16 Kommentare
Neuester Kommentar
Keine Ursache
Kannst Du mir noch einen Tipp geben, wie ich es mit out-file hinbekomme, so dass es auch vom Taskplaner aus gestartet in eine Datei schreibt?
Dazu pappst du an den obigen Code hinter -AutoSize einfach noch ein| out-file 'C:\log\cpu.log'
Gerade nur einen 2012R2er hier, teste nachher mal auf einem 2008R2er.
Die Counter lauten hier eventuell einfach anders.
Die verfügbaren Counter kannst du dir mit:
anzeigen lassen.
Wenn es ein deutsches System ist muss 'process' stattdessen 'prozess' lauten.
Die Meldung ist aber ein möglicher Indiz das dein Skript stattdessen in einer 32-Bit Konsole läuft.
-edit- auf einem 2008R2 einwandfrei im Taskplaner als SYSTEM getestet, hier ist es aber ein deutsches System auf dem der Performance-Counter:
\Prozess\Prozessorzeit (%)
lautet. Es kann bei dir eigentlich nur am Namen des Counters liegen.
Das mal wieder zum Thema "sprachunabhängige" Counternamen ... Danke MS
Die Counter lauten hier eventuell einfach anders.
Das angegebene Objekt wurde nicht auf dem Computer gefunden
Die verfügbaren Counter kannst du dir mit:
Get-Counter -ListSet process | select -Expand Counter
Wenn es ein deutsches System ist muss 'process' stattdessen 'prozess' lauten.
Die Meldung ist aber ein möglicher Indiz das dein Skript stattdessen in einer 32-Bit Konsole läuft.
-edit- auf einem 2008R2 einwandfrei im Taskplaner als SYSTEM getestet, hier ist es aber ein deutsches System auf dem der Performance-Counter:
\Prozess\Prozessorzeit (%)
lautet. Es kann bei dir eigentlich nur am Namen des Counters liegen.
Das mal wieder zum Thema "sprachunabhängige" Counternamen ... Danke MS
Lösung dazu findest du hier:
http://www.powershellmagazine.com/2013/07/19/querying-performance-count ...
http://www.powershellmagazine.com/2013/07/19/querying-performance-count ...
Lag aber im Endeffekt an der ISE. Die hat manchmal so ihre Eigenheiten.
Ich hatte den Code zurückgezogen da die IDs auf jeder Platform anders sind (wusste ich nicht), d.h. will man ein Skript für eine Platform universell machen muss man sich erst die IDs der jeweiligen Platform (WIN10/2008R2/2021R2) holen, d.h die Zeilen 25 und 26 mit der jeweiligen Funktion Get-PerformanceCounterIdByName ausführen. Hierbei ist der lokalisierte String des aktuellen Systems zu nehmen auf dem man das gerade ausführt. Hinterher kann man auf der selben Platform stattdessen die ermittelten IDs benutzen.
D.h. Zeilen 14-26 führt man einmalig auf der Platform aus und kann dann für $root und $sub die ermittelten IDs verwenden.
Funktioniert hier auf diesen Systemen: WIN7/WIN10/2008R2/2012R2
(ACHTUNG: habe hier die deutschen Strings in Zeilen 25 und 26 verwendet. Und wie gesagt Zeilen 14-26 sind nur einmalig auf einem System der selben Platform auszuführen, nur um an die IDs zu kommen)
D.h. Zeilen 14-26 führt man einmalig auf der Platform aus und kann dann für $root und $sub die ermittelten IDs verwenden.
Funktioniert hier auf diesen Systemen: WIN7/WIN10/2008R2/2012R2
(ACHTUNG: habe hier die deutschen Strings in Zeilen 25 und 26 verwendet. Und wie gesagt Zeilen 14-26 sind nur einmalig auf einem System der selben Platform auszuführen, nur um an die IDs zu kommen)
Function Get-PerformanceCounterNameByID {
param([UInt32]$id)
$buff = New-Object System.Text.StringBuilder(1024)
[UInt32]$bSize = $buff.Capacity
Add-Type -MemberDefinition '[DllImport("pdh.dll", SetLastError=true, CharSet=CharSet.Unicode)] public static extern UInt32 PdhLookupPerfNameByIndex(string szMachineName, uint dwNameIndex, System.Text.StringBuilder szNameBuffer, ref uint pcchNameBufferSize);' -Name PerfCounter -Namespace Util
$result = [Util.PerfCounter]::PdhLookupPerfNameByIndex($env:COMPUTERNAME, $id, $buff, [Ref]$bSize)
if ($result -eq 0){
$buff.ToString().Substring(0, $bSize-1)
}else{
Throw 'Get-PerformanceCounterNameById : Konnte lokalisierten Namen nicht finden. Überprüfen sie die übergebene ID.'
}
}
function Get-PerformanceCounterIdByName {
param([Parameter(Mandatory=$true)][string]$Name)
$counters = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage' -Name Counter).Counter
$index = [array]::IndexOf($counters,$Name)
if ($index -ne -1){
return $counters[($index-1)]
}else{
throw 'Get-PerformanceCounterIdByName: ID für diesen Namen wurde nicht gefunden'
}
}
$root = Get-PerformanceCounterIdByName -Name 'Prozess'
$sub = Get-PerformanceCounterIdByName -Name 'Prozessorzeit (%)'
$counter = "\$(Get-PerformanceCounterNameById $root)(*)\$(Get-PerformanceCounterNameByID $sub)"
Get-Counter -Counter $counter -EA Ignore | select -Expand CounterSamples | sort CookedValue -Desc | ft InstanceName,@{n='CPU';e={($_.Cookedvalue/100).toString('P')}} -AutoSize