PowerShell (el más óptimo)
Gracias Vomit ;) que funciona como yo quería, y me permitió ver la RAM por sesión desconectada. Experimenté que Get-Counter
es muy lento, cada llamada en un bucle tarda ~1 seg. Así que opté por Get-CimInstance -ClassName Win32_PerfRawData_PerfProc_Process
y entonces obtener el conjunto de trabajo privado. - rinkert
Como destaca la OP, el rendimiento de Get-Counter
no es tan óptimo como Get-CimInstance
al recuperar valores de propiedades de la clase correspondiente. Esta variación de PowerShell incorpora esta consideración, ofreciendo un rendimiento mejorado si es de importancia para usted.
$session = quser | Where-Object { ($_ -match 'Disc') } 2>&1;
$sId = $session | ForEach-Object { ($_ -split '\s+')[2]};
$processes = Get-Process | Where-Object { $_.SessionId -in $sId };
foreach ($process in $processes) {
$workingSet = [int](Get-CimInstance -ClassName Win32_PerfRawData_PerfProc_Process -Filter "Name='$($process.Name)'").WorkingSetPrivate / 1KB;
"$($process.Id), $($workingSet)";
};
Un Gotcha
Tenga en cuenta que la solución anterior puede tener problemas para acceder a determinadas WorkingSetPrivate
valores de propiedad en la clase. Considere la posibilidad de añadir lógica condicional para ignorar los valores nulos y cero para una salida más deseable, si es necesario.
foreach ($process in $processes) {
$instance = Get-CimInstance -ClassName Win32_PerfRawData_PerfProc_Process -Filter "Name='$($process.Name)'"
if ($instance.WorkingSetPrivate -ne $null -and $instance.WorkingSetPrivate -gt 0) {
$workingSet = [int]($instance.WorkingSetPrivate / 1KB)
"$($process.Id), $($workingSet)"
}
}
Otras soluciones
Incorporar esta solución a su tarea en consecuencia resolverá este problema. Este ejemplo es una versión simple y precisa para que coincida con los valores mostrados en el Gestor de tareas como prefieras para la RAM privada activa.
Esencialmente esto...
- Pone el
Get-Process
en un comando ForEach-Object
para iterar cada proceso devuelto y los valores de las propiedades.
- Utiliza un
PSCustomObject
, dentro de almacenar el PID
en un campo.
- Utiliza
Get-Counter
especificando el Working Set - Private
a devolver, lanzándolo a un [int]
y dividiéndolo por 1 KB
en otro campo.
Los resultados devolverán una columna con el PID
y otra columna con el Memory (active private)
que coincide con lo que se ve desde el Administrador de tareas y el Details
para esas propiedades.
PowerShell
$session = quser | Where-Object { ($_ -match 'Disc') } 2>&1;
$sId = $session | ForEach-Object { ($_ -split '\s+')[2]};
Get-Process | Where-Object { $_.SessionId -in $sId } | ForEach-Object {
[PSCustomObject]@{
"PID" = $_.Id
"Memory (active private)" = [int](Get-Counter -Counter "\Process($($_.Name))\Working Set - Private").CounterSamples.CookedValue / 1KB
};
};
Salida
PID Memory (active private)
--- -----------------------
16464 164
25920 164
11412 264
12284 712
18488 712
20084 712
3660 96952
10416 96952
18424 96952
1408 59000
PowerShell (otra variante)
Aquí hay otra variación en PowerShell usando un comando ForEach
declaración de bucle que emite sólo los valores separados por comas deseados de forma más similar a la lógica existente en caso de que esto importe.
$session = quser | Where-Object { ($_ -match 'Disc') } 2>&1;
$sId = $session | ForEach-Object { ($_ -split '\s+')[2]};
$processes = Get-Process | Where-Object { $_.SessionId -in $sId };
foreach ($process in $processes) {
$workingSet = (Get-Counter -Counter "\Process($($process.Name))\Working Set - Private").CounterSamples.CookedValue / 1KB;
"$($process.Id), $([int]$workingSet)";
};
Salida
16464, 164
25920, 164
11412, 264
12284, 728
18488, 728
20084, 728
3660, 97732
10416, 97732
18424, 97732
1408, 57576
Recursos de apoyo