.png)
Ich möchte den pro Sitzung verwendeten Speicher über eine PowerShell-Funktion abrufen. Mich interessieren nur getrennte Sitzungen. Im Taskmanager kann ich den pro Sitzungs-ID verwendeten Speicher sehen:
Ich habe versucht, den in MB verwendeten Arbeitsspeicher in PowerShell mithilfe des folgenden Skripts abzurufen:
# Get all user sessions
$sessions = qwinsta | Where-Object { $_ -match 'Disc' }
$procs = get-process # | where-object {$_.ProcessName -ne "Idle"}
foreach ($session in $sessions)
{
$sessionId = ($session -split '\s+')[2]
$usrprocs = $procs | where-object {$_.SessionId -eq $sessionId}
$usrMem=0
foreach($proc in $usrprocs)
{
$usrMem = $usrMem + [int64]($proc.WorkingSet64/(1024*1024))
}
echo "$sessionId, $usrMem"
}
Aber das gibt mir das folgende Ergebnis:
20, 481
21, 451
22, 670
23, 763
24, 949
Das ist nicht annähernd der im Task-Manager angegebene Arbeitsspeicherverbrauch. Wie kann ich den RAM pro Sitzung ermitteln?
Aktualisieren Aufgrund des Vorschlags von Vomit IT habe ich Folgendes getan, bekomme aber trotzdem noch die falschen Werte angezeigt:
# Get all user sessions
$sessions = qwinsta | Where-Object { ($_ -match 'Disc') }
foreach ($session in $sessions)
{
$sessionId = ($session -split '\s+')[2]
$usrprocs = Get-Process | Where-Object { $_.SessionId -eq $sessionId }
$usrMem=0
foreach($proc in $usrprocs)
{
$usrMem = $usrMem + [int](Get-Counter -Counter "\Process($($proc.Name))\Working Set - Private").CounterSamples.CookedValue / 1KB
}
echo "$sessionId, $usrMem"
}
Ergebnis
20, 808288
22, 830872
23, 806404
24, 806312
25, 802892
Antwort1
PowerShell (am besten geeignet)
Danke, Vomit ;), das funktioniert wie gewünscht und ermöglicht mir, die RAM-Nutzung pro getrennter Sitzung zu sehen. Ich habe die Erfahrung gemacht, dass es
Get-Counter
sehr langsam ist, jeder Aufruf in einer Schleife dauert ca. 1 Sekunde. Also habe ich mich dafür entschieden, mitzumachenGet-CimInstance -ClassName Win32_PerfRawData_PerfProc_Process
und dann den Arbeitssatz privat zu machen. – rinkert
Wie vom OP hervorgehoben, Get-Counter
ist die Leistung nicht so optimal wie Get-CimInstance
beim Abrufen von Eigenschaftswerten aus der entsprechenden Klasse. Diese Variante von PowerShell berücksichtigt diese Überlegung und bietet eine verbesserte Leistung, falls dies für Sie von Bedeutung ist.
$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)";
};
Ein Gotcha
Bitte beachten Sie, dass die obige Lösung möglicherweise Probleme beim Zugriff auf bestimmte WorkingSetPrivate
Eigenschaftswerte in der Klasse hat. Erwägen Sie bei Bedarf das Hinzufügen einer bedingten Logik, um Null- und Nullwerte zu ignorieren und so ein besseres Ergebnis zu erzielen.
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)"
}
}
Andere Lösungen
Integrieren Sie diese Lösung entsprechend in Ihre Aufgabewird dieses Problem lösen. Dieses Beispiel ist eine einfache Version und entspricht genau den Werten in derTaskmanagerwie Sie es für aktiven privaten RAM bevorzugen.
Im Wesentlichen dies ...
- Fügt den
Get-Process
Befehl in eineForEach-Object
Schleife ein, um jeden zurückgegebenen Prozess- und Eigenschaftswert zu durchlaufen. - Verwendet ein
PSCustomObject
, um diePID
in einem Feld zu speichern. - Verwendet
Get-Counter
, gibt an, wasWorking Set - Private
zurückgegeben werden soll, wandelt es in ein um[int]
und dividiert das dann1 KB
in einem anderen Feld durch .
Die Ergebnisse geben eine Spalte mit PID
und eine weitere Spalte mit der Memory (active private)
Übereinstimmung mit dem zurück, was Sie im Task-Manager und in der Details
Registerkartenansicht dort für diese Eigenschaften sehen.
Power Shell
$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
};
};
Ausgabe
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 (eine andere Variante)
Hier ist eine weitere Variante in PowerShell mit einemForEach
loop-Anweisungdas nur die gewünschten Werte mit Komma getrennt ausgibt und damit Ihrer vorhandenen Logik ähnelt, falls dies von Bedeutung ist.
$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)";
};
Ausgabe
16464, 164
25920, 164
11412, 264
12284, 728
18488, 728
20084, 728
3660, 97732
10416, 97732
18424, 97732
1408, 57576