PowerShell(最优)

PowerShell(最优)

我想通过 PowerShell 函数获取每个会话使用的内存。我只对断开连接的会话感兴趣。在任务管理器中,我可以看到每个 sessionID 使用的内存:

在此处输入图片描述

我尝试通过以下脚本在 PowerShell 中获取使用的内存(以 MB 为单位):

# 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 和零值,以获得更理想的输出。

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返回,将其转换为[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

支持资源

相关内容