【问题标题】:powershell to return values like a task managerpowershell 像任务管理器一样返回值
【发布时间】:2020-03-21 15:58:04
【问题描述】:

我想使用 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 来显示每个进程的所有者,但是缺少一些参数。我从微软找不到任何关于 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/

【问题讨论】:

    标签: powershell


    【解决方案1】:

    Guo-Jyun Zeng,欢迎来到 SO。

    首先,您的“网络”部分没有显示任何内容的原因是变量扩展失败。让我解释一下——虽然 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 Read Bytes/sec”的特定于进程的性能计数器都计算所有 I/O,而不仅仅是网络。事实上,查看处理器对象,我找不到任何特定于 Network-only 的计数器。

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

    最后,作为性能方面,您可以通过重新安排您正在做的一些事情来显着减少脚本对硬件的影响:

    1. 从“Win32_PerfFormattedData_PerfProc_Process”显式请求所需的属性,因此它不会默认为所有属性。
    2. 将 Select-Object -First 5 与您的第一个 Select-Object 合并,这样您就只在循环的其余部分处理这 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
    }
    

    【讨论】:

    • 感谢您的详细解答。但是,当我使用“select-object -First 5 -Property”时,我的 CPU 始终为 0。与任务管理器对比时,CPU使用率太高,没有划分核心数。另外,我会尝试在我的代码中添加用户信息。我的母语不是英语,请原谅我的英语不好。
    • @guo-jyunzeng,你的英语很好。 =) 如果还有什么我可以提供帮助的,请告诉我。
    • 我想添加每个进程的所有者信息。我尝试了一些方法,例如@{Name="Username";Expression={win32_process $_.getowner().user}},@{Name="Username";Expression={$_.getowner().user}}, @{Name="Username";Expression={$_.startinfo.username}}, @{Name="Username";Expression={$owners[$_.id.tostring()]}}, @{Name= “用户名”; Expression = {$_.ComputerName}} 等。但是,它们都失败了。所以,我再次需要你的帮助。非常感谢。
    • 这是一个很好的起点:devblogs.microsoft.com/scripting/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 2022-12-17
    • 2016-06-04
    • 1970-01-01
    • 2018-09-27
    • 2021-12-04
    相关资源
    最近更新 更多