3

I have the following script to find the process "dotnet.exe". In my system, I have many dotnet.exe processes running. But I want to kill the "dotnet.exe" which has command line argument "MyService\Web\argument". I'm trying to do it by the following script. But it doesn't find anything, although I see the process in the Task Manager.

$process = Get-WmiObject Win32_Process | select name, commandline

foreach ($p in $process)
{
    if ($p.name -contains "dotnet.exe" -and $p.commandline -contains "web")
    {
        $kp =    Get-Process $p;
        $kp.CloseMainWindow();
        if (!$kp.HasExited)
        {
            $kp | Stop-Process -Force
        }
    }
    else
    {
        Write-Host name: $p.name and param: $p.commandline;
    }
}
7
  • Does $process contain the one that you are looking for? Commented Jan 3, 2018 at 20:52
  • 2
    (Get-WmiObject Win32_Process -Filter "name like '%dotnet.exe%' and commandline like '%web%'").Terminate()? Commented Jan 3, 2018 at 20:54
  • You're using the wrong comparison operator. -contains is designed for array comparisons against a single element. Use -like Commented Jan 3, 2018 at 21:35
  • I get error as: Method invocation failed because [Selected.System.Management.ManagementObject] does not contain a method named 'Terminate'. At C:\practice\kill_web.ps1:6 char:8 + $p.Terminate() + ~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Terminate:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound Commented Jan 4, 2018 at 9:07
  • 1
    Apparently you tried to retrofit the code I posted into the code in your question. Why did you do that? Please do not get creative before you got things working. Use the code I posted as-is without any modifications or additions. Commented Jan 4, 2018 at 9:49

2 Answers 2

3

All you need to do is filter the process list directly via Get-WmiObject and then terminate the matching process(es):

$fltr = "name like '%dotnet.exe%' and commandline like '%web%'"
Get-WmiObject Win32_Process -Filter $fltr | ForEach-Object {
    $_.Terminate()
}

You could also call Terminate() directly on the output of Get-WmiObject like this:

(Get-WmiObject Win32_Process -Filter $fltr).Terminate()

However, there are situations where this could fail, e.g. if Get-WmiObject doesn't return any results, or if you're using PowerShell v2 or earlier and Get-WmiObject returns more than one result (passing a method call to the members of an array requires member enumeration, which was introduced with PowerShell v3). Using a ForEach-Object loop is both more robust and backwards-compatible.

Sign up to request clarification or add additional context in comments.

4 Comments

In case, (Get-WmiObject Win32_Process -Filter $fltr) return null, the call Terminate() would result in error. So I would suggest having a null check condition.
@masiboo Please read again. I already addressed this issue in my answer.
Sorry, I'm talking about single line statement. (Get-WmiObject Win32_Process -Filter $fltr).Terminate()
Please. Read. Again. The paragraph right below that code snippet details the caveat.
1

The Get-WmiObject cmdlet returns quite useful objects, but you have stripped off everything by selecting only the Name and CommandLine parameters:

$process = Get-WmiObject Win32_Process | select name, commandline

If you remove the | select name, commandline part, you can still loop through each process but also make use of methods like Terminate() that will still be available.

You could do it in one shot, as per @ansgar-wiechers comment, or still make use of the loop and add in more logging, etc. if you wanted:

$process = Get-WmiObject Win32_Process

foreach($p in $process){
    if($p.Name -eq "*dotnet.exe" -and $p.CommandLine -like "*web*"){
       $p.Terminate()
       # and so on... 
    }
}

Note also the comment from @TheIncorrigible1 about the use of comparison operators. I have used -eq for the process name and -like for the command line.

3 Comments

I think in your code, u mentioned $p.Name -and $p.Name. It must be $p.commandline. Anyway, I get error like Method invocation failed because [Selected.System.Management.ManagementObject] does not contain a method named 'Terminate'. At C:\practice\kill_web.ps1:6 char:8 + $p.Terminate() + ~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Terminate:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound
I have fixed the typo with the property name.
Make sure you are using the actual object returned by Get-WmiObject. You must not use the select statement, as this will make methods such as Terminate() unavailable. I have updated my answer to make this more explicit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.