How do I kill a processes running a given executable?
Asked Answered
B

2

1

I want to kill a job. First, I need it's process Id, so I execute:

get-process

And I get a boatload of processes. OK, I just want one particular process, so I use:

get-process | select-string -pattern "nginx"

Which gives me this object:

System.Diagnostics.Process (nginx)

What do I do with this? How can I pretty print this to give me the same line of output I'm getting when I ask for all the processes? I basically just want this when I grep for a given executing process:

166      11     2436       8244       0.13  24196   1 nginx                                                        
Brimstone answered 5/3, 2021 at 18:32 Comment(1)
Please don't use the term "job" when you mean process. This is not only misleading, but also attracts wrong search results, when people are looking for something about PowerShell JobsUnreserved
A
4

Select-String is probably not the hammer you wanna use for this particular nail (see below) :-)

Get-Process has a -Name parameter that takes a wildcard:

Get-Process -Name nginx
# or
Get-Process -Name *nginx*

To kill the process, either call Kill() directly on the object:

$nginxProcess = Get-Process nginx |Select -First 1
$nginxProcess.Kill()

... or simply pipe the process instances to Stop-Process:

Get-Process -Name nginx |Stop-Process

As you can see, we never actually need to locate or pass the process id - the Process object already has that information embedded in it, and the *-Process cmdlets are designed to work in concert - PowerShell is all about command composition, and this is an example of it.

That being said, Stop-Process is also perfectly capable of killing processes by name alone:

Stop-Process -Name nginx

How did I know the *-Process cmdlets had a -Name parameter?

Apart from reading the help files and documentation (I get it, I don't want to read anything either unless I absolutely have to ;-)), a quick way to learn about the parameters exposed by a cmdlet is by running Get-Command <commandName> -Syntax:

PS ~> Get-Command Stop-Process -Syntax

Stop-Process [-Id] <int[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

Stop-Process -Name <string[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

Stop-Process [-InputObject] <Process[]> [-PassThru] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

The output shows us 3 distinct "parameter sets" (combinations of parameter input accepted by the command), and the required and optional arguments we can pass to it.


What's wrong with Select-String?

The Select-String cmdlet is the PowerShell cognate to grep - it takes some input, and performs regular expression matching against it based on whatever pattern you give it.

But grep is only useful when you're operating on strings - and as you've already found, Get-Process returns structured .NET objects, not flat strings.

Instead, the PowerShell-idiomatic approach is to filter the data, using the Where-Object cmdlet:

Get-Process | Where-Object Name -like '*nginx*'

Here, we instruct Where-Object to only let through object that have a Name property, the value of which must satisfy the wildcard pattern *nginx*.

Where-Object also supports arbitrary filter expressions, by accepting a scriptblock - PowerShell will assign the current pipeline object being evaluated to $_ (and $PSItem):

Get-Process | Where-Object { $_.Name -like '*nginx*' }

... which you can extend to whatever degree you need:

# Only let them through if a specific user is executing
Get-Process | Where-Object { $_.Name -like '*nginx*' -and $env:USERNAME -ne 'Quarkly'}
Allnight answered 5/3, 2021 at 18:37 Comment(3)
It's probably worth noting that while Select-String is the wrong cmdlet to use in the OP's context, Where-Object would have been a better alternative given that context. Still not as good of a solution as you provided, but useful information to help them become a better scripter in general.Brigand
@Brigand Good point, agreed. I've updated the answerAllnight
Yes, the suggestion to use Where-Object was enlightening.Brimstone
B
0

Note: PowerShell must be run as Administrator in order to execute these commands.

Kill a process with a known PID:

Syntax:

Stop-Process -Force -Id <pid>

Example:

Stop-Process -Force -Id 1234

Kill a process with a known name:

Syntax:

Stop-Process -Force -Name <name>

Example:

Stop-Process -Force -Name Taskmgr

Kill a process with a name wildcard search pattern

Syntax:

Get-Process -Name <pattern> | Stop-Process -Force

Example:

Get-Process -Name *skmg* | Stop-Process -Force
Bodice answered 11/4 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.