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:
$pidOfInterestmay receive multiple PIDs (process IDs), given that multiple processes may match yourWhere-Objectfilter; that accessing.ProcessIddirectly on a potential array of values still works to extract its elements' property values is courtesy of PowerShell's member-access enumeration feature.If
$pidOfInterestdoes end up containing multiple PIDs, you can pass them totaskkill.exeas follows:taskkill $pidOfInterest.ForEach({ '/pid', $_ })With
Stop-Process(see below), it is simpler, because its-Idparameter accepts an array of PIDs:Stop-Process -Id $pidOfInterest
The
select Processid,Commandlinepart of your command just creates unnecessary overhead, so it was omitted above - theGet-CimInstanceoutput objects can be filtered directly.You don't strictly need
taskkill.exefor terminating processes, given that PowerShell has aStop-Processcmdlet.However, an important difference is that
taskkill.exeattempts graceful, cooperative termination by default, whereasStop-Process(as of PowerShell 7.2.3) invariably terminates forcefully - which is whattaskkill.exeoffers as an opt-int with/f- Improving
Stop-Processin 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
}
