'Trapping a PowerShell Statement from Win32_Process into a Variable for Taskkill Command
This powershell statement looks for a long commandline string from a process java.exe - it uses the string server1 to trap this specific process. It returns the words Processid
and Commandline
with its relative values.
gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1"
returns this line where 15112
is all I need:
Processid Commandline
--------- -----------
15112 D:\ ..a long command string.
How would you trap the single PID number returned from the above PS statement in a variable to run a taskkill /pid $PIDNUM
on ? Not sure how to extract that single number from the statement.
Solution 1:[1]
Very simple, we store the entire result into the variable $PIDNUM
, and we can access the result object's properties using dot-notation
$PIDNUM = (gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1").ProcessID
taskkill /pid $PIDNUM
or
$PIDNUM = gwmi win32_process | select Processid,Commandline | where-object CommandLine -match "server1"
taskkill /pid $PIDNUM.ProcessID
If your first statement finds multiple tasks, you'll need to run a loop to execute the taskkill for each object stored in the $PIDNUM
variable
foreach ($num in $PIDNUM)
{
taskkill /pid $num.processid
}
Solution 2:[2]
First, the obligatory pointer:
- The CIM cmdlets (e.g.,
Get-CimInstance
) superseded the WMI cmdlets (e.g.,Get-WmiObject
, whose built-in alias isgwmi
) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) v6+, where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.
$pidOfInterest =
(
Get-CimInstance win32_process |
Where-Object CommandLine -match server1
).ProcessId
Note:
$pidOfInterest
may receive multiple PIDs (process IDs), given that multiple processes may match yourWhere-Object
filter; that accessing.ProcessId
directly on a potential array of values still works to extract its elements' property values is courtesy of PowerShell's member-access enumeration feature.If
$pidOfInterest
does end up containing multiple PIDs, you can pass them totaskkill.exe
as follows:taskkill $pidOfInterest.ForEach({ '/pid', $_ })
With
Stop-Process
(see below), it is simpler, because its-Id
parameter accepts an array of PIDs:Stop-Process -Id $pidOfInterest
The
select Processid,Commandline
part of your command just creates unnecessary overhead, so it was omitted above - theGet-CimInstance
output objects can be filtered directly.You don't strictly need
taskkill.exe
for terminating processes, given that PowerShell has aStop-Process
cmdlet.However, an important difference is that
taskkill.exe
attempts graceful, cooperative termination by default, whereasStop-Process
(as of PowerShell 7.2.3) invariably terminates forcefully - which is whattaskkill.exe
offers as an opt-int with/f
- Improving
Stop-Process
in the future to support graceful, cooperative termination too is the subject of GitHub issue #13664.
- Improving
Attempting graceful termination means that termination may not be effective, however.
See this answer for more information.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |