¿Comando de Linux "Top" para Windows Powershell?

61

Estoy buscando un cmdlet de PowerShell que pueda proporcionar una funcionalidad similar a la aplicación Linux Top. Algo que se actualiza en un intervalo determinado y muestra la lista de procesos con CPU% util.

He visto scripts que enumeran la utilización de CPU% en un bucle, pero algo como top sería mucho más útil ya que hemos configurado el acceso SSH / Powershell para la administración (¡todavía prefiero un shell de masilla!)


fuente
Esto cae directamente en la categoría de preguntas superuser.com .
Genial: ¡no se dio cuenta de que ese sitio incluso existía! (Soy principalmente un desarrollador de C #)
3
La propiedad de CPU en el objeto de proceso no es el porcentaje de CPU, es el tiempo total de CPU desde el inicio del proceso.

Respuestas:

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

Este es un revestimiento simple que también mantendrá las etiquetas en la parte superior.

Esto funciona porque formatear la tabla sin ningún parámetro simplemente dibuja la tabla predeterminada. el tamaño automático se usa para ajustar automáticamente el ancho de la columna para que todos los datos puedan caber en la pantalla.

Aquí hay un desglose de los comandos abreviados utilizados

  • select -f es un atajo para -first
  • ft es un acceso directo para Format-Table
  • -a es un atajo para -autosize
  • el sueño por defecto usa segundos
usuario1820024
fuente
2
CPUin pses el número de segundos de uso total, no% de CPU. Entonces esto no es tan útil.
Artyom
26

No sé nada de eso en forma de cmdlet único, pero como usted dice, los scripts son fáciles de escribir para emular top.

while (1) { ps | sort -desc cpu | select -first 30; sleep -seconds 2; cls }
x0n
fuente
lo suficientemente cerca, puedo ajustarlo desde aquí ... ¡bien hecho! (Soy un desarrollador de C #, pero también administro nuestros servidores, así que en la curva de PowerShell ...)
si desea obtener más información, por ejemplo, visite www.poshcode.org
x0n
@TimAtVenturality: puede ajustar el script como una función con parámetros para replicar más de cerca la parte superior.
Joe Internet
18

Una solución similar a las otras, pero usando Get-Counter en lugar de Get-Process.

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

Salida de muestra:

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

Encontré que la mayoría de las otras soluciones aquí usando get-process informan el tiempo total de la CPU desde el inicio del proceso. Eso no fue útil en mi servidor que permanece activo las 24 horas del día, los 7 días de la semana, donde el mejor resultado siempre fue justo svchosty systemen millones de segundos. Un verdadero topo equivalente del Administrador de tareas proporcionaría una instantánea del uso de la CPU registrado recientemente durante un tiempo fijo y Get-Counter lo proporciona. Dado que esta publicación de Superusuario sigue siendo el principal resultado de Google para "powershell top", pensé que valía la pena contribuir con esta alternativa.

Mi comando se basa en el ejemplo 13 de los documentos Get-Counter: https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Diagnostics/Get-Counter .
Aquí hay un desglose del one-liner para que pueda modificarlo más fácilmente según sus necesidades:

  • While(1) { solo lo repite
  • get-counter '\Process(*)\% Processor Time'selecciona la CPU% de datos. Parece que este comando tarda mucho tiempo en volver, por lo que no es necesariosleep
  • cls claro para la nueva mesa
  • sort -des CookedValue CookedValue es el campo en el que estamos interesados, para poner el más grande en la parte superior
  • select -f 15 mostrar los primeros 15
  • ft -a mostrar en tabla formateada
fireforge124
fuente
44
Esta es la mejor respuesta: Get-Counterle ofrece la CPU "instantánea", en lugar del tiempo acumulado de CPU ps. Mejor formato : 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

Proporciona encabezados agradables en la parte superior con cada actualización sin necesidad de borrar toda la consola.

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

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

No conozco un cmdlet de PowerShell que proporcione la funcionalidad. Hay un comando externo gratuito que hace lo que quieres. Mira la pslist de Mark Russinovich de la suite Sysinternals. Pslist proporciona una lista de procesos en ejecución en una vista configurable. "pslist -s" proporciona el tipo de actualización continua que desea, con una frecuencia de actualización predeterminada de una vez por segundo.

Prefiero usar el GUI Process Explorer de Mark, pero pslist es útil para las sesiones de consola.

La página de inicio de Sysinternals está aquí: http://technet.microsoft.com/en-us/sysinternals

Dennis

DMcCunney
fuente
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 "-------  ------    -----      ----- -----   ------     -- -----------"}

Esta es una forma un poco mejor, ya que puedes ver los encabezados en la parte superior cada vez

Ross Wiley
fuente
1

Además, quiero señalar que si desea un entorno similar a Linux para Windows, puede usar Cygwin. Trae el entorno Linux a Windows. Puedes usar casi todos los comandos. Sin embargo, no estoy seguro de cuán útil es esto para usted.

http://www.cygwin.com/

Josiah
fuente
1

Esto también puede hacer el truco:

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 {}
}

La función se basa en las Get-Countermuestras y generará el ProcessId,ProcessName,ProcessorUsagey WorkingSet. Esta muestra de contador podría mejorarse aún más para incluir User, CommandLineen la salida, pero no he resuelto todavía de manera performant para hacerlo.

Hames
fuente
1

Este comentario de Mark debería recibir más recomendaciones, porque hace casi exactamente cuál era la pregunta y funciona:

Proporciona encabezados agradables en la parte superior con cada actualización sin necesidad de borrar toda la consola.

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

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

(enlace al comentario: https://superuser.com/a/770455/989044 )

Debería crear un módulo simple para él y alojarlo en github o proporcionarle choco. Creo que debería ser un módulo estándar en primer lugar, porque está muy buscado en Google y hay todo tipo de soluciones, pero ninguna de ellas es tan elegante y cercana al comando superior de Linux.

Perdón por publicarlo así, pero debido a las reglas de strikt aquí es imposible comentar o hacer una nota sin 50 karma más o menos.

Matthi _
fuente
0

Para ejecutar top directamente desde cmd, deberá crear el archivo% WINDIR% \ top.bat con este código:

@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}}"
usuario374797
fuente
0

Si desea filtrar por proceso, use findtr

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

Es posible que desee iniciar el monitor de recursos desde powershell con:

PS C:\>resmon

Siempre puede cerrar la aplicación con Alt + F4 y eso debería cambiar el foco de nuevo a la ventana de PowerShell.

Albino Cordeiro
fuente
1
OP quisiera usar sesiones remotas de PowerShell, por lo que una respuesta GUI no cabe aquí.
PL
0

Puede probar htop-alternative para windows - NTop

Monitor de sistema similar a htop con Vi-emulation para Windows. Porque usar el Administrador de tareas no es lo suficientemente bueno.

ingrese la descripción de la imagen aquí

NTop como en Windows NT-op o NukeTop. Lo que prefieras (lo último obviamente).

Opciones de línea de comando :

  • -C Usar esquema de color monocromo.
  • -h Mostrar información de ayuda.
  • -p PID, PID ... Muestra solo los PID dados.
  • -s COLUMNA Ordenar por esta columna.
  • -u NOMBRE DE USUARIO Solo muestra los procesos que pertenecen a este usuario.
  • -v Versión impresa.

Comandos interactivos:

  • Flechas arriba y abajo, PgUp y PgDown, j y k Desplazar la lista de procesos.
  • CTRL + Flechas izquierda y derecha Cambian la columna de clasificación del proceso.
  • g Ir a la parte superior de la lista de procesos.
  • G Ir al final de la lista de procesos.
  • Espacio Etiqueta un proceso seleccionado.
  • U Desagrupe todos los procesos etiquetados.
  • K Mata a todos los procesos etiquetados.
  • Me Invertir el orden de clasificación.
  • F Seguir proceso: si el orden de clasificación hace que el proceso seleccionado actualmente se mueva en la lista, haga que la barra de selección lo siga. Mover el cursor manualmente deshabilita automáticamente esta función.
  • n Siguiente en la búsqueda.
  • N Anterior en búsqueda.

Comandos vi :

  • : exec CMD Ejecuta el comando dado de Windows.
  • : kill PID (s) Mata todos los procesos dados.
  • : q ,: salir Salir de NTop.
  • / PATTERN,: search PATTERN Haz una búsqueda.
  • : sort COLUMN Ordena la lista de procesos después de la columna dada.
  • : árbol de proceso de vista de árbol.

Los binarios precompilados se pueden descargar aquí.

Geografía
fuente
1
¿Puedes explicar cómo lograr la solución con esto? de revisión Buena guía para recomendar software aquí
fixer1234
0

Guarde lo siguiente en un archivo llamado mytop.ps1en una carpeta que está en su PATHvariable de entorno. Luego use uno de los siguientes de cualquier consola de PowerShell:

  1. mytop - para utilizar la ordenación predeterminada por la columna 'Memoria' y mostrar las primeras 30 líneas.
  2. mytop CPU 50 - para ordenar por la columna 'CPU' y mostrar las primeras 50 líneas.
  3. While(1) {$p = myTop Memory 50; cls; $p} - para que se actualice cada segundo más o menos.

mytop.ps1 contenido:

##################################################
#  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

Salida de ejemplo:

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

Crédito adicional a:

  1. rokumaru para https://stackoverflow.com/a/55698377/5060792
  2. LotPings para https://stackoverflow.com/a/55680398/5060792
  3. DBADon para https://stackoverflow.com/a/55697007/5060792
Arcilla
fuente
0

Use el siguiente comando, le dará la utilización de la CPU de los 10 principales y la salida se actualizará cada 5 segundos

mientras que (1) {ps | Sort-Object -Property cpu -Descending | seleccione -Primero 10; la salida del host de escritura "se actualizará en 5 segundos nn Maneja NPM (K) PM (K) WS (K) CPU (s) Id SI ProcessName"; dormir -segundos 5}

usuario1057886
fuente