Powershell自行更改数组内容

daz*_*sed 3 powershell properties

我有一段非常简单的代码,可以获取我需要的原始数据来计算任何wscript进程在过去30秒内使用的CPU的秒数

$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
Run Code Online (Sandbox Code Playgroud)

但是,在$ curr之后,$ prev中的值会重置,如下面的输出所示.第2节应与第1节相同,但它与第3节相匹配.

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
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 5

[System.Diagnostics.Process]返回Get-Process实例活动对象,这意味着它们的属性反映了调用时的进程状态.[1]

因此,假设wscript您的Get-Process调用之间的进程集没有变化,您将获得指向相同进程的对象,因此它们的属性返回相同的值 - 即当时的值,例如消耗的CPU时间,远.

为了避免这种情况,您需要拍摄感兴趣的值的快照,这可以通过以下方式创建[pscustomobject]过程对象的克隆来Select-Object轻松完成:

$prev = Get-Process -Name "wscript" | Select-Object *
Run Code Online (Sandbox Code Playgroud)

请注意,这将克隆所有公共属性; 为了获得更好的性能,您可能只想克隆感兴趣的值,比如说Select-Object Id, Name, CPU.
另外,请注意我是如何消除需求的Where-Object,因为您可以简单地找到给定名称的进程Get-Process -Name.


要计算消耗的CPU时间差异,可以使用以下方法:

# 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
Run Code Online (Sandbox Code Playgroud)

[1]某些属性(如缓存)会.MainWindowTitle缓存,并且需要调用该.Refresh()方法以反映当时的当前值.