Powershell самостоятельно меняет содержимое массива - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть очень простой кусок кода, который должен получить необработанные данные, необходимые для вычисления количества секунд использования CPU за последние 30 секунд любым процессом wscript

$prev=Get-Process | Where-Object { $_.Name -eq "wscript" } 

$prev

start-sleep -Seconds 30

$curr=Get-Process | Where-Object { $_.Name -eq "wscript" } 

echo "section 2"

$prev

echo "section 3"

$curr

Однако значения в $ prev сбрасываются после $ curr, как показано в выходных данных ниже. Раздел 2 должен быть таким же, как первый раздел, но он соответствует третьему разделу.

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                                                                                                                                       
-------  ------    -----      -----     ------     --  -- -----------                                                                                                                                                       
    177      19     2640       9252   1,795.55  12308   1 wscript                                                                                                                                                           
    177      19     2628       9340   1,799.67  17316   1 wscript                                                                                                                                                           
    177      19     2652       9292   1,803.83  25248   1 wscript                                                                                                                                                           
section 2
    177      19     2640       9252   1,825.28  12308   1 wscript                                                                                                                                                           
    177      19     2628       9340   1,829.42  17316   1 wscript                                                                                                                                                           
    177      19     2652       9292   1,833.53  25248   1 wscript                                                                                                                                                           
section 3
    177      19     2640       9204   1,825.28  12308   1 wscript                                                                                                                                                           
    177      19     2628       9296   1,829.42  17316   1 wscript                                                                                                                                                           
    177      19     2652       9264   1,833.55  25248   1 wscript

1 Ответ

0 голосов
/ 06 ноября 2018

Экземпляры [System.Diagnostics.Process], возвращаемые Get-Process, представляют собой live объекты , что означает, что их свойства отражают состояние процесса во время вызова . [1]

Таким образом, предполагая, что набор процессов wscript не изменился между вашими вызовами Get-Process, вы получите объекты, которые указывают на такие же процессы и их свойства возвращают те же самые значения, а именно тогдашние текущие значения, такие как процессорное время, использованное до сих пор.

Чтобы избежать этого, необходимо сделать снимок интересующих значений , что проще всего сделать , создав [pscustomobject] клонов объектов процесса с помощью Select-Object

$prev = Get-Process -Name "wscript" | Select-Object *

Обратите внимание, что это клоны все публичные свойства; для повышения производительности вы можете просто клонировать интересующие вас значения, скажем, Select-Object Id, Name, CPU.
Также обратите внимание, как я избавился от необходимости Where-Object, учитывая, что вы можете просто найти процессы с заданным именем с помощью Get-Process -Name.


Чтобы рассчитать разницу в потребляемом времени процессора, вы можете использовать следующий подход:

# Get the processes...
$processes = Get-Process "wscript"
# ... and create snapshot objects for them.
$processesSnapshot = $processes | Select-Object *

start-sleep -Seconds 30

# Create objects that contain the delta (difference) in CPU
# time elapsed, by comparing the .CPU values from the live objects
# to that of the snapshots.
$i = 0
$CpuDeltas = foreach ($process in $processes) {
  $processSnapshot = $processesSnapshot[$i++]
  # Clone the snapshot object and add a property reflecting the CPU-consumption
  # delta and output it.
  $processSnapshot | Select-Object *, @{ n='CpuDelta'; e={ $process.CPU - $_.CPU } } 
}

# Output for display.
$CpuDeltas | Format-Table Id, Name, CpuDelta

[1] Некоторые свойства, такие как .MainWindowTitle, кэшируются и требуют вызова метода .Refresh() для отражения текущего значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...