In a previous tip we illustrated how you can extract the command from a command line and strip all arguments. Today, you get a function that does both. It returns a custom object that splits a command line into the actual command and its argument(s):
function Get-Argument { param ( $CommandLine ) $result = 1 | Select-Object -Property Command, Argument if ($CommandLine.StartsWith('"')) { $index = $CommandLine.IndexOf('"', 1) if ($index -gt 0) { $result.Command = $CommandLine.SubString(0, $index).Trim('"') $result.Argument = $CommandLine.SubString($index+1).Trim() $result } } else { $index = $CommandLine.IndexOf(' ') if ($index -gt 0) { $result.Command = $CommandLine.SubString(0, $index) $result.Argument = $CommandLine.SubString($index+1).Trim() $result } } } Get-Argument -CommandLine 'notepad c:\test' Get-Argument -CommandLine '"notepad.exe" c:\test'
Here is the result:
And here is a real world example: it takes all running processes, and returns the commands and arguments:
Get-WmiObject -Class Win32_Process | Where-Object { $_.CommandLine } | ForEach-Object { Get-Argument -CommandLine $_.CommandLine }
This is what the result would look like:
Now that command and argument are separated, you could also group information like this:
Get-WmiObject -Class Win32_Process | Where-Object { $_.CommandLine } | ForEach-Object { Get-Argument -CommandLine $_.CommandLine } | Group-Object -Property Command | Sort-Object -Property Count -Descending | Out-GridView