Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell script - CommandLine of a process not showing

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"

List output

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"

List output 2

like image 863
chrz997 Avatar asked Jan 01 '26 20:01

chrz997


1 Answers

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.

    • To verify that it is working, open a (separate) Windows PowerShell window and run a tight loop as follows in it: while ($true) {}
    • In a different PowerShell window, run the code above with -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%.
like image 122
mklement0 Avatar answered Jan 04 '26 13:01

mklement0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!