At work the other day, I found myself needing to gain some minimal process information. I mainly use .NET for my day to day existence (trying to learn Erlang right now argghh), but yeah day to day right now its .NET, so I am obviously aware of the .NET Process
class, and what it brings to the table.
I am also aware of using Windows Management Instrumentation (WMI) is the infrastructure for management data and operations on Windows-based operating systems. As such, you may also use WMI queries from .NET which you may read more about here.
The thing is for my purpose I had to use a purely command line solution, so using .NET code was out, sure I could have created a small Console App, but I just felt there was a better tool for the job. Enter PowerShell.
My Requirements
I simply wanted to grab all processes matching a certain name, and grab a property value from each process matching that name, and export that to either CSV or XML. I figured this should be something that I could easily do in PowerShell. So let's examine this step by step.
Step 1: Grabbing All Processes Matching a Criteria
Let's say we want to grab all instances of the “notepad” process. This is how we could do that in PowerShell.
Get-Process "notepad"
This yields this result:
Cool, so we have some properties for each process. Mmm interesting, I wonder if we can grab some of those properties, which is what I need to do.
Step 2: Grabbing the Property Value of Interest for the Matched Processes
One of the really really great things about PowerShell is that you can pipe the results of one operation to the next (using F# a bit I have come to love the pipe operator). That means I should be able to use these Processes that I have and try and pipe them into another PowerShell operation that extracts one of the properties. Let's try that next. I came up with this (say I wanted to grab just the “Handles
” information).
Get-Process "notepad" | Select-Object Handles
Which yields this result. See the “handles” is the only thing remaining for the “notepad” process.
If you wanted to be a bit more verbose about how you get these results, the following also works, which yield exactly the same results as those above.
Get-Process | Where-Object {$_.ProcessName -eq 'notepad'} | format-table -property Handles Get-Process | Where-Object {$_.ProcessName -eq 'notepad'} | Select-Object Handles
Ok, so what have we achieved so far?
Well, we have managed to grab only the processes we are interested in by name, and grab the value of only the property we care about for each of these processes (note only one instance of notepad.exe was running for the screen shots above). Ok, so we are doing well, not much left to do, we simply need to export this to CSV or XML.
Step 3a: Export to CSV
Ok let's export the data to CSV, must be a way right? Sure enough PowerShell doesn’t let us down, here is how:
Get-Process "notepad" | Select-Object Handles | Export-Csv file.csv
Which gives us the following CSV file
#TYPE Selected.System.Diagnostics.Process
"Handles"
"421"
Step 3b: Export to XML
Exporting to an XML file is just as easy, here is how:
Get-Process "notepad" | Select-Object Handles | Export-Clixml file.xml
Which gives us the following XML file:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.System.Diagnostics.Process</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<I32 N="Handles">421</I32>
</MS>
</Obj>
</Objs>
And there you go, job done……Hope that helped at least someone.