Powershell像任务管理器一样返回值

时间:2020-03-17 15:27:03

标签: powershell

我想使用Powershell返回值,例如任务管理器。
但是,网络使用情况无法正确返回。
如何修改代码?非常感谢。

$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
while ($true) {
    $tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process | 
    select-object -property Name, @{Name = "CPU"; Expression = {($_.PercentProcessorTime/$cores)}}, @{Name = "PID"; Expression = {$_.IDProcess}}, @{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, @{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, @{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, @{"Name"="Network"; Expression = {get-counter "\Process($_.Name)\IO Read Bytes/sec"}} |
    Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
    Sort-Object -Property CPU -Descending|
    Select-Object -First 5;
    cls
    $tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network";
    Start-Sleep 3
}

此代码根据文章进行了如下修改:
1. CPU and memory usage in percentage for all processes in Powershell
2. https://superuser.com/questions/1314534/windows-powershell-displaying-cpu-percentage-and-memory-usage#new-answer?newreg=a9290345d72946db9c7f8fd2af10de0a
3. Powershell Script - list process with cpu, memory, disk usage


我添加了一个$ process变量来显示每个进程的所有者,但是缺少一些参数。我找不到来自Microsoft的有关Get-WmiObject Win32_PerfFormattedData_PerfProc_Process的任何文档,这正常吗?修改后的代码如下:

$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
$Process = Get-Wmiobject Win32_process -computername "myComputerName" | select *,@{Name='Owner';Expression={($_.GetOwner()).User}}
while ($true) {
    $tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process | 
    select-object -property Name, @{Name = "CPU"; Expression = {($_.PercentProcessorTime/$cores)}}, @{Name = "PID"; Expression = {$_.IDProcess}}, @{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, @{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, @{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, @{"Name"="Network"; Expression = { $_.IOReadBytesPersec }}, @{Name="Username"; Expression = {($($Process | ?{$_.ProcessId -eq $Item.IDProcess})).Owner} |
    Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
    Sort-Object -Property CPU -Descending|
    Select-Object -First 15;
    cls
    $tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network", "Username";
    Start-Sleep 1
}

修改后的部分引用自https://powershell.org/forums/topic/getting-percentage-cpu-time-and-owner-for-processes/

1 个答案:

答案 0 :(得分:1)

曾国俊,您好!

首先,“网络”部分未显示任何内容的原因是因为变量扩展失败。让我解释一下-虽然PowerShell可以理解在双引号字符串内扩展的基本变量,但它不能直接理解具有自己属性的稍微复杂的对象。因此,您遇到的问题在这里:

 @{"Name"="Network"; Expression = {get-counter "\Process($_.Name)\IO Read Bytes/sec"}}

由于'$ _。Name'在双引号中,因此PowerShell不知道如何处理。您可以通过以下两种方法轻松地解决此问题:

 @{"Name"="Network"; Expression = {get-counter "\Process($($_.Name))\IO Read Bytes/sec"}}

或使用字符串标记:

@{"Name"="Network"; Expression = {get-counter ("\Process({0})\IO Read Bytes/sec" -f $_.Name)}}

但是,在要重现的测试中,仅运行Get-Counter会返回一个复杂的对象。也就是说,具有自己的属性和方法的对象因此无论如何都不会起作用。在定位结果属性时,我以为您会喜欢(Get-Counter“ \ Process(ProcessName)\ IO Read Bytes / sec”)。CounterSamples.CookedValue,该脚本根本不会返回数据-就像Get-Counters是花太长时间或其他东西。

但是,“ Win32_PerfFormattedData_PerfProc_Process”似乎已经具有您想要为其提供数据的计数器的等效属性:IOReadBytesPersec。

我唯一要注意的是,该属性和“ IO读取字节/秒”的特定于进程的性能计数器都对所有I / O进行计数,而不仅仅是网络。实际上,在查看处理器对象时,我找不到任何仅针对Network-only的计数器。

您的CPU在我运行时什么也不显示,因为在很多情况下,您试图将其除以0。在查看PercentProcessorTime时,它没有指定有关所有处理器总数的任何信息。我不认为负载会像您的代码那样在内核之间分配,我可能是错的。

最后,从性能角度来看,您可以通过重新安排一些正在做的事情来大大减少脚本对硬件的影响:

  1. 从“ Win32_PerfFormattedData_PerfProc_Process”中明确请求所需的属性,因此它并非默认为所有属性。
  2. 将“选择对象-前5个”与第一个“选择对象”合并在一起,以便在循环的其余部分中仅处理这5个对象。

以下是一些经过稍微修改的代码,以显示我描述的一些更改:

$RAM= Get-WMIObject Win32_PhysicalMemory | Measure -Property capacity -Sum | %{$_.sum/1Mb}
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
while ($true) {
    $tmp = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process | 
    select-object -First 5 -Property Name, @{Name = "CPU"; Expression = {($_.PercentProcessorTime)}}, @{Name = "PID"; Expression = {$_.IDProcess}}, @{"Name" = "Memory(MB)"; Expression = {[int]($_.WorkingSetPrivate/1mb)}}, @{"Name" = "Memory(%)"; Expression = {([math]::Round(($_.WorkingSetPrivate/1Mb)/$RAM*100,2))}}, @{Name="Disk(MB)"; Expression = {[Math]::Round(($_.IODataOperationsPersec / 1mb),2)}}, @{"Name"="Network"; Expression = { $_.IOReadBytesPersec }} |
    Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} |
    Sort-Object -Property CPU -Descending
    cls
    $tmp | Format-Table -Autosize -Property Name, CPU, PID, "Memory(MB)", "Memory(%)", "Disk(MB)", "Network";
    Start-Sleep 3
}
相关问题