向下滚动以获取TL; DR
我需要尽快为每个进程获取以下属性,最好是5秒,最多10秒: ID,名称,描述,路径,公司,用户名,会话ID,StartTime,内存,CPU(百分比,而不是时间)
要获取此数据,我整理了以下(我认为)功能完善的代码段:
$ProcessCPU = Get-Wmiobject Win32_PerfFormattedData_PerfProc_Process | Select-Object IDProcess,PercentProcessorTime
$Processes = Get-Process -Includeusername |
Select-Object `
@{Name='Id';Expression={[int]$_.Id}},@{Name='Name';Expression={[string]$_.Name}},@{Name='Description';Expression={[string]$_.Description}},@{Name='Path';Expression={[string]$_.Path}},@{Name='Company';Expression={[string]$_.Company}},@{Name='username';Expression={[string]$_.username}},@{Name='SessionId';Expression={[string]$_.SessionId}},@{Name='StartTime';Expression={[string](($_.StartTime).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))}},@{Name='MemoryMB';Expression={[int]([math]::Round($_.WorkingSet/1MB,2))}},@{Name='CPUPercent';Expression={
[int]($ProcessCPU | ?{'IDProcess' -eq $_.Id}).PercentProcessorTime
}}
问题在于,此行导致执行此操作需要18-22秒(这大约需要16秒):
@{Name='CPUPercent';Expression={
[int]($ProcessCPU | ?{'IDProcess' -eq $_.Id}).PercentProcessorTime
}}
PS C:\Windows\system32> Measure-Command -Expression {
$ProcessCPU = Get-Wmiobject Win32_PerfFormattedData_PerfProc_Process | Select-Object IDProcess,PercentProcessorTime
$Processes = Get-Process -Includeusername |
Select-Object `
@{Name='Id';Expression={[int]$_.Id}},@{Name='CPUPercent';Expression={
[int]($ProcessCPU | ?{'IDProcess' -eq $_.Id}).PercentProcessorTime
}}
}
TotalSeconds : 19.061206
当我删除上面提到的慢属性表达式并保留WMI查询时,执行大约需要4.5秒:
Measure-Command -Expression {
$ProcessCPU = Get-Wmiobject Win32_PerfFormattedData_PerfProc_Process | Select-Object IDProcess,2))}}
}
TotalSeconds : 4.5202906
我认为,通过在单个查询中获取所有必需的数据并返回到$ProcessCPU
数组会很快-但我很欣赏我正在遍历{{1 }}。
TL; DR:
是否有更高效的方法将两个对象连接到一个公共属性,而不是像上面那样使用迭代?即$Processes
?
我尝试了以下代码块来测试$ProcessCPU.IDProcess on $Processes.Id
,它仅用了3秒钟就执行了,但是输出是不可接受的:
$Output = $ProcessCPU + $Processes | Group-Object -Property Id