.png)
PowerShell 함수를 통해 세션당 사용되는 메모리를 가져오고 싶습니다. 연결이 끊긴 세션에만 관심이 있습니다. 작업 관리자에서 sessionID당 사용된 메모리를 볼 수 있습니다.
다음 스크립트를 통해 PowerShell에서 MB 단위로 사용되는 mem을 얻으려고 했습니다.
# 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"
}
그러나 이것은 나에게 다음과 같은 결과를 제공합니다.
20, 481
21, 451
22, 670
23, 763
24, 949
작업 관리자에 나열된 사용된 메모리 근처에는 없습니다. 세션당 RAM을 어떻게 얻을 수 있나요?
업데이트 Vomit IT의 제안에 따라 이렇게 했지만 여전히 잘못된 값이 표시됩니다.
# 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"
}
결과
20, 808288
22, 830872
23, 806404
24, 806312
25, 802892
답변1
PowerShell(가장 최적)
Vomit에게 감사드립니다;) 제가 원하는 대로 작동하고 연결이 끊긴 세션당 RAM 사용량을 볼 수 있게 해주었습니다. 나는 매우 느린 경험을 했습니다
Get-Counter
. 루프의 각 호출은 ~1초 정도 걸립니다. 그래서 저는Get-CimInstance -ClassName Win32_PerfRawData_PerfProc_Process
작업 세트를 비공개로 설정하기로 결정했습니다. – 린커트
OP에서 강조한 바와 같이 의 성능은 해당 클래스에서 속성 값을 검색할 때만 Get-Counter
큼 최적이 아닙니다 . Get-CimInstance
이 PowerShell 변형은 이러한 고려 사항을 통합하여 중요한 경우 향상된 성능을 제공합니다.
$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)";
};
알았어
위의 해결 방법은 WorkingSetPrivate
클래스의 특정 속성 값에 액세스하는 데 문제가 있을 수 있습니다. 필요한 경우 보다 바람직한 출력을 위해 null 및 0 값을 무시하는 조건부 논리를 추가하는 것을 고려하십시오.
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)"
}
}
기타 솔루션
이에 따라 이 솔루션을 작업에 통합이 문제를 해결할 것입니다. 이 예는 간단한 버전이며 그림에 표시된 값과 정확하게 일치합니다.작업 관리자활성 개인 RAM을 선호합니다.
본질적으로 이것은 ...
- 반환된 각 프로세스 및 속성 값을 반복하기 위해
Get-Process
명령을 루프에 넣습니다 .ForEach-Object
- 한 필드에
PSCustomObject
를 저장하는 데 , 를 사용합니다 .PID
- 를 사용하여 반환할 을
Get-Counter
지정하고Working Set - Private
이를 an으로 캐스팅[int]
한 다음1 KB
다른 필드에서 으로 나눕니다.
결과는 작업 관리자에서 볼 수 있는 것과 일치하는 PID
열과 해당 속성에 대한 탭 보기가 있는 열을 반환합니다.Memory (active private)
Details
파워셸
$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
};
};
산출
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(또 다른 변형)
다음은 PowerShell을 사용하는 또 다른 변형입니다.ForEach
루프 문이것이 중요한 경우 기존 논리와 더 유사하게 구분된 원하는 쉼표로 값만 출력합니다.
$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)";
};
산출
16464, 164
25920, 164
11412, 264
12284, 728
18488, 728
20084, 728
3660, 97732
10416, 97732
18424, 97732
1408, 57576