Linux "Top" -Befehl für Windows Powershell?


61

Ich suche ein PowerShell-Cmdlet, das ähnliche Funktionen wie die Linux Top-App bietet. Etwas, das in bestimmten Intervallen aktualisiert wird und die Prozessliste mit CPU% util anzeigt.

Ich habe Skripte gesehen, die die CPU-Auslastung in einer Schleife auflisten, aber so etwas wie top wäre viel praktischer, da wir SSH / Powershell-Zugriff für die Verwaltung eingerichtet haben (ich bevorzuge immer noch eine Putty-Shell!)


Dies fällt direkt in der superuser.com Kategorie von Fragen.

Cool - wusste gar nicht, dass es diese Seite überhaupt gibt! (Ich bin hauptsächlich ein C #

3
Die CPU-Eigenschaft für das Prozessobjekt ist nicht der Prozentsatz der CPU, sondern die Gesamt-CPU-Zeit seit dem Prozessstart.

Antworten:


36
While(1) {ps | sort -des cpu | select -f 15 | ft -a; sleep 1; cls}

Dies ist eine einfache Einlage, die auch die Etiketten oben hält.

Dies funktioniert, da beim Formatieren der Tabelle ohne Parameter nur die Standardtabelle gezeichnet wird. Die automatische Größe wird verwendet, um die Spaltenbreite automatisch anzupassen, damit alle Daten auf den Bildschirm passen.

Hier ist eine Aufschlüsselung der verwendeten verkürzten Befehle

  • select -f ist eine Abkürzung für -first
  • ft ist eine Abkürzung für Format-Table
  • -a ist eine Abkürzung für -autosize
  • Standardmäßig werden Sekunden für den Ruhezustand verwendet

2
CPUin psist die Anzahl der Sekunden der Gesamtnutzung, nicht% CPU. Das ist also nicht so nützlich.
Artyom

26

Ich weiß nichts davon in Form eines einzelnen Cmdlets, aber wie Sie sagen, Skripte sind einfach zu schreiben, um top zu emulieren.

while (1) { ps | sort -desc cpu | select -first 30; sleep -seconds 2; cls }

nah genug - ich kann es von hier aus optimieren ... gut gemacht! (Ich bin ein C #

Wenn Sie mehr erfahren möchten - zum Beispiel - besuchen
Sie

@TimAtVenturality - Sie können das Skript als Funktion mit Parametern umbrechen, um top genauer zu replizieren.
Joe Internet

17

Eine ähnliche Lösung wie die anderen, jedoch mit Get-Counter anstelle von Get-Process.

While(1) { $p = get-counter '\Process(*)\% Processor Time'; cls; $p.CounterSamples | sort -des CookedValue | select -f 15 | ft -a}

Beispielausgabe:

Path                                                      InstanceName              CookedValue
----                                                      ------------              -----------
\\server_name\process(_total)\% processor time                 _total               4806.03969127454
\\server_name\process(idle)\% processor time                   idle                 1103.7573538257
\\server_name\process(program#2)\% processor time              program              749.692930701698
\\server_name\process(program#5)\% processor time              program              563.424255927765
\\server_name\process(program#1)\% processor time              program              535.714866291973
\\server_name\process(program#6)\% processor time              program              455.665518455242
\\server_name\process(program#3)\% processor time              program              426.416718284128
\\server_name\process(program)\% processor time                program              395.628507577693
\\server_name\process(program#4)\% processor time              program              335.591496700144
\\server_name\process(microsoftedgecp#2)\% processor time      microsoftedgecp      129.310484967028
\\server_name\process(system)\% processor time                 system               80.0493478367316
\\server_name\process(chrome#8)\% processor time               chrome               1.53941053532176

Ich habe festgestellt, dass die meisten anderen Lösungen hier mithilfe von get-process die gesamte CPU-Zeit seit dem Start des Prozesses melden. Das war auf meinem Server, der rund um die Uhr erreichbar ist und bei dem das beste Ergebnis immer nur svchostund systemin Millionen von Sekunden erzielt wurde, nicht sinnvoll . Ein True- topoder Task-Manager-Äquivalent würde einen Schnappschuss der CPU-Auslastung geben, die kürzlich über einen festgelegten Zeitraum aufgezeichnet wurde, und Get-Counter stellt dies bereit. Da dieser Superuser-Beitrag immer noch das Top-Google-Ergebnis für "Powershell-Top" ist, habe ich mir diese Alternative zu Eigen gemacht.

Mein Befehl basiert auf Beispiel 13 aus den Get-Counter-Dokumenten: https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Diagnostics/Get-Counter .
Hier ist eine Aufschlüsselung des Einzeilers, damit Sie ihn leichter an Ihre Bedürfnisse anpassen können:

  • While(1) { schlingt es einfach
  • get-counter '\Process(*)\% Processor Time'Wählt die CPU% Daten aus. Dieser Befehl scheint eine beträchtliche Zeit in Anspruch zu nehmen, sodass dies nicht erforderlich istsleep
  • cls klar für den neuen Tisch
  • sort -des CookedValue CookedValue ist das Feld, auf dem wir uns auskennen
  • select -f 15 Anzeige zuerst 15
  • ft -a Anzeige in formatierter Tabelle

4
Dies ist die beste Antwort: Get-CounterSie erhalten die "augenblickliche" CPU und nicht die kumulierte CPU-Zeit von ps. Bessere Formatierung : Get-Counter '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples| Select-Object -Property instancename, cookedvalue| ? {$_.instanceName -notmatch "^(idle|_total|system)$"} | Sort-Object -Property cookedvalue -Descending| Select-Object -First 25| ft InstanceName,@{L='CPU';E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}} -AutoSize
pjhsea

6

Bietet die netten Überschriften oben bei jedem Update, ohne dass die gesamte Konsole gelöscht werden muss.

$saveY = [console]::CursorTop
$saveX = [console]::CursorLeft      

while ($true) {
    Get-Process | Sort -Descending CPU | Select -First 30;
    Sleep -Seconds 2;
    [console]::setcursorposition($saveX,$saveY+3)
}

5

Mir ist kein PowerShell-Cmdlet bekannt, das die Funktionalität bereitstellt. Es gibt einen externen Freeware-Befehl, der das tut, was Sie wollen. Schauen Sie sich die PS - Liste von Mark Russinovich aus der Sysinternals-Suite an. PSLIST enthält eine Liste der ausgeführten Prozesse in einer konfigurierbaren Ansicht. "pslist -s" bietet die Art von kontinuierlicher Aktualisierung, die Sie möchten, mit einer Standardaktualisierungsrate von einmal pro Sekunde.

Ich bevorzuge Marks GUI Process Explorer, aber pslist ist praktisch für Konsolensitzungen.

Die Sysinternals-Homepage finden Sie hier: http://technet.microsoft.com/en-us/sysinternals

Dennis


2
while (1) {ps | sort -desc cpu | select -first 30; 
sleep -seconds 2; cls; 
write-host "Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName"; 
write-host "-------  ------    -----      ----- -----   ------     -- -----------"}

Dies ist nur eine etwas schönere Möglichkeit, da die Überschriften jedes Mal oben zu sehen sind


1

Außerdem möchte ich darauf hinweisen, dass Sie Cygwin verwenden können, wenn Sie eine Linux-ähnliche Umgebung für Windows möchten. Es bringt die Linux-Umgebung zu Windows. Sie können fast jeden Befehl verwenden. Nicht sicher, wie nützlich dies für Sie ist.

http://www.cygwin.com/


1

Dies kann auch den Trick machen:

function htopish {
  Param (
    [Parameter(Position=1)] [Alias("l")]
    [int]$TotalList=24,
    [Parameter(Position=2)] [Alias("r")]
    [int]$Invertal=1
  )
  Begin {}
  Process {
    While ($true) {
      $CounterSamples = Get-Counter '\Process(*)\ID Process','\Process(*)\% Processor Time','\Process(*)\Working Set' | Select-Object -Expand CounterSamples
      Clear-Host
      $CounterSamples | Group-Object { Split-Path $_.Path } | Where-Object {$_.Group[1].InstanceName -notmatch "^Idle|_Total|System$"} | Sort-Object -Property {$_.Group[1].CookedValue} -Descending | Select-Object -First $TotalList | Format-Table @{Name="ProcessId";Expression={$_.Group[0].CookedValue}},@{Name="ProcessorUsage";Expression={[System.Math]::Round($_.Group[1].CookedValue/100/$env:NUMBER_OF_PROCESSORS,4)}},@{Name="ProcessName";Expression={$_.Group[1].InstanceName}},@{Name="WorkingSet";Expression={[System.Math]::Round($_.Group[2].CookedValue/1MB,4)}}
      Sleep -Seconds $Invertal
    }
  }
  End {}
}

Die Funktion basiert auf den Get-CounterSamples und gibt die ProcessId,ProcessName,ProcessorUsageund aus WorkingSet. Dieser Zähler Probe kann weiter verbessert werden , umfassen User, CommandLinein dem Ausgang , aber ich habe noch nicht eine performante Art und Weise , es zu tun ausgearbeitet.


1

Dieser Kommentar von Mark sollte mehr Empfehlungen erhalten, da er fast genau die Frage beantwortet und funktioniert:

Bietet die netten Überschriften oben bei jedem Update, ohne dass die gesamte Konsole gelöscht werden muss.

$saveY = [console]::CursorTop
$saveX = [console]::CursorLeft      

while ($true) {
    Get-Process | Sort -Descending CPU | Select -First 30;
    Sleep -Seconds 2;
    [console]::setcursorposition($saveX,$saveY+3)
}

(Link zum Kommentar: https://superuser.com/a/770455/989044 )

Sie sollten ein einfaches Modul dafür erstellen und auf Github hosten oder es mit Choco versehen. Ich denke, es sollte in erster Linie ein Standardmodul sein, da es auf Google stark gesucht wird und es alle Arten von Problemumgehungen gibt, aber keine davon ist so elegant und nahe am obersten Linux-Kommando.

Es tut mir leid, dass du es so gepostet hast, aber wegen der strengen Regeln hier ist es unmöglich, Kommentare oder Notizen zu machen, ohne 50 Karma oder so.


0

Um top direkt von cmd aus zu starten, müssen Sie die Datei% WINDIR% \ top.bat mit folgendem Code erstellen:

@echo off && cls && @echo TOP Program initialisation. Please Wait...
powershell -ExecutionPolicy unrestricted -command "& {cls; While(1) {ps | sort -des cpu | select -f 35 | ft -a; sleep 2; cls}}"

0

Wenn Sie nach Prozessen filtern möchten, verwenden Sie findstr

while (1) { ps | findstr explorer | sort -desc cpu | select -first 30; sleep -seconds 2; cls }

0

Möglicherweise möchten Sie den Ressourcenmonitor von Powershell aus starten mit:

PS C:\>resmon

Sie können die Anwendung jederzeit mit Alt + F4 schließen, und das sollte den Fokus wieder auf das Powershell-Fenster richten.


1
OP möchte Remote-Powershell-Sitzungen verwenden, daher passt eine GUI-Antwort nicht hierher.
PL

0

Sie können versuchen, HTOP-Alternative für Windows - NTop

htop-ähnlicher Systemmonitor mit Vi-Emulation für Windows. Weil die Verwendung des Task-Managers nicht cool genug ist.

Bildbeschreibung hier eingeben

NTop wie in Windows NT-op oder NukeTop. Was auch immer Sie bevorzugen (letzteres offensichtlich).

Befehlszeilenoptionen :

  • -C Verwenden Sie einfarbiges Farbschema.
  • -h Zeigt Hilfeinformationen an.
  • -p PID, PID ... Zeigt nur die angegebenen PIDs an.
  • -s SPALTE Nach dieser Spalte sortieren.
  • -u BENUTZERNAME Zeigt nur Prozesse an, die zu diesem Benutzer gehören.
  • -v Druckversion.

Interaktive Befehle:

  • Aufwärts- und Abwärtspfeile, PgUp und PgDown, j und k Blättern Sie durch die Prozessliste.
  • STRG + Linke und rechte Pfeiltaste Ändert die Prozesssortierspalte.
  • g Gehen Sie zum Anfang der Prozessliste.
  • G Gehen Sie zum Ende der Prozessliste.
  • Leertaste Markiert einen ausgewählten Prozess.
  • U Deaktivieren Sie alle markierten Prozesse.
  • K Alle markierten Prozesse beenden.
  • Ich kehre die Sortierreihenfolge um.
  • F Prozess folgen: Wenn die Sortierreihenfolge bewirkt, dass der aktuell ausgewählte Prozess in der Liste verschoben wird, lassen Sie die Auswahlleiste folgen. Durch manuelles Bewegen des Cursors wird diese Funktion automatisch deaktiviert.
  • n Weiter bei der Suche.
  • N Vorherige Suche.

Vi Befehle :

  • : exec CMD Führt den angegebenen Windows-Befehl aus.
  • : kill PID (s) Alle angegebenen Prozesse beenden.
  • : q ,: quit NTop beenden.
  • / PATTERN,: suche PATTERN Führe eine Suche durch.
  • : sort COLUMN Sortiert die Prozessliste nach der angegebenen Spalte.
  • : tree Prozessbaum anzeigen.

Vorkompilierte Binärdateien können hier heruntergeladen werden


1
Können Sie erläutern, wie die Lösung damit erreicht werden kann? Aus Bewertung Gute Anleitung zum Empfehlen von Software hier
Fixer1234

0

Speichern Sie Folgendes in einer Datei mit dem Namen mytop.ps1in einem Ordner, der sich in Ihrer PATHUmgebungsvariablen befindet. Verwenden Sie dann eine der folgenden Optionen in einer beliebigen PowerShell-Konsole:

  1. mytop - Standardmäßig nach der Spalte 'Speicher' sortieren und die ersten 30 Zeilen anzeigen.
  2. mytop CPU 50 - Nach der Spalte 'CPU' sortieren und die ersten 50 Zeilen anzeigen.
  3. While(1) {$p = myTop Memory 50; cls; $p} - um es jede Sekunde oder so aktualisieren zu lassen.

mytop.ps1 Inhalt:

##################################################
#  Linux top equivalent in PowerShell
##################################################
if ($args[0] -eq $null) {
    $SortCol = "Memory"
} else {
    $SortCol = $args[0]    
}

if ($args[1] -eq $null) {
    $Top = 30
} else {
    $Top = $args[1]   
}


$LogicalProcessors = (Get-WmiObject -class Win32_processor `
    -Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;

function myTopFunc ([string]$SortCol = "Memory", [int]$Top = 30) {
    ## Check user level of PowerShell 
    if (
        ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() 
        ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
    )
    {
        $procTbl = get-process -IncludeUserName | select ID, Name, UserName, Description, MainWindowTitle
    } else {
        $procTbl = get-process | select ID, Name, Description, MainWindowTitle
    }

    Get-Counter `
        '\Process(*)\ID Process',`
        '\Process(*)\% Processor Time',`
        '\Process(*)\Working Set - Private'`
        -ea SilentlyContinue |
    foreach CounterSamples |
    where InstanceName -notin "_total","memory compression" |
    group { $_.Path.Split("\\")[3] } |
    foreach {
        $procIndex = [array]::indexof($procTbl.ID, [Int32]$_.Group[0].CookedValue)
        [pscustomobject]@{
            Name = $_.Group[0].InstanceName;
            ID = $_.Group[0].CookedValue;
            User = $procTbl.UserName[$procIndex]
            CPU = if($_.Group[0].InstanceName -eq "idle") {
                $_.Group[1].CookedValue / $LogicalProcessors 
                } else {
                $_.Group[1].CookedValue 
                };
            Memory = $_.Group[2].CookedValue / 1KB;
            Description = $procTbl.Description[$procIndex];
            Title = $procTbl.MainWindowTitle[$procIndex];
        }
    } |
    sort -des $SortCol |
    select -f $Top @(
        "Name", "ID", "User",
        @{ n = "CPU"; e = { ("{0:N1}%" -f $_.CPU) } },
        @{ n = "Memory"; e = { ("{0:N0} K" -f $_.Memory) } },
        "Description", "Title"
        ) | ft -a
}

myTopFunc -SortCol $SortCol -top $Top

Beispielausgabe:

Name                               ID User                         CPU   Memory       Description
----                               -- ----                         ---   ------       -----------
sqlservr                         7776 NT SERVICE\MSSQLSERVER       0.0%  19,001,488 K SQL Server Windows NT - 64 Bit
python                          12872 NA\user1                     0.0%  2,159,796 K  Python
svchost                          3328 NT AUTHORITY\SYSTEM          1.6%  1,022,080 K  Host Process for Windows Services
onedrive                        11872 NA\user1                     0.0%  423,396 K    Microsoft OneDrive
python                          13764 NA\user1                     0.0%  304,608 K    Python
chrome                          21188 NA\user1                     0.0%  250,624 K    Google Chrome
python                          28144 NA\user2                     0.0%  225,824 K    Python
code                            21384 NA\user1                     0.0%  211,160 K    Visual Studio Code
code                            27412 NA\user2                     0.0%  185,892 K    Visual Studio Code
ssms                            18288 NA\user1                     29.5% 155,452 K    SSMS
chrome                           7536 NA\user1                     0.0%  154,124 K    Google Chrome
code                            21652 NA\user1                     0.0%  149,900 K    Visual Studio Code
explorer                         3204 NA\user1                     0.0%  134,340 K    Windows Explorer
python                          11712 NA\user1                     0.0%  130,624 K    Python
chrome                          21588 NA\user1                     0.0%  107,448 K    Google Chrome
code                            10152 NA\user1                     0.0%  100,880 K    Visual Studio Code
code                            20232 NA\user2                     0.0%  99,124 K     Visual Studio Code
python                          22184 NA\user1                     0.0%  94,800 K     Python
code                            14828 NA\user1                     0.0%  84,872 K     Visual Studio Code
searchui                        13344 NA\user1                     0.0%  78,260 K     Search and Cortana application
com.docker.service              10644 NT AUTHORITY\SYSTEM          0.0%  77,332 K     Docker.Service

Zusätzliches Guthaben für:

  1. rokumaru für https://stackoverflow.com/a/55698377/5060792
  2. LotPings für https://stackoverflow.com/a/55680398/5060792
  3. DBADon für https://stackoverflow.com/a/55697007/5060792


0

Mit dem folgenden Befehl erhalten Sie die Top 10 der CPU-Auslastung und die Ausgabe wird alle 5 Sekunden aktualisiert

while (1) {ps | Sort-Object -Property cpu -Descending | select -First 10; Write-Host "Die Ausgabe wird in 5 Sekunden aktualisiert. nn Handles NPM (K) PM (K) WS (K) CPU (s) ID SI ProcessName"; Schlaf - 5 Sekunden

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.