PowerShell中线程的详细信息

jaql4c8m  于 2023-04-21  发布在  Shell
关注(0)|答案(4)|浏览(253)

如何通过powershell获取一个进程中所有线程的CPU消耗,格式如下

我运行gwmi win32_thread|select -First 1时找不到任何处理器信息。而且Start Address是数字!?!

vlju58qv

vlju58qv2#

显示与Process Explorer相同的详细信息

您提供的屏幕截图似乎是Process Explorer的屏幕截图,而不是任务管理器的屏幕截图。这使事情变得更加复杂,因为(如果我没记错的话)Process Explorer使用内核驱动程序来获取有关系统的详细信息,以便比Windows更精确地计算CPU时间。我手头没有这本书,但这应该在Windows Sysinternals Administrator's Reference中描述。

将起始地址转换为DLL和方法

开始地址,顾名思义,就是一个地址。通常它会以十六进制格式显示,但实际上它只是一个数字,所以在您的情况下它可能是数字。转换为十六进制没有问题。
如果你想把数字转换成一些有用的东西,比如DLL名称和方法名称,你需要使用符号。在你的截图中看到:Process Explorer还需要下载符号,否则将从DLL start开始计算偏移量(如van.dll+1c904)。
为了处理符号,Process Explorer使用了一个名为dbghelp.dll的Microsoft DLL。您已经在Options/Configure symbols...中配置了它。如果您愿意,您可以使用相同的DLL,但我要说,这是您停止使用Powershell的地方,因为dbghelp.dll是本机DLL,不能由. NET使用。您甚至不能在Visual Studio中创建.NET互操作程序集。因为它不是COM DLL。
此外,Process Explorer还对起始地址的显示值应用了另一个魔法:通常起始地址总是相同的:一些Microsoft代码,它创建一个线程对象,然后调用应用程序特定的代码。Process Explorer向上走堆栈跟踪并显示调用堆栈上的第一个非Microsoft帧。我不确定WMI返回的地址是否考虑了同样的事情。
如果你想给予dbghelp.dll,从地址转换为DLL的方法应该是IDebugSymbols::GetNameByOffset()
另请注意,从地址到方法的转换需要在远程计算机上完成,因为只有远程计算机才知道加载的DLL的确切版本。然后,还要考虑远程计算机需要访问Internet才能从Microsoft服务器下载符号。

远程执行

在评论中,您提到您希望在远程计算机上执行该命令。Process Explorer不支持远程计算机。虽然我不确定原因,但我猜测它只能通过WMI访问远程PC-因此遇到与您相同的限制。
然而,也有一些alternatives to Process Explorer, discussed in the Process Explorer Forum。它们似乎也受到WMI限制,但您可以给予一下。除此之外,您可以使用SysInternals PsExec在远程机器上执行程序。

总体结论

我猜预期的解决方案太复杂了,无法在StackOverflow上回答,特别是如果工具集仅限于Powershell。它至少需要C++来集成dbghelp.dllPSExec以访问远程机器。

carvr3hs

carvr3hs3#

不确定这是否可以用powershell开箱即用,但既然你提供赏金,我建议看看Process Hacker的源代码。
http://processhacker.sourceforge.net/
IIRC进程黑客是用C编写的,并且是完全开源的。
以编程方式清除windows7待机内存

q1qsirdb

q1qsirdb4#

这在PowerShell 7.3.3中运行良好

(Get-Process -ProcessName taskmgr).Threads|Sort-Object TotalProcessorTime -Descending| 
    Format-Table -Property Id,PriorityLevel,ThreadState,WaitReason,StartTime,TotalProcessorTime

输出

相关问题