I've been trying to create a PowerShell script which should list all running instances of svchost.exe process along with their PID, CommandLine, CPU, and RAM usage. However, I have an issue with displaying CommandLine parameter - this line is blank for all the listed processes. Could you help me, please? (I'm only a beginner.) Thanks!
Get-Process -Name svchost |
Select-Object Id, ProcessName, CommandLine, @{Name='CPU Usage (%)';Expression={($_.TotalProcessorTime.TotalSeconds / (Get-WmiObject -Class Win32_Processor | Select-Object -ExpandProperty NumberOfLogicalProcessors)).ToString("F2")}},
@{Name='RAM Usage (MB)';Expression={[Math]::Round(($_.WorkingSet / 1MB),1)}} |
Out-File -FilePath "$env:userprofile\Desktop\svch_list.txt"

Tried this code also but I couldn't get CPU usage to work properly - it was showing 0.00% for every listed process (CommandLine was working perfectly):
Get-CimInstance -Class Win32_Process -Filter "Name LIKE 'svchost%'" |
Select-Object ProcessId, CommandLine, @{Name='CPU Usage';Expression={($_.PercentProcessorTime / (Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfLogicalProcessors).ToString("P")}},
@{Name='RAM Usage (MB)';Expression={[Math]::Round(($_.WorkingSetSize / 1MB),1)}} |
Out-File -FilePath "$env:userprofile\Desktop\svch_list.txt"

Your commands for obtaining the command lines are correct in principle:
The first one only works in PowerShell (Core) 7+, because only there are the System.Diagnostics.Process instances output by Get-Process's output decorated with a .CommandLine property by PowerShell (the linked type does not have this property); a simplified example:
Get-Process svchost | Select-Object Id, Name, CommandLine
The second one, based on Get-CimInstance and the Win32_Process class works in Windows PowerShell too; a simplified example (note the need to include .exe in this case, and the different column name for the process ID):
Get-CimInstance Win32_Process -Filter 'Name = "svchost.exe"' |
Select-Object ProcessId, Name, CommandLine
However, to see most svchost.exe command lines, you need to run with elevation, i.e. as an administrator (your second screenshot implies that you're already doing that).
(This isn't required to see the command lines of processes launched by you rather than the system).
However, even then I see 2 processes that don't have a command line - not sure why.
As for calculating the CPU utilization in percent:
.TotalProcessorTime.TotalSeconds is the cumulative time that the given process has spent using the CPU(s) since it was launched. A such, it is not suitable for calculating a momentary CPU utilization percentage.
While .PercentProcessorTime is the correct property for this calculation, it only exists on the Win32_PerfRawData_PerfProc_Process WMI class, not the Win32_Process class.
Therefore, a solution that works in both PowerShell editions is the following (RAM Usage (MB) column omitted):
Get-CimInstance Win32_Process -Filter 'Name = "svchost.exe"' |
Select-Object ProcessId, Name, @{
Name = 'CPU Usage (%)'
Expression = {
((Get-CimInstance Win32_PerfFormattedData_PerfProc_Process -Filter "IDProcess = $($_.ProcessId)").PercentProcessorTime / $env:NUMBER_OF_PROCESSORS).ToString('F2')
}
}, CommandLine
However, you can also use the calculated CPU Usage (%) property with the PowerShell 7+ solution, if you replace $_.ProcessId with $_.Id.
Note:
The .PercentProcessorTime value is an integer value, so its precision is limited, and it seemingly applies across all logical processors that the system has, so its value can be greater than 100.
Fractional values that may warrant .ToString('F2') formatting only come into play through the division by the number of logical processors (most easily obtained via the $env:NUMBER_OF_PROCESSORS environment variable), which is necessary to normalize the value to a true percentage value (with a maximum of 100).
Note that svchost.exe processes, specifically, often use so little CPU time that they show with 0% CPU utilization (confirm via Task Manager), so the fact that this value is reported for them does not mean that the calculation isn't working.
while ($true) {}-Filter 'Name = "powershell.exe"' instead of -Filter 'Name = "svchost.exe"', and you should see a percentage value that close to maxing out one of the logical processors in your system; e.g., if there are 2 logical processors, you should see a value close to 50%.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With