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.
CodePudding user response:
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.
CodePudding user response:
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
}