Powershell自行更改阵列内容

时间:2018-11-06 13:43:02

标签: 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

但是,在$ curr之后,$ prev中的值将重置,如下面的输出所示。第2部分应与第一部分相同,但与第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

1 个答案:

答案 0 :(得分:5)

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

因此,假设在您的wscript调用之间Get-Process进程集未发生变化,您将获得指向 same 进程及其<因此,strong>属性会返回相同的值-即 then-current 值,例如到目前为止消耗的CPU时间。

为避免这种情况,您需要对目标值进行快照 ,这很容易通过创建[pscustomobject]个克隆来实现。通过Select-Object 处理过程对象:

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

请注意,这会克隆 all 个公共属性。为了获得更好的性能,您可能希望仅使用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

[1]有些属性(例如.MainWindowTitle)已被缓存,并且需要调用.Refresh()方法以反映当时的值。