以下PowerShell代码有效,生成如下所示的输出,并且可以重现。
一般的问题是:我怎样才能加快速度?
最大的瓶颈是Get-Process
和Get-Counter
cmdlet。
根据@LotPings评论编辑。
$LogicalProcessors = (Get-WmiObject –class Win32_processor
-Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;
function myTop([String]$SortCol='CPU', [Int32]$top=30) {
$NameArray = get-counter '\Process(*)\ID Process' -EA SilentlyContinue |
Select -Expand CounterSamples | Select InstanceName
$IdArray = get-counter '\Process(*)\ID Process' -EA SilentlyContinue |
Select -Expand CounterSamples | Select CookedValue
$CpuArray = get-counter '\Process(*)\% Processor Time' -EA SilentlyContinue |
Select -Expand CounterSamples | Select CookedValue
$MemArray = get-counter '\Process(*)\Working Set - Private' -EA SilentlyContinue |
Select -Expand CounterSamples | Select CookedValue
$procTbl = get-process | select ID, Name, Description, MainWindowTitle
$TopTable = @()
For ($i=0; $i -lt $NameArray.Length; $i++) {
$procIndex = [array]::indexof($procTbl.ID, [Int32]$IdArray[$i].CookedValue)
if ($NameArray[$i].InstanceName -eq '_total') {continue}
if ($NameArray[$i].InstanceName -eq 'memory compression') {continue}
if ($NameArray[$i].InstanceName -eq 'idle') {
$NewRow = [PSCustomObject]@{
Name = $NameArray[$i].InstanceName;
ID = $IdArray[$i].CookedValue;
CPU = ($CpuArray[$i].CookedValue) / $LogicalProcessors;
Mem = $MemArray[$i].CookedValue;
procID = $procTbl.ID[$procIndex];
Description = $procTbl.Description[$procIndex];
Title = $procTbl.MainWindowTitle[$procIndex];
}
$TopTable += $NewRow
} else {
$NewRow = [PSCustomObject]@{
Name = $NameArray[$i].InstanceName;
ID = $IdArray[$i].CookedValue;
CPU = $CpuArray[$i].CookedValue;
Mem = $MemArray[$i].CookedValue;
procID = $procTbl.ID[$procIndex];
Description = $procTbl.Description[$procIndex];
Title = $procTbl.MainWindowTitle[$procIndex];
}
$TopTable += $NewRow
}
}
$TopTable | sort -des $SortCol | select -f $top |`
select Name, ID,`
@{Name='CPU'; Expression = {("{0:N1}%" -f $_.CPU) } },`
@{Name='Mem'; Expression = {("{0:N0} K" -f ($_.Mem /1kb) )} },
Description, Title
}
While(1) {$p = myTop -SortCol CPU -top 12 | ft -a ; sleep 0; cls; $p}
输出(刷新率约为2秒):
Name ID CPU Mem Description Title
---- -- --- --- ----------- -----
memory compression 2768 0.0% 996,516 kb
code 8828 0.0% 232,084 kb Visual Studio Code
chrome 28620 0.0% 217,088 kb Google Chrome
code 41596 0.0% 180,076 kb Visual Studio Code
chrome 33772 0.0% 140,976 kb Google Chrome Speed up PowerShell Get-Counter and Get-Pro...
code 22600 0.0% 127,952 kb Visual Studio Code
teams 27412 0.0% 105,656 kb Microsoft Teams
powershell 55692 1.5% 95,596 kb Windows PowerShell
mcshield 8596 0.0% 93,784 kb
onedrive 59644 0.0% 80,796 kb Microsoft OneDrive
code 21708 0.0% 79,688 kb Visual Studio Code
powershell 64228 0.0% 74,508 kb Administrator: Windows PowerShell
由于我的语言环境有不同的计数器名称,我无法测试自己:
## Q:\Test\2019\04\14\SO_55678790.ps1
$LogicalProcessors = (Get-WmiObject –class Win32_processor).NumberOfLogicalProcessors;
function myTop([String]$SortCol='CPU', [Int32]$top=30) {
$NameArray = get-counter '\Process(*)\ID Process' -EA SilentlyContinue |
Select -Expand CounterSamples | Select-Object InstanceName,CookedValue
$CpuArray = get-counter '\Process(*)\% Processor Time' -EA SilentlyContinue |
Select -Expand CounterSamples | Select-Object CookedValue
$MemArray = get-counter '\Process(*)\Working Set - Private' -EA SilentlyContinue |
Select -Expand CounterSamples | Select-Object CookedValue
$proc = Get-Process
$TopTable = For ($i=0; $i -lt $NameArray.Length; $i++) {
$procIndex = [array]::indexof($proc.Id, [Int32]$NameArray[$i].CookedValue)
if ($NameArray[$i].InstanceName -eq '_total') {continue}
if ($NameArray[$i].InstanceName -eq 'idle') {
$CPU = ($CpuArray[$i].CookedValue) / $LogicalProcessors
} else {
$CPU = $CpuArray[$i].CookedValue;
}
[PSCustomObject]@{
Name = $NameArray[$i].InstanceName
ID = $NameArray[$i].CookedValue
CPU = $CPU
Mem = $MemArray[$i].CookedValue
Description = $proc[$procIndex].Description
Title = $proc[$procIndex].MainWindowTitle
}
}
$TopTable | Sort-Object -Descending $SortCol | Select-Object -First $top Name,ID,
@{Name='CPU'; Expression = {("{0:N1}%" -f $_.CPU) } },
@{Name='Mem'; Expression = {("{0:N0} kb" -f ($_.Mem /1kb) )} },
Description, Title
}
While(1) {
myTop -SortCol CPU -top 12 | ft -a
sleep 0
cls
# pause
}